mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-03 23:40:03 +00:00 
			
		
		
		
	[Federation][Kubefed] Use the discovered api version using the discovery client for RBAC
This commit is contained in:
		@@ -48,6 +48,7 @@ go_test(
 | 
				
			|||||||
        "//pkg/api/testapi:go_default_library",
 | 
					        "//pkg/api/testapi:go_default_library",
 | 
				
			||||||
        "//pkg/api/v1:go_default_library",
 | 
					        "//pkg/api/v1:go_default_library",
 | 
				
			||||||
        "//pkg/apis/extensions/v1beta1:go_default_library",
 | 
					        "//pkg/apis/extensions/v1beta1:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/apis/rbac:go_default_library",
 | 
				
			||||||
        "//pkg/apis/rbac/v1beta1:go_default_library",
 | 
					        "//pkg/apis/rbac/v1beta1:go_default_library",
 | 
				
			||||||
        "//pkg/kubectl/cmd/testing:go_default_library",
 | 
					        "//pkg/kubectl/cmd/testing:go_default_library",
 | 
				
			||||||
        "//pkg/kubectl/cmd/util:go_default_library",
 | 
					        "//pkg/kubectl/cmd/util:go_default_library",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -261,6 +261,17 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rbacAvailable := true
 | 
				
			||||||
 | 
						rbacVersionedClientset, err := util.GetVersionedClientForRBACOrFail(hostFactory)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if _, ok := err.(*util.NoRBACAPIError); !ok {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// If the error is type NoRBACAPIError, We continue to create the rest of
 | 
				
			||||||
 | 
							// the resources, without the SA and roles (in the abscense of RBAC support).
 | 
				
			||||||
 | 
							rbacAvailable = false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	serverName := fmt.Sprintf("%s-%s", i.commonOptions.Name, APIServerNameSuffix)
 | 
						serverName := fmt.Sprintf("%s-%s", i.commonOptions.Name, APIServerNameSuffix)
 | 
				
			||||||
	serverCredName := fmt.Sprintf("%s-%s", serverName, CredentialSuffix)
 | 
						serverCredName := fmt.Sprintf("%s-%s", serverName, CredentialSuffix)
 | 
				
			||||||
	cmName := fmt.Sprintf("%s-%s", i.commonOptions.Name, CMNameSuffix)
 | 
						cmName := fmt.Sprintf("%s-%s", i.commonOptions.Name, CMNameSuffix)
 | 
				
			||||||
@@ -329,19 +340,26 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 7. Create federation controller manager
 | 
						sa := &api.ServiceAccount{}
 | 
				
			||||||
	// 7a. Create a service account in the host cluster for federation
 | 
						sa.Name = ""
 | 
				
			||||||
	// controller manager.
 | 
						// 7. Create deployment for federation controller manager
 | 
				
			||||||
	sa, err := createControllerManagerSA(hostClientset, i.commonOptions.FederationSystemNamespace, i.options.dryRun)
 | 
						// The below code either creates the SA and the related roles or skips
 | 
				
			||||||
	if err != nil {
 | 
						// creating the same if the RBAC support is not found in the base cluster
 | 
				
			||||||
		return err
 | 
						// TODO: We must evaluate creating a separate service account even when RBAC support is missing
 | 
				
			||||||
	}
 | 
						if rbacAvailable {
 | 
				
			||||||
 | 
							// 7a. Create a service account in the host cluster for federation
 | 
				
			||||||
 | 
							// controller manager.
 | 
				
			||||||
 | 
							sa, err = createControllerManagerSA(rbacVersionedClientset, i.commonOptions.FederationSystemNamespace, i.options.dryRun)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 7b. Create RBAC role and role binding for federation controller
 | 
							// 7b. Create RBAC role and role binding for federation controller
 | 
				
			||||||
	// manager service account.
 | 
							// manager service account.
 | 
				
			||||||
	_, _, err = createRoleBindings(hostClientset, i.commonOptions.FederationSystemNamespace, sa.Name, i.options.dryRun)
 | 
							_, _, err = createRoleBindings(rbacVersionedClientset, i.commonOptions.FederationSystemNamespace, sa.Name, i.options.dryRun)
 | 
				
			||||||
	if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
		return err
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 7c. Create a dns-provider config secret
 | 
						// 7c. Create a dns-provider config secret
 | 
				
			||||||
@@ -874,12 +892,15 @@ func createControllerManager(clientset client.Interface, namespace, name, svcNam
 | 
				
			|||||||
							},
 | 
												},
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
					ServiceAccountName: saName,
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if saName != "" {
 | 
				
			||||||
 | 
							dep.Spec.Template.Spec.ServiceAccountName = saName
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if dryRun {
 | 
						if dryRun {
 | 
				
			||||||
		return dep, nil
 | 
							return dep, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,6 +48,7 @@ import (
 | 
				
			|||||||
	"k8s.io/kubernetes/pkg/api/testapi"
 | 
						"k8s.io/kubernetes/pkg/api/testapi"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/v1"
 | 
						"k8s.io/kubernetes/pkg/api/v1"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
 | 
						"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/apis/rbac"
 | 
				
			||||||
	rbacv1beta1 "k8s.io/kubernetes/pkg/apis/rbac/v1beta1"
 | 
						rbacv1beta1 "k8s.io/kubernetes/pkg/apis/rbac/v1beta1"
 | 
				
			||||||
	cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
 | 
						cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
 | 
				
			||||||
	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
 | 
						cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
 | 
				
			||||||
@@ -63,6 +64,9 @@ const (
 | 
				
			|||||||
	lbIP     = "10.20.30.40"
 | 
						lbIP     = "10.20.30.40"
 | 
				
			||||||
	nodeIP   = "10.20.30.50"
 | 
						nodeIP   = "10.20.30.50"
 | 
				
			||||||
	nodePort = 32111
 | 
						nodePort = 32111
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						testAPIGroup   = "testGroup"
 | 
				
			||||||
 | 
						testAPIVersion = "testVersion"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestInitFederation(t *testing.T) {
 | 
					func TestInitFederation(t *testing.T) {
 | 
				
			||||||
@@ -96,6 +100,7 @@ func TestInitFederation(t *testing.T) {
 | 
				
			|||||||
		cmArgOverrides               string
 | 
							cmArgOverrides               string
 | 
				
			||||||
		apiserverEnableHTTPBasicAuth bool
 | 
							apiserverEnableHTTPBasicAuth bool
 | 
				
			||||||
		apiserverEnableTokenAuth     bool
 | 
							apiserverEnableTokenAuth     bool
 | 
				
			||||||
 | 
							isRBACAPIAvailable           bool
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			federation:            "union",
 | 
								federation:            "union",
 | 
				
			||||||
@@ -191,6 +196,7 @@ func TestInitFederation(t *testing.T) {
 | 
				
			|||||||
			dryRun:               "",
 | 
								dryRun:               "",
 | 
				
			||||||
			apiserverEnableHTTPBasicAuth: true,
 | 
								apiserverEnableHTTPBasicAuth: true,
 | 
				
			||||||
			apiserverEnableTokenAuth:     true,
 | 
								apiserverEnableTokenAuth:     true,
 | 
				
			||||||
 | 
								isRBACAPIAvailable:           true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -198,6 +204,7 @@ func TestInitFederation(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for i, tc := range testCases {
 | 
						for i, tc := range testCases {
 | 
				
			||||||
		cmdErrMsg = ""
 | 
							cmdErrMsg = ""
 | 
				
			||||||
 | 
							tmpDirPath := ""
 | 
				
			||||||
		buf := bytes.NewBuffer([]byte{})
 | 
							buf := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if tc.dnsProviderConfig != "" {
 | 
							if tc.dnsProviderConfig != "" {
 | 
				
			||||||
@@ -208,7 +215,16 @@ func TestInitFederation(t *testing.T) {
 | 
				
			|||||||
			tc.dnsProviderConfig = tmpfile.Name()
 | 
								tc.dnsProviderConfig = tmpfile.Name()
 | 
				
			||||||
			defer os.Remove(tmpfile.Name())
 | 
								defer os.Remove(tmpfile.Name())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		hostFactory, err := fakeInitHostFactory(tc.apiserverServiceType, tc.federation, util.DefaultFederationSystemNamespace, tc.advertiseAddress, tc.lbIP, tc.dnsZoneName, tc.image, dnsProvider, tc.dnsProviderConfig, tc.etcdPersistence, tc.etcdPVCapacity, tc.apiserverArgOverrides, tc.cmArgOverrides, tc.apiserverEnableHTTPBasicAuth, tc.apiserverEnableTokenAuth)
 | 
					
 | 
				
			||||||
 | 
							// Check pkg/kubectl/cmd/testing/fake (fakeAPIFactory.DiscoveryClient()) for details of tmpDir
 | 
				
			||||||
 | 
							// We want an unique discovery cache path for each test run, else the case from previous case would be used
 | 
				
			||||||
 | 
							tmpDirPath, err = ioutil.TempDir("", "")
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatalf("[%d] unexpected error: %v", i, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							defer os.Remove(tmpDirPath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							hostFactory, err := fakeInitHostFactory(tc.apiserverServiceType, tc.federation, util.DefaultFederationSystemNamespace, tc.advertiseAddress, tc.lbIP, tc.dnsZoneName, tc.image, dnsProvider, tc.dnsProviderConfig, tc.etcdPersistence, tc.etcdPVCapacity, tc.apiserverArgOverrides, tc.cmArgOverrides, tmpDirPath, tc.apiserverEnableHTTPBasicAuth, tc.apiserverEnableTokenAuth, tc.isRBACAPIAvailable)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			t.Fatalf("[%d] unexpected error: %v", i, err)
 | 
								t.Fatalf("[%d] unexpected error: %v", i, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -577,7 +593,7 @@ func TestCertsHTTPS(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, namespaceName, advertiseAddress, lbIp, dnsZoneName, image, dnsProvider, dnsProviderConfig, etcdPersistence, etcdPVCapacity, apiserverOverrideArg, cmOverrideArg string, apiserverEnableHTTPBasicAuth, apiserverEnableTokenAuth bool) (cmdutil.Factory, error) {
 | 
					func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, namespaceName, advertiseAddress, lbIp, dnsZoneName, image, dnsProvider, dnsProviderConfig, etcdPersistence, etcdPVCapacity, apiserverOverrideArg, cmOverrideArg, tmpDirPath string, apiserverEnableHTTPBasicAuth, apiserverEnableTokenAuth, isRBACAPIAvailable bool) (cmdutil.Factory, error) {
 | 
				
			||||||
	svcName := federationName + "-apiserver"
 | 
						svcName := federationName + "-apiserver"
 | 
				
			||||||
	svcUrlPrefix := "/api/v1/namespaces/federation-system/services"
 | 
						svcUrlPrefix := "/api/v1/namespaces/federation-system/services"
 | 
				
			||||||
	credSecretName := svcName + "-credentials"
 | 
						credSecretName := svcName + "-credentials"
 | 
				
			||||||
@@ -982,12 +998,14 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
 | 
				
			|||||||
							},
 | 
												},
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
					ServiceAccountName:       "federation-controller-manager",
 | 
					 | 
				
			||||||
					DeprecatedServiceAccount: "federation-controller-manager",
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if isRBACAPIAvailable {
 | 
				
			||||||
 | 
							cm.Spec.Template.Spec.ServiceAccountName = "federation-controller-manager"
 | 
				
			||||||
 | 
							cm.Spec.Template.Spec.DeprecatedServiceAccount = "federation-controller-manager"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if dnsProviderConfig != "" {
 | 
						if dnsProviderConfig != "" {
 | 
				
			||||||
		cm = addDNSProviderConfigTest(cm, cmDNSProviderSecret.Name)
 | 
							cm = addDNSProviderConfigTest(cm, cmDNSProviderSecret.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1024,11 +1042,37 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
 | 
				
			|||||||
	podList.Items = append(podList.Items, apiServerPod)
 | 
						podList.Items = append(podList.Items, apiServerPod)
 | 
				
			||||||
	podList.Items = append(podList.Items, cmPod)
 | 
						podList.Items = append(podList.Items, cmPod)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						apiGroupList := &metav1.APIGroupList{}
 | 
				
			||||||
 | 
						testGroup := metav1.APIGroup{
 | 
				
			||||||
 | 
							Name: testAPIGroup,
 | 
				
			||||||
 | 
							Versions: []metav1.GroupVersionForDiscovery{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									GroupVersion: testAPIGroup + "/" + testAPIVersion,
 | 
				
			||||||
 | 
									Version:      testAPIVersion,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						rbacGroup := metav1.APIGroup{
 | 
				
			||||||
 | 
							Name: rbac.GroupName,
 | 
				
			||||||
 | 
							Versions: []metav1.GroupVersionForDiscovery{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									GroupVersion: rbac.GroupName + "/v1beta1",
 | 
				
			||||||
 | 
									Version:      "v1beta1",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						apiGroupList.Groups = append(apiGroupList.Groups, testGroup)
 | 
				
			||||||
 | 
						if isRBACAPIAvailable {
 | 
				
			||||||
 | 
							apiGroupList.Groups = append(apiGroupList.Groups, rbacGroup)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f, tf, codec, _ := cmdtesting.NewAPIFactory()
 | 
						f, tf, codec, _ := cmdtesting.NewAPIFactory()
 | 
				
			||||||
	extCodec := testapi.Extensions.Codec()
 | 
						extCodec := testapi.Extensions.Codec()
 | 
				
			||||||
	rbacCodec := testapi.Rbac.Codec()
 | 
						rbacCodec := testapi.Rbac.Codec()
 | 
				
			||||||
	ns := dynamic.ContentConfig().NegotiatedSerializer
 | 
						ns := dynamic.ContentConfig().NegotiatedSerializer
 | 
				
			||||||
	tf.ClientConfig = kubefedtesting.DefaultClientConfig()
 | 
						tf.ClientConfig = kubefedtesting.DefaultClientConfig()
 | 
				
			||||||
 | 
						tf.TmpDir = tmpDirPath
 | 
				
			||||||
	tf.Client = &fake.RESTClient{
 | 
						tf.Client = &fake.RESTClient{
 | 
				
			||||||
		APIRegistry:          api.Registry,
 | 
							APIRegistry:          api.Registry,
 | 
				
			||||||
		NegotiatedSerializer: ns,
 | 
							NegotiatedSerializer: ns,
 | 
				
			||||||
@@ -1036,6 +1080,10 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
 | 
				
			|||||||
			switch p, m := req.URL.Path, req.Method; {
 | 
								switch p, m := req.URL.Path, req.Method; {
 | 
				
			||||||
			case p == "/healthz":
 | 
								case p == "/healthz":
 | 
				
			||||||
				return &http.Response{StatusCode: http.StatusOK, Header: kubefedtesting.DefaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte("ok")))}, nil
 | 
									return &http.Response{StatusCode: http.StatusOK, Header: kubefedtesting.DefaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte("ok")))}, nil
 | 
				
			||||||
 | 
								case p == "/api" && m == http.MethodGet:
 | 
				
			||||||
 | 
									return &http.Response{StatusCode: http.StatusOK, Header: kubefedtesting.DefaultHeader(), Body: kubefedtesting.ObjBody(codec, &metav1.APIVersions{})}, nil
 | 
				
			||||||
 | 
								case p == "/apis" && m == http.MethodGet:
 | 
				
			||||||
 | 
									return &http.Response{StatusCode: http.StatusOK, Header: kubefedtesting.DefaultHeader(), Body: kubefedtesting.ObjBody(codec, apiGroupList)}, nil
 | 
				
			||||||
			case p == "/api/v1/namespaces" && m == http.MethodPost:
 | 
								case p == "/api/v1/namespaces" && m == http.MethodPost:
 | 
				
			||||||
				body, err := ioutil.ReadAll(req.Body)
 | 
									body, err := ioutil.ReadAll(req.Body)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,12 +15,14 @@ go_library(
 | 
				
			|||||||
        "//federation/apis/federation:go_default_library",
 | 
					        "//federation/apis/federation:go_default_library",
 | 
				
			||||||
        "//federation/client/clientset_generated/federation_clientset:go_default_library",
 | 
					        "//federation/client/clientset_generated/federation_clientset:go_default_library",
 | 
				
			||||||
        "//pkg/api:go_default_library",
 | 
					        "//pkg/api:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/apis/rbac:go_default_library",
 | 
				
			||||||
        "//pkg/client/clientset_generated/internalclientset:go_default_library",
 | 
					        "//pkg/client/clientset_generated/internalclientset:go_default_library",
 | 
				
			||||||
        "//pkg/kubectl/cmd:go_default_library",
 | 
					        "//pkg/kubectl/cmd:go_default_library",
 | 
				
			||||||
        "//pkg/kubectl/cmd/util:go_default_library",
 | 
					        "//pkg/kubectl/cmd/util:go_default_library",
 | 
				
			||||||
        "//vendor:github.com/spf13/cobra",
 | 
					        "//vendor:github.com/spf13/cobra",
 | 
				
			||||||
        "//vendor:github.com/spf13/pflag",
 | 
					        "//vendor:github.com/spf13/pflag",
 | 
				
			||||||
        "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
 | 
					        "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
 | 
				
			||||||
 | 
					        "//vendor:k8s.io/apimachinery/pkg/runtime/schema",
 | 
				
			||||||
        "//vendor:k8s.io/apimachinery/pkg/util/net",
 | 
					        "//vendor:k8s.io/apimachinery/pkg/util/net",
 | 
				
			||||||
        "//vendor:k8s.io/client-go/rest",
 | 
					        "//vendor:k8s.io/client-go/rest",
 | 
				
			||||||
        "//vendor:k8s.io/client-go/tools/clientcmd",
 | 
					        "//vendor:k8s.io/client-go/tools/clientcmd",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,18 +21,19 @@ import (
 | 
				
			|||||||
	"net"
 | 
						"net"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/runtime/schema"
 | 
				
			||||||
 | 
						utilnet "k8s.io/apimachinery/pkg/util/net"
 | 
				
			||||||
 | 
						restclient "k8s.io/client-go/rest"
 | 
				
			||||||
	"k8s.io/client-go/tools/clientcmd"
 | 
						"k8s.io/client-go/tools/clientcmd"
 | 
				
			||||||
	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
 | 
						clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
 | 
				
			||||||
 | 
						federationapi "k8s.io/kubernetes/federation/apis/federation"
 | 
				
			||||||
	fedclient "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
 | 
						fedclient "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api"
 | 
						"k8s.io/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/apis/rbac"
 | 
				
			||||||
	client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
 | 
						client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
 | 
				
			||||||
	kubectlcmd "k8s.io/kubernetes/pkg/kubectl/cmd"
 | 
						kubectlcmd "k8s.io/kubernetes/pkg/kubectl/cmd"
 | 
				
			||||||
	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
 | 
						cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	utilnet "k8s.io/apimachinery/pkg/util/net"
 | 
					 | 
				
			||||||
	restclient "k8s.io/client-go/rest"
 | 
					 | 
				
			||||||
	federationapi "k8s.io/kubernetes/federation/apis/federation"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
	"github.com/spf13/pflag"
 | 
						"github.com/spf13/pflag"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -54,8 +55,19 @@ const (
 | 
				
			|||||||
	userAgentName = "kubefed-tool"
 | 
						userAgentName = "kubefed-tool"
 | 
				
			||||||
	KubeAPIQPS    = 20.0
 | 
						KubeAPIQPS    = 20.0
 | 
				
			||||||
	KubeAPIBurst  = 30
 | 
						KubeAPIBurst  = 30
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rbacAPINotAvailable = "RBAC API not available"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// used to identify the rbac api availability error.
 | 
				
			||||||
 | 
					type NoRBACAPIError struct {
 | 
				
			||||||
 | 
						s string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n *NoRBACAPIError) Error() string {
 | 
				
			||||||
 | 
						return n.s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AdminConfig provides a filesystem based kubeconfig (via
 | 
					// AdminConfig provides a filesystem based kubeconfig (via
 | 
				
			||||||
// `PathOptions()`) and a mechanism to talk to the federation
 | 
					// `PathOptions()`) and a mechanism to talk to the federation
 | 
				
			||||||
// host cluster and the federation control plane api server.
 | 
					// host cluster and the federation control plane api server.
 | 
				
			||||||
@@ -211,3 +223,40 @@ func buildConfigFromSecret(secret *api.Secret, serverAddress string) (*restclien
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return clusterConfig, nil
 | 
						return clusterConfig, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetVersionedClientForRBACOrFail discovers the versioned rbac APIs and gets the versioned
 | 
				
			||||||
 | 
					// clientset for either the preferred version or the first listed version (if no preference listed)
 | 
				
			||||||
 | 
					// TODO: We need to evaluate the usage of RESTMapper interface to achieve te same functionality
 | 
				
			||||||
 | 
					func GetVersionedClientForRBACOrFail(hostFactory cmdutil.Factory) (client.Interface, error) {
 | 
				
			||||||
 | 
						discoveryclient, err := hostFactory.DiscoveryClient()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						groupList, err := discoveryclient.ServerGroups()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("Couldn't get clientset to create RBAC roles in the host cluster: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, g := range groupList.Groups {
 | 
				
			||||||
 | 
							if g.Name == rbac.GroupName {
 | 
				
			||||||
 | 
								if g.PreferredVersion.GroupVersion != "" {
 | 
				
			||||||
 | 
									gv, err := schema.ParseGroupVersion(g.PreferredVersion.GroupVersion)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return hostFactory.ClientSetForVersion(&gv)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								for i := 0; i < len(g.Versions); i++ {
 | 
				
			||||||
 | 
									if g.Versions[i].GroupVersion != "" {
 | 
				
			||||||
 | 
										gv, err := schema.ParseGroupVersion(g.Versions[i].GroupVersion)
 | 
				
			||||||
 | 
										if err != nil {
 | 
				
			||||||
 | 
											return nil, err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										return hostFactory.ClientSetForVersion(&gv)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, &NoRBACAPIError{rbacAPINotAvailable}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user