Skip to content

Commit ebd6f88

Browse files
committed
stop shimming the upstream factory inputs
1 parent 7d3a129 commit ebd6f88

18 files changed

+273
-237
lines changed

pkg/oc/cli/cli.go

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
kubecmd "k8s.io/kubernetes/pkg/kubectl/cmd"
1313
ktemplates "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
1414
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
15+
"k8s.io/kubernetes/pkg/kubectl/resource"
1516

1617
"github.com/openshift/origin/pkg/cmd/flagtypes"
1718
"github.com/openshift/origin/pkg/cmd/templates"
@@ -315,6 +316,9 @@ func CommandFor(basename string) *cobra.Command {
315316
case "kubectl":
316317
cmd = kubecmd.NewKubectlCommand(kcmdutil.NewFactory(nil), in, out, errout)
317318
default:
319+
// we only need this change for `oc`. `kubectl` should behave as close to `kubectl` as we can
320+
resource.OAPIToGroupified = OAPIToGroupified
321+
kcmdutil.OAPIToGroupifiedGVK = OAPIToGroupifiedGVK
318322
cmd = NewCommandCLI("oc", "oc", in, out, errout)
319323
}
320324

pkg/oc/cli/groupification.go

+190
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package cli
2+
3+
import (
4+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
5+
"k8s.io/apimachinery/pkg/runtime"
6+
"k8s.io/apimachinery/pkg/runtime/schema"
7+
8+
appsv1 "github.com/openshift/api/apps/v1"
9+
authorizationv1 "github.com/openshift/api/authorization/v1"
10+
buildv1 "github.com/openshift/api/build/v1"
11+
imagev1 "github.com/openshift/api/image/v1"
12+
networkv1 "github.com/openshift/api/network/v1"
13+
oauthv1 "github.com/openshift/api/oauth/v1"
14+
projectv1 "github.com/openshift/api/project/v1"
15+
quotav1 "github.com/openshift/api/quota/v1"
16+
routev1 "github.com/openshift/api/route/v1"
17+
securityv1 "github.com/openshift/api/security/v1"
18+
templatev1 "github.com/openshift/api/template/v1"
19+
userv1 "github.com/openshift/api/user/v1"
20+
"github.com/openshift/origin/pkg/apps/apis/apps"
21+
"github.com/openshift/origin/pkg/authorization/apis/authorization"
22+
"github.com/openshift/origin/pkg/build/apis/build"
23+
"github.com/openshift/origin/pkg/image/apis/image"
24+
"github.com/openshift/origin/pkg/network/apis/network"
25+
"github.com/openshift/origin/pkg/oauth/apis/oauth"
26+
"github.com/openshift/origin/pkg/project/apis/project"
27+
"github.com/openshift/origin/pkg/quota/apis/quota"
28+
"github.com/openshift/origin/pkg/route/apis/route"
29+
"github.com/openshift/origin/pkg/security/apis/security"
30+
"github.com/openshift/origin/pkg/template/apis/template"
31+
"github.com/openshift/origin/pkg/user/apis/user"
32+
)
33+
34+
func OAPIToGroupifiedGVK(gvk *schema.GroupVersionKind) {
35+
if len(gvk.Group) > 0 {
36+
return
37+
}
38+
39+
newGroup, ok := oapiKindsToGroup[gvk.Kind]
40+
if !ok {
41+
return
42+
}
43+
gvk.Group = newGroup
44+
}
45+
46+
func OAPIToGroupified(uncast runtime.Object, gvk *schema.GroupVersionKind) {
47+
if len(gvk.Group) > 0 {
48+
return
49+
}
50+
51+
switch obj := uncast.(type) {
52+
case *unstructured.Unstructured:
53+
newGroup := fixOAPIGroupKindInTopLevelUnstructured(obj.Object)
54+
if len(newGroup) > 0 {
55+
gvk.Group = newGroup
56+
}
57+
case *unstructured.UnstructuredList:
58+
newGroup := fixOAPIGroupKindInTopLevelUnstructured(obj.Object)
59+
if len(newGroup) > 0 {
60+
gvk.Group = newGroup
61+
}
62+
63+
case *apps.DeploymentConfig, *appsv1.DeploymentConfig, *apps.DeploymentConfigList, *appsv1.DeploymentConfigList,
64+
*apps.DeploymentConfigRollback, *appsv1.DeploymentConfigRollback:
65+
gvk.Group = apps.GroupName
66+
67+
case *authorization.ClusterRoleBinding, *authorizationv1.ClusterRoleBinding, *authorization.ClusterRoleBindingList, *authorizationv1.ClusterRoleBindingList,
68+
*authorization.ClusterRole, *authorizationv1.ClusterRole, *authorization.ClusterRoleList, *authorizationv1.ClusterRoleList,
69+
*authorization.Role, *authorizationv1.Role, *authorization.RoleList, *authorizationv1.RoleList,
70+
*authorization.RoleBinding, *authorizationv1.RoleBinding, *authorization.RoleBindingList, *authorizationv1.RoleBindingList,
71+
*authorization.RoleBindingRestriction, *authorizationv1.RoleBindingRestriction, *authorization.RoleBindingRestrictionList, *authorizationv1.RoleBindingRestrictionList:
72+
gvk.Group = authorization.GroupName
73+
74+
case *build.BuildConfig, *buildv1.BuildConfig, *build.BuildConfigList, *buildv1.BuildConfigList,
75+
*build.Build, *buildv1.Build, *build.BuildList, *buildv1.BuildList:
76+
gvk.Group = build.GroupName
77+
78+
case *image.Image, *imagev1.Image, *image.ImageList, *imagev1.ImageList,
79+
*image.ImageSignature, *imagev1.ImageSignature,
80+
*image.ImageStreamImage, *imagev1.ImageStreamImage,
81+
*image.ImageStreamImport, *imagev1.ImageStreamImport,
82+
*image.ImageStreamMapping, *imagev1.ImageStreamMapping,
83+
*image.ImageStream, *imagev1.ImageStream, *image.ImageStreamList, *imagev1.ImageStreamList,
84+
*image.ImageStreamTag, *imagev1.ImageStreamTag:
85+
gvk.Group = image.GroupName
86+
87+
case *network.ClusterNetwork, *networkv1.ClusterNetwork, *network.ClusterNetworkList, *networkv1.ClusterNetworkList,
88+
*network.NetNamespace, *networkv1.NetNamespace, *network.NetNamespaceList, *networkv1.NetNamespaceList,
89+
*network.HostSubnet, *networkv1.HostSubnet, *network.HostSubnetList, *networkv1.HostSubnetList,
90+
*network.EgressNetworkPolicy, *networkv1.EgressNetworkPolicy, *network.EgressNetworkPolicyList, *networkv1.EgressNetworkPolicyList:
91+
gvk.Group = network.GroupName
92+
93+
case *project.Project, *projectv1.Project, *project.ProjectList, *projectv1.ProjectList,
94+
*project.ProjectRequest, *projectv1.ProjectRequest:
95+
gvk.Group = project.GroupName
96+
97+
case *quota.ClusterResourceQuota, *quotav1.ClusterResourceQuota, *quota.ClusterResourceQuotaList, *quotav1.ClusterResourceQuotaList:
98+
gvk.Group = quota.GroupName
99+
100+
case *oauth.OAuthAuthorizeToken, *oauthv1.OAuthAuthorizeToken, *oauth.OAuthAuthorizeTokenList, *oauthv1.OAuthAuthorizeTokenList,
101+
*oauth.OAuthClientAuthorization, *oauthv1.OAuthClientAuthorization, *oauth.OAuthClientAuthorizationList, *oauthv1.OAuthClientAuthorizationList,
102+
*oauth.OAuthClient, *oauthv1.OAuthClient, *oauth.OAuthClientList, *oauthv1.OAuthClientList,
103+
*oauth.OAuthAccessToken, *oauthv1.OAuthAccessToken, *oauth.OAuthAccessTokenList, *oauthv1.OAuthAccessTokenList:
104+
gvk.Group = oauth.GroupName
105+
106+
case *route.Route, *routev1.Route, *route.RouteList, *routev1.RouteList:
107+
gvk.Group = route.GroupName
108+
109+
case *security.SecurityContextConstraints, *securityv1.SecurityContextConstraints, *security.SecurityContextConstraintsList, *securityv1.SecurityContextConstraintsList:
110+
gvk.Group = security.GroupName
111+
112+
case *template.Template, *templatev1.Template, *template.TemplateList, *templatev1.TemplateList:
113+
gvk.Group = template.GroupName
114+
115+
case *user.Group, *userv1.Group, *user.GroupList, *userv1.GroupList,
116+
*user.Identity, *userv1.Identity, *user.IdentityList, *userv1.IdentityList,
117+
*user.UserIdentityMapping, *userv1.UserIdentityMapping,
118+
*user.User, *userv1.User, *user.UserList, *userv1.UserList:
119+
gvk.Group = user.GroupName
120+
121+
}
122+
}
123+
124+
var oapiKindsToGroup = map[string]string{
125+
"DeploymentConfigRollback": "apps.openshift.io",
126+
"DeploymentConfig": "apps.openshift.io", "DeploymentConfigList": "apps.openshift.io",
127+
"ClusterRoleBinding": "authorization.openshift.io", "ClusterRoleBindingList": "authorization.openshift.io",
128+
"ClusterRole": "authorization.openshift.io", "ClusterRoleList": "authorization.openshift.io",
129+
"RoleBindingRestriction": "authorization.openshift.io", "RoleBindingRestrictionList": "authorization.openshift.io",
130+
"RoleBinding": "authorization.openshift.io", "RoleBindingList": "authorization.openshift.io",
131+
"Role": "authorization.openshift.io", "RoleList": "authorization.openshift.io",
132+
"BuildConfig": "build.openshift.io", "BuildConfigList": "build.openshift.io",
133+
"Build": "build.openshift.io", "BuildList": "build.openshift.io",
134+
"Image": "image.openshift.io", "ImageList": "image.openshift.io",
135+
"ImageSignature": "image.openshift.io",
136+
"ImageStreamImage": "image.openshift.io",
137+
"ImageStreamImport": "image.openshift.io",
138+
"ImageStreamMapping": "image.openshift.io",
139+
"ImageStream": "image.openshift.io", "ImageStreamList": "image.openshift.io",
140+
"ImageStreamTag": "image.openshift.io", "ImageStreamTagList": "image.openshift.io",
141+
"ClusterNetwork": "network.openshift.io", "ClusterNetworkList": "network.openshift.io",
142+
"EgressNetworkPolicy": "network.openshift.io", "EgressNetworkPolicyList": "network.openshift.io",
143+
"HostSubnet": "network.openshift.io", "HostSubnetList": "network.openshift.io",
144+
"NetNamespace": "network.openshift.io", "NetNamespaceList": "network.openshift.io",
145+
"OAuthAccessToken": "oauth.openshift.io", "OAuthAccessTokenList": "oauth.openshift.io",
146+
"OAuthAuthorizeToken": "oauth.openshift.io", "OAuthAuthorizeTokenList": "oauth.openshift.io",
147+
"OAuthClientAuthorization": "oauth.openshift.io", "OAuthClientAuthorizationList": "oauth.openshift.io",
148+
"OAuthClient": "oauth.openshift.io", "OAuthClientList": "oauth.openshift.io",
149+
"Project": "project.openshift.io", "ProjectList": "project.openshift.io",
150+
"ProjectRequest": "project.openshift.io",
151+
"ClusterResourceQuota": "quota.openshift.io", "ClusterResourceQuotaList": "quota.openshift.io",
152+
"Route": "route.openshift.io", "RouteList": "route.openshift.io",
153+
"SecurityContextConstraint": "security.openshift.io", "SecurityContextConstraintList": "security.openshift.io",
154+
"Template": "template.openshift.io", "TemplateList": "template.openshift.io",
155+
"Group": "user.openshift.io", "GroupList": "user.openshift.io",
156+
"Identity": "user.openshift.io", "IdentityList": "user.openshift.io",
157+
"UserIdentityMapping": "user.openshift.io",
158+
"User": "user.openshift.io", "UserList": "user.openshift.io",
159+
}
160+
161+
func fixOAPIGroupKindInTopLevelUnstructured(obj map[string]interface{}) string {
162+
kind, ok := obj["kind"]
163+
if !ok {
164+
return ""
165+
}
166+
kindStr, ok := kind.(string)
167+
if !ok {
168+
return ""
169+
}
170+
newGroup, ok := oapiKindsToGroup[kindStr]
171+
if !ok {
172+
return ""
173+
}
174+
175+
apiVersion, ok := obj["apiVersion"]
176+
if !ok {
177+
return newGroup
178+
}
179+
apiVersionStr, ok := apiVersion.(string)
180+
if !ok {
181+
return newGroup
182+
}
183+
184+
if apiVersionStr != "v1" {
185+
return newGroup
186+
}
187+
obj["apiVersion"] = newGroup + "/v1"
188+
189+
return newGroup
190+
}

pkg/oc/cli/util/clientcmd/factory.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func New(flags *pflag.FlagSet) *Factory {
4848

4949
// Factory provides common options for OpenShift commands
5050
type Factory struct {
51-
ClientAccessFactory
51+
kcmdutil.ClientAccessFactory
5252
kcmdutil.ObjectMappingFactory
5353
kcmdutil.BuilderFactory
5454
}

pkg/oc/cli/util/clientcmd/factory_builder.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ import (
2525
)
2626

2727
type ring2Factory struct {
28-
clientAccessFactory ClientAccessFactory
28+
clientAccessFactory kcmdutil.ClientAccessFactory
2929
objectMappingFactory kcmdutil.ObjectMappingFactory
3030
kubeBuilderFactory kcmdutil.BuilderFactory
3131
}
3232

33-
func NewBuilderFactory(clientAccessFactory ClientAccessFactory, objectMappingFactory kcmdutil.ObjectMappingFactory) kcmdutil.BuilderFactory {
33+
func NewBuilderFactory(clientAccessFactory kcmdutil.ClientAccessFactory, objectMappingFactory kcmdutil.ObjectMappingFactory) kcmdutil.BuilderFactory {
3434
return &ring2Factory{
3535
clientAccessFactory: clientAccessFactory,
3636
objectMappingFactory: objectMappingFactory,

pkg/oc/cli/util/clientcmd/factory_client_access.go

+7-68
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ package clientcmd
22

33
import (
44
"errors"
5-
"net/http"
65
"path/filepath"
76
"regexp"
87
"strconv"
98
"strings"
10-
"time"
119

1210
"github.com/spf13/cobra"
1311
"github.com/spf13/pflag"
@@ -21,14 +19,12 @@ import (
2119
restclient "k8s.io/client-go/rest"
2220
kclientcmd "k8s.io/client-go/tools/clientcmd"
2321
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
24-
"k8s.io/client-go/util/homedir"
2522
kapi "k8s.io/kubernetes/pkg/apis/core"
2623
kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
2724
"k8s.io/kubernetes/pkg/kubectl"
2825
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
2926
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
3027
"k8s.io/kubernetes/pkg/kubectl/resource"
31-
"k8s.io/kubernetes/pkg/kubectl/util/transport"
3228

3329
appsapiv1 "github.com/openshift/api/apps/v1"
3430
appsapi "github.com/openshift/origin/pkg/apps/apis/apps"
@@ -38,83 +34,22 @@ import (
3834
)
3935

4036
type ring0Factory struct {
41-
clientConfig kclientcmd.ClientConfig
4237
kubeClientAccessFactory kcmdutil.ClientAccessFactory
4338
}
4439

45-
type ClientAccessFactory interface {
46-
kcmdutil.ClientAccessFactory
47-
}
48-
49-
func NewClientAccessFactory(optionalClientConfig kclientcmd.ClientConfig) ClientAccessFactory {
40+
func NewClientAccessFactory(optionalClientConfig kclientcmd.ClientConfig) kcmdutil.ClientAccessFactory {
5041
// if we call this factory construction method, we want the openshift style config loading
5142
kclientcmd.UseOpenShiftKubeConfigValues = true
5243
kclientcmd.ErrEmptyConfig = kclientcmd.NewErrConfigurationMissing()
5344
set.ParseDockerImageReferenceToStringFunc = ParseDockerImageReferenceToStringFunc
5445

55-
flags := pflag.NewFlagSet("", pflag.ContinueOnError)
56-
clientConfig := optionalClientConfig
57-
if optionalClientConfig == nil {
58-
clientConfig = kcmdutil.DefaultClientConfig(flags)
59-
}
6046
factory := &ring0Factory{
61-
clientConfig: clientConfig,
47+
kubeClientAccessFactory: kcmdutil.NewClientAccessFactory(optionalClientConfig),
6248
}
63-
factory.kubeClientAccessFactory = kcmdutil.NewClientAccessFactoryFromDiscovery(
64-
flags,
65-
clientConfig,
66-
&discoveryFactory{clientConfig: clientConfig},
67-
)
6849

6950
return factory
7051
}
7152

72-
type discoveryFactory struct {
73-
clientConfig kclientcmd.ClientConfig
74-
cacheDir string
75-
}
76-
77-
func (f *discoveryFactory) BindFlags(flags *pflag.FlagSet) {
78-
defaultCacheDir := filepath.Join(homedir.HomeDir(), ".kube", "http-cache")
79-
flags.StringVar(&f.cacheDir, kcmdutil.FlagHTTPCacheDir, defaultCacheDir, "Default HTTP cache directory")
80-
}
81-
82-
func (f *discoveryFactory) DiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
83-
// Output using whatever version was negotiated in the client cache. The
84-
// version we decode with may not be the same as what the server requires.
85-
cfg, err := f.clientConfig.ClientConfig()
86-
if err != nil {
87-
return nil, err
88-
}
89-
// given 25 groups with one-ish version each, discovery needs to make 50 requests
90-
// double it just so we don't end up here again for a while. This config is only used for discovery.
91-
cfg.Burst = 100
92-
93-
if f.cacheDir != "" {
94-
wt := cfg.WrapTransport
95-
cfg.WrapTransport = func(rt http.RoundTripper) http.RoundTripper {
96-
if wt != nil {
97-
rt = wt(rt)
98-
}
99-
return transport.NewCacheRoundTripper(f.cacheDir, rt)
100-
}
101-
}
102-
103-
// at this point we've negotiated and can get the client
104-
kubeClient, err := kclientset.NewForConfig(cfg)
105-
if err != nil {
106-
return nil, err
107-
108-
}
109-
110-
cacheDir := computeDiscoverCacheDir(filepath.Join(homedir.HomeDir(), ".kube", "cache", "discovery"), cfg.Host)
111-
return kcmdutil.NewCachedDiscoveryClient(newLegacyDiscoveryClient(kubeClient.Discovery().RESTClient()), cacheDir, time.Duration(10*time.Minute)), nil
112-
}
113-
114-
func (f *ring0Factory) RawConfig() (clientcmdapi.Config, error) {
115-
return f.kubeClientAccessFactory.RawConfig()
116-
}
117-
11853
func (f *ring0Factory) DiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
11954
return f.kubeClientAccessFactory.DiscoveryClient()
12055
}
@@ -131,8 +66,12 @@ func (f *ring0Factory) ClientConfig() (*restclient.Config, error) {
13166
return f.kubeClientAccessFactory.ClientConfig()
13267
}
13368

69+
func (f *ring0Factory) RawConfig() (clientcmdapi.Config, error) {
70+
return f.kubeClientAccessFactory.RawConfig()
71+
}
72+
13473
func (f *ring0Factory) BareClientConfig() (*restclient.Config, error) {
135-
return f.clientConfig.ClientConfig()
74+
return f.kubeClientAccessFactory.BareClientConfig()
13675
}
13776

13877
func (f *ring0Factory) RESTClient() (*restclient.RESTClient, error) {

0 commit comments

Comments
 (0)