Skip to content

Commit

Permalink
stop shimming the upstream factory inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
deads2k committed Apr 13, 2018
1 parent c6b766f commit 80bdf3f
Show file tree
Hide file tree
Showing 18 changed files with 336 additions and 157 deletions.
4 changes: 4 additions & 0 deletions pkg/oc/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/oc/cli/cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (o *VersionOptions) Complete(cmd *cobra.Command, f *clientcmd.Factory, out
o.Clients = f.ClientSet
var err error
o.ClientConfig, err = f.ClientConfig()
if err != nil && !clientcmd.IsConfigurationMissing(err) {
if err != nil && !kclientcmd.IsEmptyConfig(err) {
return err
}

Expand Down
190 changes: 190 additions & 0 deletions pkg/oc/cli/groupification.go
Original file line number Diff line number Diff line change
@@ -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
}
69 changes: 6 additions & 63 deletions pkg/oc/cli/util/clientcmd/factory_client_access.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package clientcmd

import (
"errors"
"net/http"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"

"github.com/spf13/cobra"
"github.com/spf13/pflag"
Expand All @@ -21,13 +19,11 @@ 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"
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"
Expand All @@ -37,7 +33,6 @@ import (
)

type ring0Factory struct {
clientConfig kclientcmd.ClientConfig
imageResolutionOptions FlagBinder
kubeClientAccessFactory kcmdutil.ClientAccessFactory
}
Expand All @@ -53,70 +48,14 @@ func NewClientAccessFactory(optionalClientConfig kclientcmd.ClientConfig) Client
kclientcmd.UseOpenShiftKubeConfigValues = true
kclientcmd.ErrEmptyConfig = kclientcmd.NewErrConfigurationMissing()

flags := pflag.NewFlagSet("", pflag.ContinueOnError)
clientConfig := optionalClientConfig
if optionalClientConfig == nil {
clientConfig = kcmdutil.DefaultClientConfig(flags)
}
factory := &ring0Factory{
clientConfig: clientConfig,
imageResolutionOptions: &imageResolutionOptions{},
}
factory.kubeClientAccessFactory = kcmdutil.NewClientAccessFactoryFromDiscovery(
flags,
clientConfig,
&discoveryFactory{clientConfig: clientConfig},
)
factory.kubeClientAccessFactory = kcmdutil.NewClientAccessFactory(optionalClientConfig)

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()
}
Expand All @@ -133,8 +72,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) {
Expand Down
Loading

0 comments on commit 80bdf3f

Please sign in to comment.