mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 12:15:52 +00:00
Merge pull request #42683 from perotinus/annotations
Automatic merge from submit-queue [Federation][kubefed] Annotate all Federation API objects with the federation name and (if applicable) the cluster name. Address part of #42324. ```release-note Adds annotations to all Federation objects created by kubefed. ```
This commit is contained in:
commit
3c7616eb19
@ -10,6 +10,7 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"annotations.go",
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
|
28
federation/apis/federation/annotations.go
Normal file
28
federation/apis/federation/annotations.go
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federation
|
||||
|
||||
// FederationNameAnnotation is the annotation which holds the name of
|
||||
// the federation that an object is associated with. It must be
|
||||
// applied to all API objects associated with that federation.
|
||||
const FederationNameAnnotation = "federation.alpha.kubernetes.io/federation-name"
|
||||
|
||||
// ClusterNameAnnotation is the annotation which holds the name of
|
||||
// the cluster that an object is associated with. If the object is
|
||||
// not associated with any cluster, then this annotation is not
|
||||
// required.
|
||||
const ClusterNameAnnotation = "federation.alpha.kubernetes.io/cluster-name"
|
@ -14,6 +14,7 @@ go_library(
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||
"//federation/apis/federation:go_default_library",
|
||||
"//federation/pkg/kubefed/util:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
@ -42,6 +43,7 @@ go_test(
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//federation/apis/federation:go_default_library",
|
||||
"//federation/pkg/kubefed/testing:go_default_library",
|
||||
"//federation/pkg/kubefed/util:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
|
@ -40,6 +40,7 @@ import (
|
||||
certutil "k8s.io/client-go/util/cert"
|
||||
triple "k8s.io/client-go/util/cert/triple"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
"k8s.io/kubernetes/federation/apis/federation"
|
||||
"k8s.io/kubernetes/federation/pkg/kubefed/util"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
@ -276,13 +277,13 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
|
||||
}
|
||||
|
||||
// 1. Create a namespace for federation system components
|
||||
_, err = createNamespace(hostClientset, i.commonOptions.FederationSystemNamespace, i.options.dryRun)
|
||||
_, err = createNamespace(hostClientset, i.commonOptions.Name, i.commonOptions.FederationSystemNamespace, i.options.dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. Expose a network endpoint for the federation API server
|
||||
svc, ips, hostnames, err := createService(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.options.apiServerAdvertiseAddress, i.options.apiServerServiceType, i.options.dryRun)
|
||||
svc, ips, hostnames, err := createService(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.apiServerAdvertiseAddress, i.options.apiServerServiceType, i.options.dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -294,7 +295,7 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
|
||||
}
|
||||
|
||||
// 3b. Create the secret containing the credentials.
|
||||
_, err = createAPIServerCredentialsSecret(hostClientset, i.commonOptions.FederationSystemNamespace, serverCredName, credentials, i.options.dryRun)
|
||||
_, err = createAPIServerCredentialsSecret(hostClientset, i.commonOptions.FederationSystemNamespace, serverCredName, i.commonOptions.Name, credentials, i.options.dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -310,7 +311,7 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
|
||||
// stores its data.
|
||||
var pvc *api.PersistentVolumeClaim
|
||||
if i.options.etcdPersistentStorage {
|
||||
pvc, err = createPVC(hostClientset, i.commonOptions.FederationSystemNamespace, svc.Name, i.options.etcdPVCapacity, i.options.dryRun)
|
||||
pvc, err = createPVC(hostClientset, i.commonOptions.FederationSystemNamespace, svc.Name, i.commonOptions.Name, i.options.etcdPVCapacity, i.options.dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -325,7 +326,7 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
|
||||
}
|
||||
|
||||
// 6. Create federation API server
|
||||
_, err = createAPIServer(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.options.image, advertiseAddress, serverCredName, i.options.apiServerEnableHTTPBasicAuth, i.options.apiServerEnableTokenAuth, i.options.apiServerOverrides, pvc, i.options.dryRun)
|
||||
_, err = createAPIServer(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.image, advertiseAddress, serverCredName, i.options.apiServerEnableHTTPBasicAuth, i.options.apiServerEnableTokenAuth, i.options.apiServerOverrides, pvc, i.options.dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -339,21 +340,21 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
|
||||
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)
|
||||
sa, err = createControllerManagerSA(rbacVersionedClientset, i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, i.options.dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 7b. Create RBAC role and role binding for federation controller
|
||||
// manager service account.
|
||||
_, _, err = createRoleBindings(rbacVersionedClientset, i.commonOptions.FederationSystemNamespace, sa.Name, i.options.dryRun)
|
||||
_, _, err = createRoleBindings(rbacVersionedClientset, i.commonOptions.FederationSystemNamespace, sa.Name, i.commonOptions.Name, i.options.dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 7c. Create a dns-provider config secret
|
||||
dnsProviderSecret, err := createDNSProviderConfigSecret(hostClientset, i.commonOptions.FederationSystemNamespace, dnsProviderSecretName, dnsProviderConfigBytes, i.options.dryRun)
|
||||
dnsProviderSecret, err := createDNSProviderConfigSecret(hostClientset, i.commonOptions.FederationSystemNamespace, dnsProviderSecretName, i.commonOptions.Name, dnsProviderConfigBytes, i.options.dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -400,10 +401,11 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func createNamespace(clientset client.Interface, namespace string, dryRun bool) (*api.Namespace, error) {
|
||||
func createNamespace(clientset client.Interface, federationName, namespace string, dryRun bool) (*api.Namespace, error) {
|
||||
ns := &api.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: namespace,
|
||||
Name: namespace,
|
||||
Annotations: map[string]string{federation.FederationNameAnnotation: federationName},
|
||||
},
|
||||
}
|
||||
|
||||
@ -414,12 +416,13 @@ func createNamespace(clientset client.Interface, namespace string, dryRun bool)
|
||||
return clientset.Core().Namespaces().Create(ns)
|
||||
}
|
||||
|
||||
func createService(clientset client.Interface, namespace, svcName, apiserverAdvertiseAddress string, apiserverServiceType v1.ServiceType, dryRun bool) (*api.Service, []string, []string, error) {
|
||||
func createService(clientset client.Interface, namespace, svcName, federationName, apiserverAdvertiseAddress string, apiserverServiceType v1.ServiceType, dryRun bool) (*api.Service, []string, []string, error) {
|
||||
svc := &api.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: svcName,
|
||||
Namespace: namespace,
|
||||
Labels: componentLabel,
|
||||
Name: svcName,
|
||||
Namespace: namespace,
|
||||
Labels: componentLabel,
|
||||
Annotations: map[string]string{federation.FederationNameAnnotation: federationName},
|
||||
},
|
||||
Spec: api.ServiceSpec{
|
||||
Type: api.ServiceType(apiserverServiceType),
|
||||
@ -563,7 +566,7 @@ func genCerts(svcNamespace, name, svcName, localDNSZoneName string, ips, hostnam
|
||||
}, nil
|
||||
}
|
||||
|
||||
func createAPIServerCredentialsSecret(clientset client.Interface, namespace, credentialsName string, credentials *credentials, dryRun bool) (*api.Secret, error) {
|
||||
func createAPIServerCredentialsSecret(clientset client.Interface, namespace, credentialsName, federationName string, credentials *credentials, dryRun bool) (*api.Secret, error) {
|
||||
// Build the secret object with API server credentials.
|
||||
data := map[string][]byte{
|
||||
"ca.crt": certutil.EncodeCertPEM(credentials.certEntKeyPairs.ca.Cert),
|
||||
@ -579,8 +582,9 @@ func createAPIServerCredentialsSecret(clientset client.Interface, namespace, cre
|
||||
|
||||
secret := &api.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: credentialsName,
|
||||
Namespace: namespace,
|
||||
Name: credentialsName,
|
||||
Namespace: namespace,
|
||||
Annotations: map[string]string{federation.FederationNameAnnotation: federationName},
|
||||
},
|
||||
Data: data,
|
||||
}
|
||||
@ -602,10 +606,10 @@ func createControllerManagerKubeconfigSecret(clientset client.Interface, namespa
|
||||
certutil.EncodeCertPEM(entKeyPairs.controllerManager.Cert),
|
||||
)
|
||||
|
||||
return util.CreateKubeconfigSecret(clientset, config, namespace, kubeconfigName, dryRun)
|
||||
return util.CreateKubeconfigSecret(clientset, config, namespace, kubeconfigName, name, "", dryRun)
|
||||
}
|
||||
|
||||
func createPVC(clientset client.Interface, namespace, svcName, etcdPVCapacity string, dryRun bool) (*api.PersistentVolumeClaim, error) {
|
||||
func createPVC(clientset client.Interface, namespace, svcName, federationName, etcdPVCapacity string, dryRun bool) (*api.PersistentVolumeClaim, error) {
|
||||
capacity, err := resource.ParseQuantity(etcdPVCapacity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -618,7 +622,7 @@ func createPVC(clientset client.Interface, namespace, svcName, etcdPVCapacity st
|
||||
Labels: componentLabel,
|
||||
Annotations: map[string]string{
|
||||
"volume.alpha.kubernetes.io/storage-class": "yes",
|
||||
},
|
||||
federation.FederationNameAnnotation: federationName},
|
||||
},
|
||||
Spec: api.PersistentVolumeClaimSpec{
|
||||
AccessModes: []api.PersistentVolumeAccessMode{
|
||||
@ -639,7 +643,7 @@ func createPVC(clientset client.Interface, namespace, svcName, etcdPVCapacity st
|
||||
return clientset.Core().PersistentVolumeClaims(namespace).Create(pvc)
|
||||
}
|
||||
|
||||
func createAPIServer(clientset client.Interface, namespace, name, image, advertiseAddress, credentialsName string, hasHTTPBasicAuthFile, hasTokenAuthFile bool, argOverrides map[string]string, pvc *api.PersistentVolumeClaim, dryRun bool) (*extensions.Deployment, error) {
|
||||
func createAPIServer(clientset client.Interface, namespace, name, federationName, image, advertiseAddress, credentialsName string, hasHTTPBasicAuthFile, hasTokenAuthFile bool, argOverrides map[string]string, pvc *api.PersistentVolumeClaim, dryRun bool) (*extensions.Deployment, error) {
|
||||
command := []string{
|
||||
"/hyperkube",
|
||||
"federation-apiserver",
|
||||
@ -669,16 +673,18 @@ func createAPIServer(clientset client.Interface, namespace, name, image, adverti
|
||||
|
||||
dep := &extensions.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
Labels: componentLabel,
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
Labels: componentLabel,
|
||||
Annotations: map[string]string{federation.FederationNameAnnotation: federationName},
|
||||
},
|
||||
Spec: extensions.DeploymentSpec{
|
||||
Replicas: 1,
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Labels: apiserverPodLabels,
|
||||
Name: name,
|
||||
Labels: apiserverPodLabels,
|
||||
Annotations: map[string]string{federation.FederationNameAnnotation: federationName},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
@ -756,15 +762,17 @@ func createAPIServer(clientset client.Interface, namespace, name, image, adverti
|
||||
return dep, nil
|
||||
}
|
||||
|
||||
return clientset.Extensions().Deployments(namespace).Create(dep)
|
||||
createdDep, err := clientset.Extensions().Deployments(namespace).Create(dep)
|
||||
return createdDep, err
|
||||
}
|
||||
|
||||
func createControllerManagerSA(clientset client.Interface, namespace string, dryRun bool) (*api.ServiceAccount, error) {
|
||||
func createControllerManagerSA(clientset client.Interface, namespace, federationName string, dryRun bool) (*api.ServiceAccount, error) {
|
||||
sa := &api.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: ControllerManagerSA,
|
||||
Namespace: namespace,
|
||||
Labels: componentLabel,
|
||||
Name: ControllerManagerSA,
|
||||
Namespace: namespace,
|
||||
Labels: componentLabel,
|
||||
Annotations: map[string]string{federation.FederationNameAnnotation: federationName},
|
||||
},
|
||||
}
|
||||
if dryRun {
|
||||
@ -773,15 +781,16 @@ func createControllerManagerSA(clientset client.Interface, namespace string, dry
|
||||
return clientset.Core().ServiceAccounts(namespace).Create(sa)
|
||||
}
|
||||
|
||||
func createRoleBindings(clientset client.Interface, namespace, saName string, dryRun bool) (*rbac.Role, *rbac.RoleBinding, error) {
|
||||
func createRoleBindings(clientset client.Interface, namespace, saName, federationName string, dryRun bool) (*rbac.Role, *rbac.RoleBinding, error) {
|
||||
roleName := "federation-system:federation-controller-manager"
|
||||
role := &rbac.Role{
|
||||
// a role to use for bootstrapping the federation-controller-manager so it can access
|
||||
// secrets in the host cluster to access other clusters.
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: roleName,
|
||||
Namespace: namespace,
|
||||
Labels: componentLabel,
|
||||
Name: roleName,
|
||||
Namespace: namespace,
|
||||
Labels: componentLabel,
|
||||
Annotations: map[string]string{federation.FederationNameAnnotation: federationName},
|
||||
},
|
||||
Rules: []rbac.PolicyRule{
|
||||
rbac.NewRule("get", "list", "watch").Groups(legacyAPIGroup).Resources("secrets").RuleOrDie(),
|
||||
@ -793,6 +802,7 @@ func createRoleBindings(clientset client.Interface, namespace, saName string, dr
|
||||
return nil, nil, err
|
||||
}
|
||||
rolebinding.Labels = componentLabel
|
||||
rolebinding.Annotations = map[string]string{federation.FederationNameAnnotation: federationName}
|
||||
|
||||
if dryRun {
|
||||
return role, &rolebinding, nil
|
||||
@ -839,15 +849,17 @@ func createControllerManager(clientset client.Interface, namespace, name, svcNam
|
||||
// https://github.com/kubernetes/dns/blob/master/pkg/dns/federation/federation.go
|
||||
// TODO v2: Until kube-dns can handle trailing periods we strip them all.
|
||||
// See https://github.com/kubernetes/dns/issues/67
|
||||
util.FedDomainMapKey: fmt.Sprintf("%s=%s", name, strings.TrimRight(dnsZoneName, ".")),
|
||||
util.FedDomainMapKey: fmt.Sprintf("%s=%s", name, strings.TrimRight(dnsZoneName, ".")),
|
||||
federation.FederationNameAnnotation: name,
|
||||
},
|
||||
},
|
||||
Spec: extensions.DeploymentSpec{
|
||||
Replicas: 1,
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: cmName,
|
||||
Labels: controllerManagerPodLabels,
|
||||
Name: cmName,
|
||||
Labels: controllerManagerPodLabels,
|
||||
Annotations: map[string]string{federation.FederationNameAnnotation: name},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
@ -1049,15 +1061,16 @@ func updateKubeconfig(config util.AdminConfig, name, endpoint, kubeConfigPath st
|
||||
return nil
|
||||
}
|
||||
|
||||
func createDNSProviderConfigSecret(clientset client.Interface, namespace, name string, dnsProviderConfigBytes []byte, dryRun bool) (*api.Secret, error) {
|
||||
func createDNSProviderConfigSecret(clientset client.Interface, namespace, name, federationName string, dnsProviderConfigBytes []byte, dryRun bool) (*api.Secret, error) {
|
||||
if dnsProviderConfigBytes == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
secretSpec := &api.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
Annotations: map[string]string{federation.FederationNameAnnotation: federationName},
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
name: dnsProviderConfigBytes,
|
||||
|
@ -42,6 +42,7 @@ import (
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/rest/fake"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/kubernetes/federation/apis/federation"
|
||||
kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing"
|
||||
"k8s.io/kubernetes/federation/pkg/kubefed/util"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
@ -619,6 +620,9 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: namespaceName,
|
||||
Annotations: map[string]string{
|
||||
federation.FederationNameAnnotation: federationName,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -631,6 +635,9 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
Namespace: namespaceName,
|
||||
Name: svcName,
|
||||
Labels: componentLabel,
|
||||
Annotations: map[string]string{
|
||||
federation.FederationNameAnnotation: federationName,
|
||||
},
|
||||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
Type: apiserverServiceType,
|
||||
@ -664,6 +671,9 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: credSecretName,
|
||||
Namespace: namespaceName,
|
||||
Annotations: map[string]string{
|
||||
federation.FederationNameAnnotation: federationName,
|
||||
},
|
||||
},
|
||||
Data: nil,
|
||||
}
|
||||
@ -676,6 +686,9 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: cmKubeconfigSecretName,
|
||||
Namespace: namespaceName,
|
||||
Annotations: map[string]string{
|
||||
federation.FederationNameAnnotation: federationName,
|
||||
},
|
||||
},
|
||||
Data: nil,
|
||||
}
|
||||
@ -688,6 +701,9 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: dnsProviderSecretName,
|
||||
Namespace: namespaceName,
|
||||
Annotations: map[string]string{
|
||||
federation.FederationNameAnnotation: federationName,
|
||||
},
|
||||
},
|
||||
Data: nil,
|
||||
}
|
||||
@ -703,6 +719,7 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
Labels: componentLabel,
|
||||
Annotations: map[string]string{
|
||||
"volume.alpha.kubernetes.io/storage-class": "yes",
|
||||
federation.FederationNameAnnotation: federationName,
|
||||
},
|
||||
},
|
||||
Spec: v1.PersistentVolumeClaimSpec{
|
||||
@ -726,6 +743,9 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
Name: "federation-controller-manager",
|
||||
Namespace: namespaceName,
|
||||
Labels: componentLabel,
|
||||
Annotations: map[string]string{
|
||||
federation.FederationNameAnnotation: federationName,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -738,6 +758,9 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
Name: "federation-system:federation-controller-manager",
|
||||
Namespace: namespaceName,
|
||||
Labels: componentLabel,
|
||||
Annotations: map[string]string{
|
||||
federation.FederationNameAnnotation: federationName,
|
||||
},
|
||||
},
|
||||
Rules: []rbacv1beta1.PolicyRule{
|
||||
{
|
||||
@ -757,6 +780,9 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
Name: "federation-system:federation-controller-manager",
|
||||
Namespace: namespaceName,
|
||||
Labels: componentLabel,
|
||||
Annotations: map[string]string{
|
||||
federation.FederationNameAnnotation: federationName,
|
||||
},
|
||||
},
|
||||
Subjects: []rbacv1beta1.Subject{
|
||||
{
|
||||
@ -838,17 +864,19 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
APIVersion: testapi.Extensions.GroupVersion().String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: svcName,
|
||||
Namespace: namespaceName,
|
||||
Labels: componentLabel,
|
||||
Name: svcName,
|
||||
Namespace: namespaceName,
|
||||
Labels: componentLabel,
|
||||
Annotations: map[string]string{federation.FederationNameAnnotation: federationName},
|
||||
},
|
||||
Spec: v1beta1.DeploymentSpec{
|
||||
Replicas: &replicas,
|
||||
Selector: nil,
|
||||
Template: v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: svcName,
|
||||
Labels: apiserverPodLabels,
|
||||
Name: svcName,
|
||||
Labels: apiserverPodLabels,
|
||||
Annotations: map[string]string{federation.FederationNameAnnotation: federationName},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
@ -954,7 +982,8 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
Namespace: namespaceName,
|
||||
Labels: componentLabel,
|
||||
Annotations: map[string]string{
|
||||
util.FedDomainMapKey: fmt.Sprintf("%s=%s", federationName, strings.TrimRight(dnsZoneName, ".")),
|
||||
util.FedDomainMapKey: fmt.Sprintf("%s=%s", federationName, strings.TrimRight(dnsZoneName, ".")),
|
||||
federation.FederationNameAnnotation: federationName,
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.DeploymentSpec{
|
||||
@ -962,8 +991,9 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
Selector: nil,
|
||||
Template: v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: cmName,
|
||||
Labels: controllerManagerPodLabels,
|
||||
Name: cmName,
|
||||
Labels: controllerManagerPodLabels,
|
||||
Annotations: map[string]string{federation.FederationNameAnnotation: federationName},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
@ -1196,6 +1226,7 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
||||
case cmName:
|
||||
want = *cm
|
||||
}
|
||||
//want = *cm
|
||||
if !apiequality.Semantic.DeepEqual(got, want) {
|
||||
return nil, fmt.Errorf("unexpected deployment object\n\tDiff: %s", diff.ObjectGoPrintDiff(got, want))
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/kubernetes/federation/apis/federation"
|
||||
"k8s.io/kubernetes/federation/pkg/kubefed/util"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
@ -150,6 +151,12 @@ func (j *joinFederation) Run(f cmdutil.Factory, cmdOut io.Writer, config util.Ad
|
||||
return err
|
||||
}
|
||||
|
||||
federationName, err := getFederationName(hostClientset, j.commonOptions.FederationSystemNamespace)
|
||||
if err != nil {
|
||||
glog.V(2).Infof("Failed to get the federation name: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// We are not using the `kubectl create secret` machinery through
|
||||
// `RunCreateSubcommand` as we do to the cluster resource below
|
||||
// because we have a bunch of requirements that the machinery does
|
||||
@ -165,7 +172,7 @@ func (j *joinFederation) Run(f cmdutil.Factory, cmdOut io.Writer, config util.Ad
|
||||
// don't have to print the created secret in the default case.
|
||||
// Having said that, secret generation machinery could be altered to
|
||||
// suit our needs, but it is far less invasive and readable this way.
|
||||
_, err = createSecret(hostClientset, clientConfig, j.commonOptions.FederationSystemNamespace, j.options.clusterContext, j.options.secretName, j.options.dryRun)
|
||||
_, err = createSecret(hostClientset, clientConfig, j.commonOptions.FederationSystemNamespace, federationName, j.commonOptions.Name, j.options.clusterContext, j.options.secretName, j.options.dryRun)
|
||||
if err != nil {
|
||||
glog.V(2).Infof("Failed creating the cluster credentials secret: %v", err)
|
||||
return err
|
||||
@ -185,7 +192,7 @@ func (j *joinFederation) Run(f cmdutil.Factory, cmdOut io.Writer, config util.Ad
|
||||
// We further need to create a configmap named kube-config in the
|
||||
// just registered cluster which will be consumed by the kube-dns
|
||||
// of this cluster.
|
||||
_, err = createConfigMap(hostClientset, config, j.commonOptions.FederationSystemNamespace, j.options.clusterContext, j.commonOptions.Kubeconfig, j.options.dryRun)
|
||||
_, err = createConfigMap(hostClientset, config, j.commonOptions.FederationSystemNamespace, federationName, j.commonOptions.Name, j.options.clusterContext, j.commonOptions.Kubeconfig, j.options.dryRun)
|
||||
if err != nil {
|
||||
glog.V(2).Infof("Failed creating the config map in cluster: %v", err)
|
||||
return err
|
||||
@ -213,7 +220,7 @@ func minifyConfig(clientConfig *clientcmdapi.Config, context string) (*clientcmd
|
||||
|
||||
// createSecret extracts the kubeconfig for a given cluster and populates
|
||||
// a secret with that kubeconfig.
|
||||
func createSecret(clientset internalclientset.Interface, clientConfig *clientcmdapi.Config, namespace, contextName, secretName string, dryRun bool) (runtime.Object, error) {
|
||||
func createSecret(clientset internalclientset.Interface, clientConfig *clientcmdapi.Config, namespace, federationName, clusterName, contextName, secretName string, dryRun bool) (runtime.Object, error) {
|
||||
// Minify the kubeconfig to ensure that there is only information
|
||||
// relevant to the cluster we are registering.
|
||||
newClientConfig, err := minifyConfig(clientConfig, contextName)
|
||||
@ -230,13 +237,13 @@ func createSecret(clientset internalclientset.Interface, clientConfig *clientcmd
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return util.CreateKubeconfigSecret(clientset, newClientConfig, namespace, secretName, dryRun)
|
||||
return util.CreateKubeconfigSecret(clientset, newClientConfig, namespace, secretName, federationName, clusterName, dryRun)
|
||||
}
|
||||
|
||||
// createConfigMap creates a configmap with name kube-dns in the joining cluster
|
||||
// which stores the information about this federation zone name.
|
||||
// If the configmap with this name already exists, its updated with this information.
|
||||
func createConfigMap(hostClientSet internalclientset.Interface, config util.AdminConfig, fedSystemNamespace, targetClusterContext, kubeconfigPath string, dryRun bool) (*api.ConfigMap, error) {
|
||||
func createConfigMap(hostClientSet internalclientset.Interface, config util.AdminConfig, fedSystemNamespace, federationName, targetClusterName, targetClusterContext, kubeconfigPath string, dryRun bool) (*api.ConfigMap, error) {
|
||||
cmDep, err := getCMDeployment(hostClientSet, fedSystemNamespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -258,6 +265,10 @@ func createConfigMap(hostClientSet internalclientset.Interface, config util.Admi
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: util.KubeDnsConfigmapName,
|
||||
Namespace: metav1.NamespaceSystem,
|
||||
Annotations: map[string]string{
|
||||
federation.FederationNameAnnotation: federationName,
|
||||
federation.ClusterNameAnnotation: targetClusterName,
|
||||
},
|
||||
},
|
||||
Data: map[string]string{
|
||||
util.FedDomainMapKey: domainMap,
|
||||
@ -366,3 +377,19 @@ func appendConfigMapString(existing string, toAppend string) string {
|
||||
}
|
||||
return fmt.Sprintf("%s,%s", existing, toAppend)
|
||||
}
|
||||
|
||||
// getFederationName gets the federation name from the appropriate annotation on the
|
||||
// control manager deployment.
|
||||
func getFederationName(hostClientSet internalclientset.Interface, fedNamespace string) (string, error) {
|
||||
d, err := getCMDeployment(hostClientSet, fedNamespace)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
name, ok := d.Annotations[federation.FederationNameAnnotation]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("Federation control manager does not have federation name annotation. Please recreate the federation with a newer version of kubefed, or use an older version of kubefed to join this cluster.")
|
||||
}
|
||||
|
||||
return name, nil
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
"k8s.io/client-go/rest/fake"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/kubernetes/federation/apis/federation"
|
||||
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||
kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing"
|
||||
"k8s.io/kubernetes/federation/pkg/kubefed/util"
|
||||
@ -41,6 +42,11 @@ import (
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
)
|
||||
|
||||
// testFederationName is a name to use for the federation in tests. Since the federation
|
||||
// name is recovered from the federation itself, this constant is an appropriate
|
||||
// functional replica.
|
||||
const testFederationName = "test-federation"
|
||||
|
||||
func TestJoinFederation(t *testing.T) {
|
||||
cmdErrMsg := ""
|
||||
cmdutil.BehaviorOnFatal(func(str string, code int) {
|
||||
@ -253,6 +259,10 @@ func fakeJoinHostFactory(clusterName, clusterCtx, secretName, server, token stri
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: secretName,
|
||||
Namespace: util.DefaultFederationSystemNamespace,
|
||||
Annotations: map[string]string{
|
||||
federation.FederationNameAnnotation: testFederationName,
|
||||
federation.ClusterNameAnnotation: clusterName,
|
||||
},
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"kubeconfig": configBytes,
|
||||
@ -275,7 +285,8 @@ func fakeJoinHostFactory(clusterName, clusterCtx, secretName, server, token stri
|
||||
Name: cmName,
|
||||
Namespace: util.DefaultFederationSystemNamespace,
|
||||
Annotations: map[string]string{
|
||||
util.FedDomainMapKey: fmt.Sprintf("%s=%s", clusterCtx, "test-dns-zone"),
|
||||
util.FedDomainMapKey: fmt.Sprintf("%s=%s", clusterCtx, "test-dns-zone"),
|
||||
federation.FederationNameAnnotation: testFederationName,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -324,6 +335,10 @@ func fakeJoinTargetClusterFactory(clusterName, clusterCtx string) (cmdutil.Facto
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: util.KubeDnsConfigmapName,
|
||||
Namespace: metav1.NamespaceSystem,
|
||||
Annotations: map[string]string{
|
||||
federation.FederationNameAnnotation: testFederationName,
|
||||
federation.ClusterNameAnnotation: clusterName,
|
||||
},
|
||||
},
|
||||
Data: map[string]string{
|
||||
util.FedDomainMapKey: fmt.Sprintf("%s=%s", clusterCtx, "test-dns-zone"),
|
||||
|
@ -148,18 +148,26 @@ func (o *SubcommandOptions) SetName(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateKubeconfigSecret(clientset client.Interface, kubeconfig *clientcmdapi.Config, namespace, name string, dryRun bool) (*api.Secret, error) {
|
||||
func CreateKubeconfigSecret(clientset client.Interface, kubeconfig *clientcmdapi.Config, namespace, name, federationName, clusterName string, dryRun bool) (*api.Secret, error) {
|
||||
configBytes, err := clientcmd.Write(*kubeconfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
annotations := map[string]string{
|
||||
federationapi.FederationNameAnnotation: federationName,
|
||||
}
|
||||
|
||||
if clusterName != "" {
|
||||
annotations[federationapi.ClusterNameAnnotation] = clusterName
|
||||
}
|
||||
|
||||
// Build the secret object with the minified and flattened
|
||||
// kubeconfig content.
|
||||
secret := &api.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
Annotations: annotations,
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
KubeconfigSecretDataKey: configBytes,
|
||||
|
Loading…
Reference in New Issue
Block a user