From e974738808701b893f857a3068974978dd7ec084 Mon Sep 17 00:00:00 2001 From: David Eads Date: Mon, 16 Apr 2018 11:31:37 -0400 Subject: [PATCH] stop shimming the upstream factory inputs --- pkg/oc/admin/prune/deployments.go | 10 +- pkg/oc/admin/prune/deployments_test.go | 2 +- pkg/oc/cli/cli.go | 4 + pkg/oc/cli/groupification.go | 190 ++++++++++++++++++ pkg/oc/cli/util/clientcmd/factory.go | 2 +- pkg/oc/cli/util/clientcmd/factory_builder.go | 4 +- .../util/clientcmd/factory_client_access.go | 75 +------ .../util/clientcmd/factory_object_mapping.go | 42 +--- pkg/oc/cli/util/clientcmd/legacy_discovery.go | 83 -------- test/cmd/authentication.sh | 4 +- test/cmd/deployments.sh | 2 +- test/cmd/migrate.sh | 4 +- test/cmd/router.sh | 2 +- test/cmd/set-liveness-probe.sh | 2 +- test/extended/builds/build_pruning.go | 2 +- test/extended/testdata/bindata.go | 42 ++-- .../default-legacy-build-config.yaml | 41 ++-- test/integration/etcd_storage_path_test.go | 8 +- .../cluster_admin_without_apigroups.yaml | 1 + 19 files changed, 278 insertions(+), 242 deletions(-) create mode 100644 pkg/oc/cli/groupification.go delete mode 100644 pkg/oc/cli/util/clientcmd/legacy_discovery.go diff --git a/pkg/oc/admin/prune/deployments.go b/pkg/oc/admin/prune/deployments.go index ab65cba878d5..632b9d99d20a 100644 --- a/pkg/oc/admin/prune/deployments.go +++ b/pkg/oc/admin/prune/deployments.go @@ -48,7 +48,7 @@ type PruneDeploymentsOptions struct { Namespace string AppsClient appsclientinternal.DeploymentConfigsGetter - KClient kclientset.Interface + KubeClient kclientset.Interface Out io.Writer } @@ -99,7 +99,7 @@ func (o *PruneDeploymentsOptions) Complete(f *clientcmd.Factory, cmd *cobra.Comm } o.Out = out - kClient, err := f.ClientSet() + kubeClient, err := f.ClientSet() if err != nil { return err } @@ -112,7 +112,7 @@ func (o *PruneDeploymentsOptions) Complete(f *clientcmd.Factory, cmd *cobra.Comm return err } o.AppsClient = appsClient - o.KClient = kClient + o.KubeClient = kubeClient return nil } @@ -142,7 +142,7 @@ func (o PruneDeploymentsOptions) Run() error { deploymentConfigs = append(deploymentConfigs, &deploymentConfigList.Items[i]) } - deploymentList, err := o.KClient.Core().ReplicationControllers(o.Namespace).List(metav1.ListOptions{}) + deploymentList, err := o.KubeClient.Core().ReplicationControllers(o.Namespace).List(metav1.ListOptions{}) if err != nil { return err } @@ -167,7 +167,7 @@ func (o PruneDeploymentsOptions) Run() error { deploymentDeleter := &describingDeploymentDeleter{w: w} if o.Confirm { - deploymentDeleter.delegate = prune.NewDeploymentDeleter(o.KClient.Core(), o.KClient.Core()) + deploymentDeleter.delegate = prune.NewDeploymentDeleter(o.KubeClient.Core(), o.KubeClient.Core()) } else { fmt.Fprintln(os.Stderr, "Dry run enabled - no modifications will be made. Add --confirm to remove deployments") } diff --git a/pkg/oc/admin/prune/deployments_test.go b/pkg/oc/admin/prune/deployments_test.go index a28279338f8c..777e3bcd3e82 100644 --- a/pkg/oc/admin/prune/deployments_test.go +++ b/pkg/oc/admin/prune/deployments_test.go @@ -15,7 +15,7 @@ func TestDeploymentPruneNamespaced(t *testing.T) { Namespace: "foo", AppsClient: osFake.Apps(), - KClient: kFake, + KubeClient: kFake, Out: ioutil.Discard, } diff --git a/pkg/oc/cli/cli.go b/pkg/oc/cli/cli.go index 30b91e643267..67cf8339db86 100644 --- a/pkg/oc/cli/cli.go +++ b/pkg/oc/cli/cli.go @@ -12,6 +12,7 @@ import ( kubecmd "k8s.io/kubernetes/pkg/kubectl/cmd" ktemplates "k8s.io/kubernetes/pkg/kubectl/cmd/templates" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + "k8s.io/kubernetes/pkg/kubectl/resource" "github.com/openshift/origin/pkg/cmd/flagtypes" "github.com/openshift/origin/pkg/cmd/templates" @@ -315,6 +316,9 @@ func CommandFor(basename string) *cobra.Command { case "kubectl": cmd = kubecmd.NewKubectlCommand(kcmdutil.NewFactory(nil), in, out, errout) default: + // we only need this change for `oc`. `kubectl` should behave as close to `kubectl` as we can + resource.OAPIToGroupified = OAPIToGroupified + kcmdutil.OAPIToGroupifiedGVK = OAPIToGroupifiedGVK cmd = NewCommandCLI("oc", "oc", in, out, errout) } diff --git a/pkg/oc/cli/groupification.go b/pkg/oc/cli/groupification.go new file mode 100644 index 000000000000..58f13b040d72 --- /dev/null +++ b/pkg/oc/cli/groupification.go @@ -0,0 +1,190 @@ +package cli + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + appsv1 "github.com/openshift/api/apps/v1" + authorizationv1 "github.com/openshift/api/authorization/v1" + buildv1 "github.com/openshift/api/build/v1" + imagev1 "github.com/openshift/api/image/v1" + networkv1 "github.com/openshift/api/network/v1" + oauthv1 "github.com/openshift/api/oauth/v1" + projectv1 "github.com/openshift/api/project/v1" + quotav1 "github.com/openshift/api/quota/v1" + routev1 "github.com/openshift/api/route/v1" + securityv1 "github.com/openshift/api/security/v1" + templatev1 "github.com/openshift/api/template/v1" + userv1 "github.com/openshift/api/user/v1" + "github.com/openshift/origin/pkg/apps/apis/apps" + "github.com/openshift/origin/pkg/authorization/apis/authorization" + "github.com/openshift/origin/pkg/build/apis/build" + "github.com/openshift/origin/pkg/image/apis/image" + "github.com/openshift/origin/pkg/network/apis/network" + "github.com/openshift/origin/pkg/oauth/apis/oauth" + "github.com/openshift/origin/pkg/project/apis/project" + "github.com/openshift/origin/pkg/quota/apis/quota" + "github.com/openshift/origin/pkg/route/apis/route" + "github.com/openshift/origin/pkg/security/apis/security" + "github.com/openshift/origin/pkg/template/apis/template" + "github.com/openshift/origin/pkg/user/apis/user" +) + +func OAPIToGroupifiedGVK(gvk *schema.GroupVersionKind) { + if len(gvk.Group) > 0 { + return + } + + newGroup, ok := oapiKindsToGroup[gvk.Kind] + if !ok { + return + } + gvk.Group = newGroup +} + +func OAPIToGroupified(uncast runtime.Object, gvk *schema.GroupVersionKind) { + if len(gvk.Group) > 0 { + return + } + + switch obj := uncast.(type) { + case *unstructured.Unstructured: + newGroup := fixOAPIGroupKindInTopLevelUnstructured(obj.Object) + if len(newGroup) > 0 { + gvk.Group = newGroup + } + case *unstructured.UnstructuredList: + newGroup := fixOAPIGroupKindInTopLevelUnstructured(obj.Object) + if len(newGroup) > 0 { + gvk.Group = newGroup + } + + case *apps.DeploymentConfig, *appsv1.DeploymentConfig, *apps.DeploymentConfigList, *appsv1.DeploymentConfigList, + *apps.DeploymentConfigRollback, *appsv1.DeploymentConfigRollback: + gvk.Group = apps.GroupName + + case *authorization.ClusterRoleBinding, *authorizationv1.ClusterRoleBinding, *authorization.ClusterRoleBindingList, *authorizationv1.ClusterRoleBindingList, + *authorization.ClusterRole, *authorizationv1.ClusterRole, *authorization.ClusterRoleList, *authorizationv1.ClusterRoleList, + *authorization.Role, *authorizationv1.Role, *authorization.RoleList, *authorizationv1.RoleList, + *authorization.RoleBinding, *authorizationv1.RoleBinding, *authorization.RoleBindingList, *authorizationv1.RoleBindingList, + *authorization.RoleBindingRestriction, *authorizationv1.RoleBindingRestriction, *authorization.RoleBindingRestrictionList, *authorizationv1.RoleBindingRestrictionList: + gvk.Group = authorization.GroupName + + case *build.BuildConfig, *buildv1.BuildConfig, *build.BuildConfigList, *buildv1.BuildConfigList, + *build.Build, *buildv1.Build, *build.BuildList, *buildv1.BuildList: + gvk.Group = build.GroupName + + case *image.Image, *imagev1.Image, *image.ImageList, *imagev1.ImageList, + *image.ImageSignature, *imagev1.ImageSignature, + *image.ImageStreamImage, *imagev1.ImageStreamImage, + *image.ImageStreamImport, *imagev1.ImageStreamImport, + *image.ImageStreamMapping, *imagev1.ImageStreamMapping, + *image.ImageStream, *imagev1.ImageStream, *image.ImageStreamList, *imagev1.ImageStreamList, + *image.ImageStreamTag, *imagev1.ImageStreamTag: + gvk.Group = image.GroupName + + case *network.ClusterNetwork, *networkv1.ClusterNetwork, *network.ClusterNetworkList, *networkv1.ClusterNetworkList, + *network.NetNamespace, *networkv1.NetNamespace, *network.NetNamespaceList, *networkv1.NetNamespaceList, + *network.HostSubnet, *networkv1.HostSubnet, *network.HostSubnetList, *networkv1.HostSubnetList, + *network.EgressNetworkPolicy, *networkv1.EgressNetworkPolicy, *network.EgressNetworkPolicyList, *networkv1.EgressNetworkPolicyList: + gvk.Group = network.GroupName + + case *project.Project, *projectv1.Project, *project.ProjectList, *projectv1.ProjectList, + *project.ProjectRequest, *projectv1.ProjectRequest: + gvk.Group = project.GroupName + + case *quota.ClusterResourceQuota, *quotav1.ClusterResourceQuota, *quota.ClusterResourceQuotaList, *quotav1.ClusterResourceQuotaList: + gvk.Group = quota.GroupName + + case *oauth.OAuthAuthorizeToken, *oauthv1.OAuthAuthorizeToken, *oauth.OAuthAuthorizeTokenList, *oauthv1.OAuthAuthorizeTokenList, + *oauth.OAuthClientAuthorization, *oauthv1.OAuthClientAuthorization, *oauth.OAuthClientAuthorizationList, *oauthv1.OAuthClientAuthorizationList, + *oauth.OAuthClient, *oauthv1.OAuthClient, *oauth.OAuthClientList, *oauthv1.OAuthClientList, + *oauth.OAuthAccessToken, *oauthv1.OAuthAccessToken, *oauth.OAuthAccessTokenList, *oauthv1.OAuthAccessTokenList: + gvk.Group = oauth.GroupName + + case *route.Route, *routev1.Route, *route.RouteList, *routev1.RouteList: + gvk.Group = route.GroupName + + case *security.SecurityContextConstraints, *securityv1.SecurityContextConstraints, *security.SecurityContextConstraintsList, *securityv1.SecurityContextConstraintsList: + gvk.Group = security.GroupName + + case *template.Template, *templatev1.Template, *template.TemplateList, *templatev1.TemplateList: + gvk.Group = template.GroupName + + case *user.Group, *userv1.Group, *user.GroupList, *userv1.GroupList, + *user.Identity, *userv1.Identity, *user.IdentityList, *userv1.IdentityList, + *user.UserIdentityMapping, *userv1.UserIdentityMapping, + *user.User, *userv1.User, *user.UserList, *userv1.UserList: + gvk.Group = user.GroupName + + } +} + +var oapiKindsToGroup = map[string]string{ + "DeploymentConfigRollback": "apps.openshift.io", + "DeploymentConfig": "apps.openshift.io", "DeploymentConfigList": "apps.openshift.io", + "ClusterRoleBinding": "authorization.openshift.io", "ClusterRoleBindingList": "authorization.openshift.io", + "ClusterRole": "authorization.openshift.io", "ClusterRoleList": "authorization.openshift.io", + "RoleBindingRestriction": "authorization.openshift.io", "RoleBindingRestrictionList": "authorization.openshift.io", + "RoleBinding": "authorization.openshift.io", "RoleBindingList": "authorization.openshift.io", + "Role": "authorization.openshift.io", "RoleList": "authorization.openshift.io", + "BuildConfig": "build.openshift.io", "BuildConfigList": "build.openshift.io", + "Build": "build.openshift.io", "BuildList": "build.openshift.io", + "Image": "image.openshift.io", "ImageList": "image.openshift.io", + "ImageSignature": "image.openshift.io", + "ImageStreamImage": "image.openshift.io", + "ImageStreamImport": "image.openshift.io", + "ImageStreamMapping": "image.openshift.io", + "ImageStream": "image.openshift.io", "ImageStreamList": "image.openshift.io", + "ImageStreamTag": "image.openshift.io", "ImageStreamTagList": "image.openshift.io", + "ClusterNetwork": "network.openshift.io", "ClusterNetworkList": "network.openshift.io", + "EgressNetworkPolicy": "network.openshift.io", "EgressNetworkPolicyList": "network.openshift.io", + "HostSubnet": "network.openshift.io", "HostSubnetList": "network.openshift.io", + "NetNamespace": "network.openshift.io", "NetNamespaceList": "network.openshift.io", + "OAuthAccessToken": "oauth.openshift.io", "OAuthAccessTokenList": "oauth.openshift.io", + "OAuthAuthorizeToken": "oauth.openshift.io", "OAuthAuthorizeTokenList": "oauth.openshift.io", + "OAuthClientAuthorization": "oauth.openshift.io", "OAuthClientAuthorizationList": "oauth.openshift.io", + "OAuthClient": "oauth.openshift.io", "OAuthClientList": "oauth.openshift.io", + "Project": "project.openshift.io", "ProjectList": "project.openshift.io", + "ProjectRequest": "project.openshift.io", + "ClusterResourceQuota": "quota.openshift.io", "ClusterResourceQuotaList": "quota.openshift.io", + "Route": "route.openshift.io", "RouteList": "route.openshift.io", + "SecurityContextConstraint": "security.openshift.io", "SecurityContextConstraintList": "security.openshift.io", + "Template": "template.openshift.io", "TemplateList": "template.openshift.io", + "Group": "user.openshift.io", "GroupList": "user.openshift.io", + "Identity": "user.openshift.io", "IdentityList": "user.openshift.io", + "UserIdentityMapping": "user.openshift.io", + "User": "user.openshift.io", "UserList": "user.openshift.io", +} + +func fixOAPIGroupKindInTopLevelUnstructured(obj map[string]interface{}) string { + kind, ok := obj["kind"] + if !ok { + return "" + } + kindStr, ok := kind.(string) + if !ok { + return "" + } + newGroup, ok := oapiKindsToGroup[kindStr] + if !ok { + return "" + } + + apiVersion, ok := obj["apiVersion"] + if !ok { + return newGroup + } + apiVersionStr, ok := apiVersion.(string) + if !ok { + return newGroup + } + + if apiVersionStr != "v1" { + return newGroup + } + obj["apiVersion"] = newGroup + "/v1" + + return newGroup +} diff --git a/pkg/oc/cli/util/clientcmd/factory.go b/pkg/oc/cli/util/clientcmd/factory.go index 1754667c3f0a..1016ad9fb3d2 100644 --- a/pkg/oc/cli/util/clientcmd/factory.go +++ b/pkg/oc/cli/util/clientcmd/factory.go @@ -48,7 +48,7 @@ func New(flags *pflag.FlagSet) *Factory { // Factory provides common options for OpenShift commands type Factory struct { - ClientAccessFactory + kcmdutil.ClientAccessFactory kcmdutil.ObjectMappingFactory kcmdutil.BuilderFactory } diff --git a/pkg/oc/cli/util/clientcmd/factory_builder.go b/pkg/oc/cli/util/clientcmd/factory_builder.go index 0898d0cc350f..013b1b884c56 100644 --- a/pkg/oc/cli/util/clientcmd/factory_builder.go +++ b/pkg/oc/cli/util/clientcmd/factory_builder.go @@ -25,12 +25,12 @@ import ( ) type ring2Factory struct { - clientAccessFactory ClientAccessFactory + clientAccessFactory kcmdutil.ClientAccessFactory objectMappingFactory kcmdutil.ObjectMappingFactory kubeBuilderFactory kcmdutil.BuilderFactory } -func NewBuilderFactory(clientAccessFactory ClientAccessFactory, objectMappingFactory kcmdutil.ObjectMappingFactory) kcmdutil.BuilderFactory { +func NewBuilderFactory(clientAccessFactory kcmdutil.ClientAccessFactory, objectMappingFactory kcmdutil.ObjectMappingFactory) kcmdutil.BuilderFactory { return &ring2Factory{ clientAccessFactory: clientAccessFactory, objectMappingFactory: objectMappingFactory, diff --git a/pkg/oc/cli/util/clientcmd/factory_client_access.go b/pkg/oc/cli/util/clientcmd/factory_client_access.go index 9bb1a492cbd7..d60502283105 100644 --- a/pkg/oc/cli/util/clientcmd/factory_client_access.go +++ b/pkg/oc/cli/util/clientcmd/factory_client_access.go @@ -2,12 +2,10 @@ package clientcmd import ( "errors" - "net/http" "path/filepath" "regexp" "strconv" "strings" - "time" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -21,14 +19,12 @@ import ( restclient "k8s.io/client-go/rest" kclientcmd "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/client-go/util/homedir" kapi "k8s.io/kubernetes/pkg/apis/core" kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/set" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" - "k8s.io/kubernetes/pkg/kubectl/util/transport" appsapiv1 "github.com/openshift/api/apps/v1" appsapi "github.com/openshift/origin/pkg/apps/apis/apps" @@ -38,83 +34,22 @@ import ( ) type ring0Factory struct { - clientConfig kclientcmd.ClientConfig kubeClientAccessFactory kcmdutil.ClientAccessFactory } -type ClientAccessFactory interface { - kcmdutil.ClientAccessFactory -} - -func NewClientAccessFactory(optionalClientConfig kclientcmd.ClientConfig) ClientAccessFactory { +func NewClientAccessFactory(optionalClientConfig kclientcmd.ClientConfig) kcmdutil.ClientAccessFactory { // if we call this factory construction method, we want the openshift style config loading kclientcmd.UseOpenShiftKubeConfigValues = true kclientcmd.ErrEmptyConfig = kclientcmd.NewErrConfigurationMissing() set.ParseDockerImageReferenceToStringFunc = ParseDockerImageReferenceToStringFunc - flags := pflag.NewFlagSet("", pflag.ContinueOnError) - clientConfig := optionalClientConfig - if optionalClientConfig == nil { - clientConfig = kcmdutil.DefaultClientConfig(flags) - } factory := &ring0Factory{ - clientConfig: clientConfig, + kubeClientAccessFactory: kcmdutil.NewClientAccessFactory(optionalClientConfig), } - factory.kubeClientAccessFactory = kcmdutil.NewClientAccessFactoryFromDiscovery( - flags, - clientConfig, - &discoveryFactory{clientConfig: clientConfig}, - ) return factory } -type discoveryFactory struct { - clientConfig kclientcmd.ClientConfig - cacheDir string -} - -func (f *discoveryFactory) BindFlags(flags *pflag.FlagSet) { - defaultCacheDir := filepath.Join(homedir.HomeDir(), ".kube", "http-cache") - flags.StringVar(&f.cacheDir, kcmdutil.FlagHTTPCacheDir, defaultCacheDir, "Default HTTP cache directory") -} - -func (f *discoveryFactory) DiscoveryClient() (discovery.CachedDiscoveryInterface, error) { - // Output using whatever version was negotiated in the client cache. The - // version we decode with may not be the same as what the server requires. - cfg, err := f.clientConfig.ClientConfig() - if err != nil { - return nil, err - } - // given 25 groups with one-ish version each, discovery needs to make 50 requests - // double it just so we don't end up here again for a while. This config is only used for discovery. - cfg.Burst = 100 - - if f.cacheDir != "" { - wt := cfg.WrapTransport - cfg.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { - if wt != nil { - rt = wt(rt) - } - return transport.NewCacheRoundTripper(f.cacheDir, rt) - } - } - - // at this point we've negotiated and can get the client - kubeClient, err := kclientset.NewForConfig(cfg) - if err != nil { - return nil, err - - } - - cacheDir := computeDiscoverCacheDir(filepath.Join(homedir.HomeDir(), ".kube", "cache", "discovery"), cfg.Host) - return kcmdutil.NewCachedDiscoveryClient(newLegacyDiscoveryClient(kubeClient.Discovery().RESTClient()), cacheDir, time.Duration(10*time.Minute)), nil -} - -func (f *ring0Factory) RawConfig() (clientcmdapi.Config, error) { - return f.kubeClientAccessFactory.RawConfig() -} - func (f *ring0Factory) DiscoveryClient() (discovery.CachedDiscoveryInterface, error) { return f.kubeClientAccessFactory.DiscoveryClient() } @@ -131,8 +66,12 @@ func (f *ring0Factory) ClientConfig() (*restclient.Config, error) { return f.kubeClientAccessFactory.ClientConfig() } +func (f *ring0Factory) RawConfig() (clientcmdapi.Config, error) { + return f.kubeClientAccessFactory.RawConfig() +} + func (f *ring0Factory) BareClientConfig() (*restclient.Config, error) { - return f.clientConfig.ClientConfig() + return f.kubeClientAccessFactory.BareClientConfig() } func (f *ring0Factory) RESTClient() (*restclient.RESTClient, error) { diff --git a/pkg/oc/cli/util/clientcmd/factory_object_mapping.go b/pkg/oc/cli/util/clientcmd/factory_object_mapping.go index 0704795f0883..9990c4158fc1 100644 --- a/pkg/oc/cli/util/clientcmd/factory_object_mapping.go +++ b/pkg/oc/cli/util/clientcmd/factory_object_mapping.go @@ -11,7 +11,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/dynamic" restclient "k8s.io/client-go/rest" kapi "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/controller" @@ -33,18 +32,17 @@ import ( buildmanualclient "github.com/openshift/origin/pkg/build/client/internalversion" buildclientinternal "github.com/openshift/origin/pkg/build/generated/internalclientset" buildutil "github.com/openshift/origin/pkg/build/util" - configcmd "github.com/openshift/origin/pkg/bulk" imageapi "github.com/openshift/origin/pkg/image/apis/image" deploymentcmd "github.com/openshift/origin/pkg/oc/cli/deploymentconfigs" "github.com/openshift/origin/pkg/oc/cli/describe" ) type ring1Factory struct { - clientAccessFactory ClientAccessFactory + clientAccessFactory kcmdutil.ClientAccessFactory kubeObjectMappingFactory kcmdutil.ObjectMappingFactory } -func NewObjectMappingFactory(clientAccessFactory ClientAccessFactory) kcmdutil.ObjectMappingFactory { +func NewObjectMappingFactory(clientAccessFactory kcmdutil.ClientAccessFactory) kcmdutil.ObjectMappingFactory { return &ring1Factory{ clientAccessFactory: clientAccessFactory, kubeObjectMappingFactory: kcmdutil.NewObjectMappingFactory(clientAccessFactory), @@ -60,45 +58,10 @@ func (f *ring1Factory) CategoryExpander() categories.CategoryExpander { } func (f *ring1Factory) ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) { - // TODO only do this for legacy kinds - if latest.OriginKind(mapping.GroupVersionKind) { - cfg, err := f.clientAccessFactory.ClientConfig() - if err != nil { - return nil, err - } - if err := configcmd.SetLegacyOpenShiftDefaults(cfg); err != nil { - return nil, err - } - cfg.APIPath = "/apis" - if mapping.GroupVersionKind.Group == kapi.GroupName { - cfg.APIPath = "/oapi" - } - gv := mapping.GroupVersionKind.GroupVersion() - cfg.GroupVersion = &gv - return restclient.RESTClientFor(cfg) - } return f.kubeObjectMappingFactory.ClientForMapping(mapping) } func (f *ring1Factory) UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) { - // TODO only do this for legacy kinds - if latest.OriginKind(mapping.GroupVersionKind) { - cfg, err := f.clientAccessFactory.ClientConfig() - if err != nil { - return nil, err - } - if err := configcmd.SetLegacyOpenShiftDefaults(cfg); err != nil { - return nil, err - } - cfg.APIPath = "/apis" - if mapping.GroupVersionKind.Group == kapi.GroupName { - cfg.APIPath = "/oapi" - } - gv := mapping.GroupVersionKind.GroupVersion() - cfg.ContentConfig = dynamic.ContentConfig() - cfg.GroupVersion = &gv - return restclient.RESTClientFor(cfg) - } return f.kubeObjectMappingFactory.UnstructuredClientForMapping(mapping) } @@ -123,6 +86,7 @@ func (f *ring1Factory) Describer(mapping *meta.RESTMapping) (kprinters.Describer } return describer, nil } + return f.kubeObjectMappingFactory.Describer(mapping) } diff --git a/pkg/oc/cli/util/clientcmd/legacy_discovery.go b/pkg/oc/cli/util/clientcmd/legacy_discovery.go deleted file mode 100644 index cab093f560da..000000000000 --- a/pkg/oc/cli/util/clientcmd/legacy_discovery.go +++ /dev/null @@ -1,83 +0,0 @@ -package clientcmd - -import ( - "net/url" - - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/discovery" - restclient "k8s.io/client-go/rest" -) - -// legacyDiscoveryClient implements the functions that discovery server-supported API groups, -// versions and resources. -type legacyDiscoveryClient struct { - *discovery.DiscoveryClient -} - -// ServerResourcesForGroupVersion returns the supported resources for a group and version. -// This can return an error *and* a partial result -func (d *legacyDiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (resources *metav1.APIResourceList, err error) { - parentList, err := d.DiscoveryClient.ServerResourcesForGroupVersion(groupVersion) - if err != nil { - return parentList, err - } - - if groupVersion != "v1" { - return parentList, nil - } - - // we request v1, we must combine the parent list with the list from /oapi - - url := url.URL{} - url.Path = "/oapi/" + groupVersion - originResources := &metav1.APIResourceList{} - err = d.RESTClient().Get().AbsPath(url.String()).Do().Into(originResources) - if err != nil { - // ignore 403 or 404 error to be compatible with an v1.0 server. - if groupVersion == "v1" && (errors.IsNotFound(err) || errors.IsForbidden(err)) { - return parentList, nil - } - return parentList, err - } - - parentList.APIResources = append(parentList.APIResources, originResources.APIResources...) - return parentList, nil -} - -// ServerResources returns the supported resources for all groups and versions. -// This can return an error *and* a partial result -func (d *legacyDiscoveryClient) ServerResources() ([]*metav1.APIResourceList, error) { - apiGroups, err := d.ServerGroups() - if err != nil { - return nil, err - } - - result := []*metav1.APIResourceList{} - failedGroups := make(map[schema.GroupVersion]error) - - for _, apiGroup := range apiGroups.Groups { - for _, version := range apiGroup.Versions { - gv := schema.GroupVersion{Group: apiGroup.Name, Version: version.Version} - resources, err := d.ServerResourcesForGroupVersion(version.GroupVersion) - if err != nil { - failedGroups[gv] = err - continue - } - - result = append(result, resources) - } - } - - if len(failedGroups) == 0 { - return result, nil - } - - return result, &discovery.ErrGroupDiscoveryFailed{Groups: failedGroups} -} - -// newLegacyDiscoveryClient creates a new DiscoveryClient for the given RESTClient. -func newLegacyDiscoveryClient(c restclient.Interface) *legacyDiscoveryClient { - return &legacyDiscoveryClient{discovery.NewDiscoveryClient(c)} -} diff --git a/test/cmd/authentication.sh b/test/cmd/authentication.sh index 1ef7776aa633..58d0172557f2 100755 --- a/test/cmd/authentication.sh +++ b/test/cmd/authentication.sh @@ -81,8 +81,8 @@ os::cmd::expect_success_and_text "curl -k -XPOST -H 'Content-Type: application/j os::cmd::expect_success_and_text "curl -k -XPOST -H 'Content-Type: application/json' -H 'Authorization: Bearer ${accesstoken}' '${API_SCHEME}://${API_HOST}:${API_PORT}/apis/authorization.openshift.io/v1/subjectaccessreviews' -d '{\"namespace\":\"${project}\",\"verb\":\"create\",\"resource\":\"pods\"}'" '"kind": "SubjectAccessReviewResponse"' os::cmd::expect_success_and_text "oc policy can-i create pods --token='${accesstoken}' -n '${project}' --ignore-scopes" 'yes' os::cmd::expect_success_and_text "oc policy can-i create pods --token='${accesstoken}' -n '${project}'" 'no' -os::cmd::expect_success_and_text "oc policy can-i create subjectaccessreviews --token='${accesstoken}' -n '${project}'" 'no' -os::cmd::expect_success_and_text "oc policy can-i create subjectaccessreviews --token='${accesstoken}' -n '${project}' --ignore-scopes" 'yes' +os::cmd::expect_success_and_text "oc policy can-i create subjectaccessreviews.authorization.openshift.io --token='${accesstoken}' -n '${project}'" 'no' +os::cmd::expect_success_and_text "oc policy can-i create subjectaccessreviews.authorization.openshift.io --token='${accesstoken}' -n '${project}' --ignore-scopes" 'yes' os::cmd::expect_success_and_text "oc policy can-i create pods --token='${accesstoken}' -n '${project}' --scopes='role:admin:*'" 'yes' os::cmd::expect_success_and_text "oc policy can-i --list --token='${accesstoken}' -n '${project}' --scopes='role:admin:*'" 'get.*pods' os::cmd::expect_success_and_not_text "oc policy can-i --list --token='${accesstoken}' -n '${project}'" 'get.*pods' diff --git a/test/cmd/deployments.sh b/test/cmd/deployments.sh index 8fa8ea9f27cc..10002ab475cc 100755 --- a/test/cmd/deployments.sh +++ b/test/cmd/deployments.sh @@ -159,7 +159,7 @@ os::test::junit::declare_suite_start "cmd/deployments/setdeploymenthook" arg="-f test/integration/testdata/test-deployment-config.yaml" os::cmd::expect_failure_and_text "oc set deployment-hook" "error: one or more deployment configs" os::cmd::expect_failure_and_text "oc set deployment-hook ${arg}" "error: you must specify one of --pre, --mid, or --post" -os::cmd::expect_failure_and_text "oc set deployment-hook ${arg} -o yaml --pre -- mycmd" 'deploymentconfigs "test-deployment-config" not found' +os::cmd::expect_failure_and_text "oc set deployment-hook ${arg} -o yaml --pre -- mycmd" 'deploymentconfigs.apps.openshift.io "test-deployment-config" not found' os::cmd::expect_success_and_text "oc set deployment-hook ${arg} --local -o yaml --post -- mycmd" 'mycmd' os::cmd::expect_success_and_not_text "oc set deployment-hook ${arg} --local -o yaml --post -- mycmd | oc set deployment-hook -f - --local -o yaml --post --remove" 'mycmd' os::cmd::expect_success "oc create ${arg}" diff --git a/test/cmd/migrate.sh b/test/cmd/migrate.sh index 0570f2a8c118..06b0132b3076 100755 --- a/test/cmd/migrate.sh +++ b/test/cmd/migrate.sh @@ -29,9 +29,9 @@ os::test::junit::declare_suite_end os::test::junit::declare_suite_start "cmd/migrate/storage_oauthclientauthorizations" # Create valid OAuth client -os::cmd::expect_success_and_text 'oc create -f test/testdata/oauth/client.yaml' 'oauthclient "test-oauth-client" created' +os::cmd::expect_success_and_text 'oc create -f test/testdata/oauth/client.yaml' 'oauthclient.oauth.openshift.io "test-oauth-client" created' # Create OAuth client authorization for client -os::cmd::expect_success_and_text 'oc create -f test/testdata/oauth/clientauthorization.yaml' 'oauthclientauthorization "user1:test-oauth-client" created' +os::cmd::expect_success_and_text 'oc create -f test/testdata/oauth/clientauthorization.yaml' 'oauthclientauthorization.oauth.openshift.io "user1:test-oauth-client" created' # Delete client os::cmd::expect_success_and_text 'oc delete oauthclient test-oauth-client' 'oauthclient.oauth.openshift.io "test-oauth-client" deleted' # Assert that migration/update still works even though the client authorization is no longer valid diff --git a/test/cmd/router.sh b/test/cmd/router.sh index e36dd4ffc14d..31b058a0f407 100755 --- a/test/cmd/router.sh +++ b/test/cmd/router.sh @@ -70,7 +70,7 @@ os::cmd::expect_success_and_text 'oc get dc/router -o yaml' 'readinessProbe' os::cmd::expect_success_and_text "oc delete svc/router" 'service "router" deleted' os::cmd::expect_success_and_text "oc delete dc/router" 'deploymentconfig.apps.openshift.io "router" deleted' # create a router and check for success with a warning about the existing clusterrolebinding -os::cmd::expect_success_and_text "oc adm router" 'warning: clusterrolebindings "router-router-role" already exists' +os::cmd::expect_success_and_text "oc adm router" 'warning: clusterrolebindings.authorization.openshift.io "router-router-role" already exists' # only when using hostnetwork should we force the probes to use localhost os::cmd::expect_success_and_not_text "oc adm router -o yaml --host-network=false" 'host: localhost' diff --git a/test/cmd/set-liveness-probe.sh b/test/cmd/set-liveness-probe.sh index c63693371b9e..23aef85744e5 100755 --- a/test/cmd/set-liveness-probe.sh +++ b/test/cmd/set-liveness-probe.sh @@ -12,7 +12,7 @@ trap os::test::junit::reconcile_output EXIT os::test::junit::declare_suite_start "cmd/set-probe-liveness" # This test setting a liveness probe, without warning about replication controllers whose deployment depends on deployment configs -os::cmd::expect_success_and_text 'oc create -f pkg/oc/graph/genericgraph/test/simple-deployment.yaml' 'deploymentconfig "simple-deployment" created' +os::cmd::expect_success_and_text 'oc create -f pkg/oc/graph/genericgraph/test/simple-deployment.yaml' 'deploymentconfig.apps.openshift.io "simple-deployment" created' os::cmd::expect_success_and_text 'oc status --suggest' 'dc/simple-deployment has no liveness probe' # test --local flag diff --git a/test/extended/builds/build_pruning.go b/test/extended/builds/build_pruning.go index f8286d9dca42..5182be87ea92 100644 --- a/test/extended/builds/build_pruning.go +++ b/test/extended/builds/build_pruning.go @@ -310,7 +310,7 @@ var _ = g.Describe("[Feature:Builds][pruning] prune builds based on settings in g.It("[Conformance] buildconfigs should not have a default history limit set when created via the legacy api", func() { g.By("creating a build config with the legacy api") - err := oc.Run("create").Args("-f", legacyBuildConfig).Execute() + err := oc.Run("create").Args("-f", legacyBuildConfig, "--raw=/oapi/v1/namespaces/"+oc.Namespace()+"/buildconfigs").Execute() o.Expect(err).NotTo(o.HaveOccurred()) buildConfig, err := oc.BuildClient().Build().BuildConfigs(oc.Namespace()).Get("myphp", metav1.GetOptions{}) diff --git a/test/extended/testdata/bindata.go b/test/extended/testdata/bindata.go index ffee4085e60e..344b616d1a3f 100644 --- a/test/extended/testdata/bindata.go +++ b/test/extended/testdata/bindata.go @@ -554,23 +554,31 @@ func testExtendedTestdataBuildsBuildPruningDefaultGroupBuildConfigYaml() (*asset return a, nil } -var _testExtendedTestdataBuildsBuildPruningDefaultLegacyBuildConfigYaml = []byte(`apiVersion: v1 -kind: BuildConfig -metadata: - name: myphp -spec: - source: - type: Git - git: - uri: 'https://github.com/openshift/cakephp-ex.git' - strategy: - type: Source - sourceStrategy: - from: - kind: ImageStreamTag - namespace: openshift - name: 'php:7.0' -`) +var _testExtendedTestdataBuildsBuildPruningDefaultLegacyBuildConfigYaml = []byte(`{ + "apiVersion": "v1", + "kind": "BuildConfig", + "metadata": { + "name": "myphp" + }, + "spec": { + "source": { + "type": "Git", + "git": { + "uri": "https://github.com/openshift/cakephp-ex.git" + } + }, + "strategy": { + "type": "Source", + "sourceStrategy": { + "from": { + "kind": "ImageStreamTag", + "namespace": "openshift", + "name": "php:7.0" + } + } + } + } +}`) func testExtendedTestdataBuildsBuildPruningDefaultLegacyBuildConfigYamlBytes() ([]byte, error) { return _testExtendedTestdataBuildsBuildPruningDefaultLegacyBuildConfigYaml, nil diff --git a/test/extended/testdata/builds/build-pruning/default-legacy-build-config.yaml b/test/extended/testdata/builds/build-pruning/default-legacy-build-config.yaml index 78a3d92f843b..0e65710a4a8b 100644 --- a/test/extended/testdata/builds/build-pruning/default-legacy-build-config.yaml +++ b/test/extended/testdata/builds/build-pruning/default-legacy-build-config.yaml @@ -1,16 +1,25 @@ -apiVersion: v1 -kind: BuildConfig -metadata: - name: myphp -spec: - source: - type: Git - git: - uri: 'https://github.com/openshift/cakephp-ex.git' - strategy: - type: Source - sourceStrategy: - from: - kind: ImageStreamTag - namespace: openshift - name: 'php:7.0' +{ + "apiVersion": "v1", + "kind": "BuildConfig", + "metadata": { + "name": "myphp" + }, + "spec": { + "source": { + "type": "Git", + "git": { + "uri": "https://github.com/openshift/cakephp-ex.git" + } + }, + "strategy": { + "type": "Source", + "sourceStrategy": { + "from": { + "kind": "ImageStreamTag", + "namespace": "openshift", + "name": "php:7.0" + } + } + } + } +} \ No newline at end of file diff --git a/test/integration/etcd_storage_path_test.go b/test/integration/etcd_storage_path_test.go index 4337a7818d57..45569190aa7f 100644 --- a/test/integration/etcd_storage_path_test.go +++ b/test/integration/etcd_storage_path_test.go @@ -1067,8 +1067,12 @@ func TestEtcd3StoragePath(t *testing.T) { mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version) if err != nil { - t.Errorf("unexpected error getting mapping for %s from %s with GVK %s: %v", kind, pkgPath, gvk, err) - continue + t.Logf("unexpected error getting mapping for %s from %s with GVK %s: %v", kind, pkgPath, gvk, err) + mapping, err = legacyscheme.Registry.RESTMapper().RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + t.Errorf("unexpected error getting mapping for %s from %s with GVK %s: %v", kind, pkgPath, gvk, err) + continue + } } gvResource := gvk.GroupVersion().WithResource(mapping.Resource) diff --git a/test/testdata/bootstrappolicy/cluster_admin_without_apigroups.yaml b/test/testdata/bootstrappolicy/cluster_admin_without_apigroups.yaml index c7446d729034..03e71ebd37c8 100644 --- a/test/testdata/bootstrappolicy/cluster_admin_without_apigroups.yaml +++ b/test/testdata/bootstrappolicy/cluster_admin_without_apigroups.yaml @@ -7,6 +7,7 @@ metadata: rules: - apiGroups: - '' # Allow mutation of Origin policy so we can proxy to RBAC + - 'authorization.openshift.io' # Allow mutation of openshift authoriation groupified so we can proxy to RBAC - 'rbac.authorization.k8s.io' # Allow mutation of RBAC so we can test escalation attributeRestrictions: null resources: