package integration import ( "reflect" "testing" "time" kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/watch" testutil "github.com/openshift/origin/test/util" testserver "github.com/openshift/origin/test/util/server" "github.com/openshift/origin/pkg/service/controller/servingcert" ) func TestServiceServingCertSigner(t *testing.T) { ns := "service-serving-cert-signer" testutil.RequireEtcd(t) defer testutil.DumpEtcdOnFailure(t) _, clusterAdminKubeConfig, err := testserver.StartTestMaster() if err != nil { t.Fatal(err) } clusterAdminConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig) if err != nil { t.Fatal(err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Fatal(err) } clusterAdminKubeClientset, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig) if err != nil { t.Fatal(err) } if _, err := testserver.CreateNewProject(clusterAdminClient, *clusterAdminConfig, "service-serving-cert-signer", "deads"); err != nil { t.Fatal(err) } service := &kapi.Service{ ObjectMeta: kapi.ObjectMeta{ Name: "my-svc", Annotations: map[string]string{ servingcert.ServingCertSecretAnnotation: "my-secret", }, }, Spec: kapi.ServiceSpec{ Ports: []kapi.ServicePort{ {Port: 80}, }, }, } actualService, err := clusterAdminKubeClientset.Services(ns).Create(service) if err != nil { t.Fatal(err) } var actualFirstSecret *kapi.Secret secretWatcher1, err := clusterAdminKubeClientset.Secrets(ns).Watch(kapi.ListOptions{ResourceVersion: actualService.ResourceVersion}) if err != nil { t.Fatal(err) } _, err = watch.Until(30*time.Second, secretWatcher1, func(event watch.Event) (bool, error) { if event.Type != watch.Added { return false, nil } secret := event.Object.(*kapi.Secret) if secret.Name == "my-secret" { actualFirstSecret = secret return true, nil } return false, nil }) if err != nil { t.Fatal(err) } secretWatcher1.Stop() // now check to make sure that regeneration works. First, remove the annotation entirely, this simulates // the "old data" case where the expiry didn't exist delete(actualFirstSecret.Annotations, servingcert.ServingCertExpiryAnnotation) actualSecondSecret, err := clusterAdminKubeClientset.Secrets(ns).Update(actualFirstSecret) if err != nil { t.Fatal(err) } var actualThirdSecret *kapi.Secret secretWatcher2, err := clusterAdminKubeClientset.Secrets(ns).Watch(kapi.ListOptions{ResourceVersion: actualSecondSecret.ResourceVersion}) if err != nil { t.Fatal(err) } _, err = watch.Until(30*time.Second, secretWatcher2, func(event watch.Event) (bool, error) { if event.Type != watch.Modified { return false, nil } secret := event.Object.(*kapi.Secret) if secret.Name == "my-secret" { actualThirdSecret = secret return true, nil } return false, nil }) if err != nil { t.Fatal(err) } secretWatcher2.Stop() if _, ok := actualThirdSecret.Annotations[servingcert.ServingCertExpiryAnnotation]; !ok { t.Fatalf("missing annotation: %#v", actualThirdSecret) } if reflect.DeepEqual(actualThirdSecret.Data, actualSecondSecret.Data) { t.Fatalf("didn't update secret content: %#v", actualThirdSecret) } // now change the annotation to indicate that we're about to expire. The controller should regenerate. actualThirdSecret.Annotations[servingcert.ServingCertExpiryAnnotation] = time.Now().Add(10 * time.Second).Format(time.RFC3339) actualFourthSecret, err := clusterAdminKubeClientset.Secrets(ns).Update(actualThirdSecret) if err != nil { t.Fatal(err) } var actualFifthSecret *kapi.Secret secretWatcher3, err := clusterAdminKubeClientset.Secrets(ns).Watch(kapi.ListOptions{ResourceVersion: actualFourthSecret.ResourceVersion}) if err != nil { t.Fatal(err) } _, err = watch.Until(30*time.Second, secretWatcher3, func(event watch.Event) (bool, error) { if event.Type != watch.Modified { return false, nil } secret := event.Object.(*kapi.Secret) if secret.Name == "my-secret" { actualFifthSecret = secret return true, nil } return false, nil }) if err != nil { t.Fatal(err) } secretWatcher3.Stop() if reflect.DeepEqual(actualFourthSecret.Data, actualFifthSecret.Data) { t.Fatalf("didn't update secret content: %#v", actualFifthSecret) } }