// createSecret creates a secret containing TLS certificates for the given Ingress. // If a secret with the same name already exists in the namespace of the // Ingress, it's updated. func createSecret(kubeClient clientset.Interface, ing *extensions.Ingress) (host string, rootCA, privKey []byte, err error) { var k, c bytes.Buffer tls := ing.Spec.TLS[0] host = strings.Join(tls.Hosts, ",") framework.Logf("Generating RSA cert for host %v", host) if err = generateRSACerts(host, true, &k, &c); err != nil { return } cert := c.Bytes() key := k.Bytes() secret := &v1.Secret{ ObjectMeta: v1.ObjectMeta{ Name: tls.SecretName, }, Data: map[string][]byte{ v1.TLSCertKey: cert, v1.TLSPrivateKeyKey: key, }, } var s *v1.Secret if s, err = kubeClient.Core().Secrets(ing.Namespace).Get(tls.SecretName, metav1.GetOptions{}); err == nil { // TODO: Retry the update. We don't really expect anything to conflict though. framework.Logf("Updating secret %v in ns %v with hosts %v for ingress %v", secret.Name, secret.Namespace, host, ing.Name) s.Data = secret.Data _, err = kubeClient.Core().Secrets(ing.Namespace).Update(s) } else { framework.Logf("Creating secret %v in ns %v with hosts %v for ingress %v", secret.Name, secret.Namespace, host, ing.Name) _, err = kubeClient.Core().Secrets(ing.Namespace).Create(secret) } return host, cert, key, err }
func secretsEqual(a, b apiv1.Secret) bool { // Clear the SelfLink and ObjectMeta.Finalizers since they will be different // in resoure in federation control plane and resource in underlying cluster. a.SelfLink = "" b.SelfLink = "" a.ObjectMeta.Finalizers = []string{} b.ObjectMeta.Finalizers = []string{} return reflect.DeepEqual(a, b) }
func TestSecretController(t *testing.T) { cluster1 := mkCluster("cluster1", api_v1.ConditionTrue) cluster2 := mkCluster("cluster2", api_v1.ConditionTrue) fakeClient := &fake_federation_release_1_4.Clientset{} RegisterList("clusters", &fakeClient.Fake, &federation_api.ClusterList{Items: []federation_api.Cluster{*cluster1}}) RegisterList("secrets", &fakeClient.Fake, &api_v1.SecretList{Items: []api_v1.Secret{}}) secretWatch := RegisterWatch("secrets", &fakeClient.Fake) clusterWatch := RegisterWatch("clusters", &fakeClient.Fake) cluster1Client := &fake_kube_release_1_4.Clientset{} cluster1Watch := RegisterWatch("secrets", &cluster1Client.Fake) RegisterList("secrets", &cluster1Client.Fake, &api_v1.SecretList{Items: []api_v1.Secret{}}) cluster1CreateChan := RegisterCopyOnCreate("secrets", &cluster1Client.Fake, cluster1Watch) cluster1UpdateChan := RegisterCopyOnUpdate("secrets", &cluster1Client.Fake, cluster1Watch) cluster2Client := &fake_kube_release_1_4.Clientset{} cluster2Watch := RegisterWatch("secrets", &cluster2Client.Fake) RegisterList("secrets", &cluster2Client.Fake, &api_v1.SecretList{Items: []api_v1.Secret{}}) cluster2CreateChan := RegisterCopyOnCreate("secrets", &cluster2Client.Fake, cluster2Watch) secretController := NewSecretController(fakeClient) informer := toFederatedInformerForTestOnly(secretController.secretFederatedInformer) informer.SetClientFactory(func(cluster *federation_api.Cluster) (kube_release_1_4.Interface, error) { switch cluster.Name { case cluster1.Name: return cluster1Client, nil case cluster2.Name: return cluster2Client, nil default: return nil, fmt.Errorf("Unknown cluster") } }) secretController.clusterAvailableDelay = time.Second secretController.secretReviewDelay = 50 * time.Millisecond secretController.smallDelay = 20 * time.Millisecond secretController.updateTimeout = 5 * time.Second stop := make(chan struct{}) secretController.Run(stop) secret1 := api_v1.Secret{ ObjectMeta: api_v1.ObjectMeta{ Name: "test-secret", Namespace: "mynamespace", }, Data: map[string][]byte{ "A": []byte("ala ma kota"), "B": []byte("quick brown fox"), }, Type: api_v1.SecretTypeOpaque, } // Test add federated secret. secretWatch.Add(&secret1) createdSecret := GetSecretFromChan(cluster1CreateChan) assert.NotNil(t, createdSecret) assert.Equal(t, secret1.Namespace, createdSecret.Namespace) assert.Equal(t, secret1.Name, createdSecret.Name) assert.True(t, reflect.DeepEqual(&secret1, createdSecret)) // Test update federated secret. secret1.Annotations = map[string]string{ "A": "B", } secretWatch.Modify(&secret1) updatedSecret := GetSecretFromChan(cluster1UpdateChan) assert.NotNil(t, updatedSecret) assert.Equal(t, secret1.Name, updatedSecret.Name) assert.Equal(t, secret1.Namespace, updatedSecret.Namespace) assert.True(t, reflect.DeepEqual(&secret1, updatedSecret)) // Test add cluster clusterWatch.Add(cluster2) createdSecret2 := GetSecretFromChan(cluster2CreateChan) assert.NotNil(t, createdSecret2) assert.Equal(t, secret1.Name, createdSecret2.Name) assert.Equal(t, secret1.Namespace, createdSecret2.Namespace) assert.True(t, reflect.DeepEqual(&secret1, createdSecret2)) close(stop) }
func TestSecretController(t *testing.T) { cluster1 := NewCluster("cluster1", api_v1.ConditionTrue) cluster2 := NewCluster("cluster2", api_v1.ConditionTrue) fakeClient := &fake_fedclientset.Clientset{} RegisterFakeList("clusters", &fakeClient.Fake, &federation_api.ClusterList{Items: []federation_api.Cluster{*cluster1}}) RegisterFakeList("secrets", &fakeClient.Fake, &api_v1.SecretList{Items: []api_v1.Secret{}}) secretWatch := RegisterFakeWatch("secrets", &fakeClient.Fake) clusterWatch := RegisterFakeWatch("clusters", &fakeClient.Fake) cluster1Client := &fake_kubeclientset.Clientset{} cluster1Watch := RegisterFakeWatch("secrets", &cluster1Client.Fake) RegisterFakeList("secrets", &cluster1Client.Fake, &api_v1.SecretList{Items: []api_v1.Secret{}}) cluster1CreateChan := RegisterFakeCopyOnCreate("secrets", &cluster1Client.Fake, cluster1Watch) cluster1UpdateChan := RegisterFakeCopyOnUpdate("secrets", &cluster1Client.Fake, cluster1Watch) cluster2Client := &fake_kubeclientset.Clientset{} cluster2Watch := RegisterFakeWatch("secrets", &cluster2Client.Fake) RegisterFakeList("secrets", &cluster2Client.Fake, &api_v1.SecretList{Items: []api_v1.Secret{}}) cluster2CreateChan := RegisterFakeCopyOnCreate("secrets", &cluster2Client.Fake, cluster2Watch) secretController := NewSecretController(fakeClient) informer := ToFederatedInformerForTestOnly(secretController.secretFederatedInformer) informer.SetClientFactory(func(cluster *federation_api.Cluster) (kubeclientset.Interface, error) { switch cluster.Name { case cluster1.Name: return cluster1Client, nil case cluster2.Name: return cluster2Client, nil default: return nil, fmt.Errorf("Unknown cluster") } }) secretController.clusterAvailableDelay = time.Second secretController.secretReviewDelay = 50 * time.Millisecond secretController.smallDelay = 20 * time.Millisecond secretController.updateTimeout = 5 * time.Second stop := make(chan struct{}) secretController.Run(stop) secret1 := api_v1.Secret{ ObjectMeta: api_v1.ObjectMeta{ Name: "test-secret", Namespace: "ns", SelfLink: "/api/v1/namespaces/ns/secrets/test-secret", }, Data: map[string][]byte{ "A": []byte("ala ma kota"), "B": []byte("quick brown fox"), }, Type: api_v1.SecretTypeOpaque, } // Test add federated secret. secretWatch.Add(&secret1) createdSecret := GetSecretFromChan(cluster1CreateChan) assert.NotNil(t, createdSecret) assert.Equal(t, secret1.Namespace, createdSecret.Namespace) assert.Equal(t, secret1.Name, createdSecret.Name) assert.True(t, secretsEqual(secret1, *createdSecret)) // Wait for the secret to appear in the informer store err := WaitForStoreUpdate( secretController.secretFederatedInformer.GetTargetStore(), cluster1.Name, types.NamespacedName{Namespace: secret1.Namespace, Name: secret1.Name}.String(), wait.ForeverTestTimeout) assert.Nil(t, err, "secret should have appeared in the informer store") // Test update federated secret. secret1.Annotations = map[string]string{ "A": "B", } secretWatch.Modify(&secret1) updatedSecret := GetSecretFromChan(cluster1UpdateChan) assert.NotNil(t, updatedSecret) assert.Equal(t, secret1.Name, updatedSecret.Name) assert.Equal(t, secret1.Namespace, updatedSecret.Namespace) assert.True(t, secretsEqual(secret1, *updatedSecret)) // Test update federated secret. secret1.Data = map[string][]byte{ "config": []byte("myconfigurationfile"), } secretWatch.Modify(&secret1) updatedSecret2 := GetSecretFromChan(cluster1UpdateChan) assert.NotNil(t, updatedSecret) assert.Equal(t, secret1.Name, updatedSecret.Name) assert.Equal(t, secret1.Namespace, updatedSecret.Namespace) assert.True(t, secretsEqual(secret1, *updatedSecret2)) // Test add cluster clusterWatch.Add(cluster2) createdSecret2 := GetSecretFromChan(cluster2CreateChan) assert.NotNil(t, createdSecret2) assert.Equal(t, secret1.Name, createdSecret2.Name) assert.Equal(t, secret1.Namespace, createdSecret2.Namespace) assert.True(t, secretsEqual(secret1, *createdSecret2)) close(stop) }
func secretsEqual(a, b api_v1.Secret) bool { a.SelfLink = "" b.SelfLink = "" return reflect.DeepEqual(a, b) }
func TestSecretController(t *testing.T) { cluster1 := NewCluster("cluster1", apiv1.ConditionTrue) cluster2 := NewCluster("cluster2", apiv1.ConditionTrue) fakeClient := &fakefedclientset.Clientset{} RegisterFakeList("clusters", &fakeClient.Fake, &federationapi.ClusterList{Items: []federationapi.Cluster{*cluster1}}) RegisterFakeList("secrets", &fakeClient.Fake, &apiv1.SecretList{Items: []apiv1.Secret{}}) secretWatch := RegisterFakeWatch("secrets", &fakeClient.Fake) secretUpdateChan := RegisterFakeCopyOnUpdate("secrets", &fakeClient.Fake, secretWatch) clusterWatch := RegisterFakeWatch("clusters", &fakeClient.Fake) cluster1Client := &fakekubeclientset.Clientset{} cluster1Watch := RegisterFakeWatch("secrets", &cluster1Client.Fake) RegisterFakeList("secrets", &cluster1Client.Fake, &apiv1.SecretList{Items: []apiv1.Secret{}}) cluster1CreateChan := RegisterFakeCopyOnCreate("secrets", &cluster1Client.Fake, cluster1Watch) cluster1UpdateChan := RegisterFakeCopyOnUpdate("secrets", &cluster1Client.Fake, cluster1Watch) cluster2Client := &fakekubeclientset.Clientset{} cluster2Watch := RegisterFakeWatch("secrets", &cluster2Client.Fake) RegisterFakeList("secrets", &cluster2Client.Fake, &apiv1.SecretList{Items: []apiv1.Secret{}}) cluster2CreateChan := RegisterFakeCopyOnCreate("secrets", &cluster2Client.Fake, cluster2Watch) secretController := NewSecretController(fakeClient) informerClientFactory := func(cluster *federationapi.Cluster) (kubeclientset.Interface, error) { switch cluster.Name { case cluster1.Name: return cluster1Client, nil case cluster2.Name: return cluster2Client, nil default: return nil, fmt.Errorf("Unknown cluster") } } setClientFactory(secretController.secretFederatedInformer, informerClientFactory) secretController.clusterAvailableDelay = time.Second secretController.secretReviewDelay = 50 * time.Millisecond secretController.smallDelay = 20 * time.Millisecond secretController.updateTimeout = 5 * time.Second stop := make(chan struct{}) secretController.Run(stop) secret1 := apiv1.Secret{ ObjectMeta: apiv1.ObjectMeta{ Name: "test-secret", Namespace: "ns", SelfLink: "/api/v1/namespaces/ns/secrets/test-secret", }, Data: map[string][]byte{ "A": []byte("ala ma kota"), "B": []byte("quick brown fox"), }, Type: apiv1.SecretTypeOpaque, } // Test add federated secret. secretWatch.Add(&secret1) // There should be 2 updates to add both the finalizers. updatedSecret := GetSecretFromChan(secretUpdateChan) assert.True(t, secretController.hasFinalizerFunc(updatedSecret, deletionhelper.FinalizerDeleteFromUnderlyingClusters)) updatedSecret = GetSecretFromChan(secretUpdateChan) assert.True(t, secretController.hasFinalizerFunc(updatedSecret, apiv1.FinalizerOrphan)) secret1 = *updatedSecret // Verify that the secret is created in underlying cluster1. createdSecret := GetSecretFromChan(cluster1CreateChan) assert.NotNil(t, createdSecret) assert.Equal(t, secret1.Namespace, createdSecret.Namespace) assert.Equal(t, secret1.Name, createdSecret.Name) assert.True(t, secretsEqual(secret1, *createdSecret), fmt.Sprintf("expected: %v, actual: %v", secret1, *createdSecret)) // Wait for the secret to appear in the informer store err := WaitForStoreUpdate( secretController.secretFederatedInformer.GetTargetStore(), cluster1.Name, types.NamespacedName{Namespace: secret1.Namespace, Name: secret1.Name}.String(), wait.ForeverTestTimeout) assert.Nil(t, err, "secret should have appeared in the informer store") checkAll := func(expected apiv1.Secret) CheckingFunction { return func(obj runtime.Object) error { glog.V(4).Infof("Checking %v", obj) s := obj.(*apiv1.Secret) if err := CompareObjectMeta(expected.ObjectMeta, s.ObjectMeta); err != nil { return err } if !reflect.DeepEqual(expected.Data, s.Data) { return fmt.Errorf("Data is different expected:%v actual:%v", expected.Data, s.Data) } if expected.Type != s.Type { return fmt.Errorf("Type is different expected:%v actual:%v", expected.Type, s.Type) } return nil } } // Test update federated secret. secret1.Annotations = map[string]string{ "A": "B", } secretWatch.Modify(&secret1) err = CheckObjectFromChan(cluster1UpdateChan, checkAll(secret1)) assert.NoError(t, err) // Wait for the secret to be updated in the informer store. err = WaitForSecretStoreUpdate( secretController.secretFederatedInformer.GetTargetStore(), cluster1.Name, types.NamespacedName{Namespace: secret1.Namespace, Name: secret1.Name}.String(), &secret1, wait.ForeverTestTimeout) assert.NoError(t, err, "secret should have been updated in the informer store") // Test update federated secret. secret1.Data = map[string][]byte{ "config": []byte("myconfigurationfile"), } secretWatch.Modify(&secret1) err = CheckObjectFromChan(cluster1UpdateChan, checkAll(secret1)) assert.NoError(t, err) // Test add cluster clusterWatch.Add(cluster2) createdSecret2 := GetSecretFromChan(cluster2CreateChan) assert.NotNil(t, createdSecret2) assert.Equal(t, secret1.Name, createdSecret2.Name) assert.Equal(t, secret1.Namespace, createdSecret2.Namespace) assert.True(t, secretsEqual(secret1, *createdSecret2), fmt.Sprintf("expected: %v, actual: %v", secret1, *createdSecret2)) close(stop) }