diff --git a/pkg/manifests/assets/canary/daemonset.yaml b/pkg/manifests/assets/canary/daemonset.yaml index 8d5ffa7989..0733ae303b 100644 --- a/pkg/manifests/assets/canary/daemonset.yaml +++ b/pkg/manifests/assets/canary/daemonset.yaml @@ -50,7 +50,7 @@ spec: volumes: - name: cert secret: - secretName: canary-serving-cert + # secret name is set at runtime defaultMode: 0420 updateStrategy: type: RollingUpdate diff --git a/pkg/manifests/assets/canary/service.yaml b/pkg/manifests/assets/canary/service.yaml index 0b1b97d791..31807820ce 100644 --- a/pkg/manifests/assets/canary/service.yaml +++ b/pkg/manifests/assets/canary/service.yaml @@ -2,10 +2,8 @@ # Specific values are applied at runtime kind: Service apiVersion: v1 -metadata: +metadata: {} # name and namespace are set at runtime. - annotations: - service.beta.openshift.io/serving-cert-secret-name: canary-serving-cert spec: type: ClusterIP ports: diff --git a/pkg/operator/controller/canary/daemonset.go b/pkg/operator/controller/canary/daemonset.go index ea477b4b13..3e428425f8 100644 --- a/pkg/operator/controller/canary/daemonset.go +++ b/pkg/operator/controller/canary/daemonset.go @@ -7,17 +7,23 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + operatorv1 "github.com/openshift/api/operator/v1" "github.com/openshift/cluster-ingress-operator/pkg/manifests" "github.com/openshift/cluster-ingress-operator/pkg/operator/controller" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" ) // ensureCanaryDaemonSet ensures the canary daemonset exists func (r *reconciler) ensureCanaryDaemonSet() (bool, *appsv1.DaemonSet, error) { - desired := desiredCanaryDaemonSet(r.config.CanaryImage) + secretName, err := r.canarySecretName(controller.CanaryDaemonSetName().Namespace) + if err != nil { + return false, nil, err + } + desired := desiredCanaryDaemonSet(r.config.CanaryImage, secretName.Name) haveDs, current, err := r.currentCanaryDaemonSet() if err != nil { return false, nil, err @@ -80,7 +86,7 @@ func (r *reconciler) updateCanaryDaemonSet(current, desired *appsv1.DaemonSet) ( // desiredCanaryDaemonSet returns the desired canary daemonset read in // from manifests -func desiredCanaryDaemonSet(canaryImage string) *appsv1.DaemonSet { +func desiredCanaryDaemonSet(canaryImage, secretName string) *appsv1.DaemonSet { daemonset := manifests.CanaryDaemonSet() name := controller.CanaryDaemonSetName() daemonset.Name = name.Name @@ -97,6 +103,8 @@ func desiredCanaryDaemonSet(canaryImage string) *appsv1.DaemonSet { daemonset.Spec.Template.Spec.Containers[0].Image = canaryImage daemonset.Spec.Template.Spec.Containers[0].Command = []string{"ingress-operator", CanaryHealthcheckCommand} + daemonset.Spec.Template.Spec.Volumes[0].Secret.SecretName = secretName + return daemonset } @@ -196,3 +204,15 @@ func cmpTolerations(a, b corev1.Toleration) bool { } return true } + +func (r *reconciler) canarySecretName(Namespace string) (types.NamespacedName, error) { + defaultIC := operatorv1.IngressController{} + defaultICName := types.NamespacedName{ + Name: manifests.DefaultIngressControllerName, + Namespace: r.config.Namespace, + } + if err := r.client.Get(context.TODO(), defaultICName, &defaultIC); err != nil { + return types.NamespacedName{}, err + } + return controller.RouterEffectiveDefaultCertificateSecretName(&defaultIC, Namespace), nil +} diff --git a/pkg/operator/controller/canary/daemonset_test.go b/pkg/operator/controller/canary/daemonset_test.go index d29bc5afca..b25a333cf3 100644 --- a/pkg/operator/controller/canary/daemonset_test.go +++ b/pkg/operator/controller/canary/daemonset_test.go @@ -16,7 +16,8 @@ import ( func Test_desiredCanaryDaemonSet(t *testing.T) { // canaryImageName is the ingress-operator image canaryImageName := "openshift/origin-cluster-ingress-operator:latest" - daemonset := desiredCanaryDaemonSet(canaryImageName) + certSecretName := "test_secret_name" + daemonset := desiredCanaryDaemonSet(canaryImageName, certSecretName) expectedDaemonSetName := controller.CanaryDaemonSetName() @@ -83,6 +84,23 @@ func Test_desiredCanaryDaemonSet(t *testing.T) { if !cmp.Equal(tolerations, expectedTolerations) { t.Errorf("expected daemonset tolerations to be %v, but got %v", expectedTolerations, tolerations) } + + volumes := daemonset.Spec.Template.Spec.Volumes + secretMode := int32(0420) + expectedVolumes := []corev1.Volume{ + { + Name: "cert", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: certSecretName, + DefaultMode: &secretMode, + }, + }, + }, + } + if !cmp.Equal(volumes, expectedVolumes) { + t.Errorf("expected daemonset volumes to be %v, but got %v", expectedVolumes, volumes) + } } func Test_canaryDaemonsetChanged(t *testing.T) { @@ -229,7 +247,7 @@ func Test_canaryDaemonsetChanged(t *testing.T) { for _, tc := range testCases { t.Run(tc.description, func(t *testing.T) { - original := desiredCanaryDaemonSet("") + original := desiredCanaryDaemonSet("", "foobar") mutated := original.DeepCopy() tc.mutate(mutated) if changed, updated := canaryDaemonSetChanged(original, mutated); changed != tc.expect { diff --git a/pkg/operator/controller/canary/service_test.go b/pkg/operator/controller/canary/service_test.go index 440d2fa691..2245f86fcd 100644 --- a/pkg/operator/controller/canary/service_test.go +++ b/pkg/operator/controller/canary/service_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/openshift/cluster-ingress-operator/pkg/manifests" "github.com/openshift/cluster-ingress-operator/pkg/operator/controller" @@ -54,10 +55,8 @@ func Test_desiredCanaryService(t *testing.T) { t.Errorf("expected service owner references %#v, but got %#v", expectedOwnerRefs, service.OwnerReferences) } - expectedAnnotations := map[string]string{ - "service.beta.openshift.io/serving-cert-secret-name": "canary-serving-cert", - } - if !cmp.Equal(service.Annotations, expectedAnnotations) { + expectedAnnotations := map[string]string{} + if !cmp.Equal(service.Annotations, expectedAnnotations, cmpopts.EquateEmpty()) { t.Errorf("expected service annotations to be %q, but got %q", expectedAnnotations, service.Annotations) } @@ -90,6 +89,9 @@ func Test_canaryServiceChanged(t *testing.T) { { description: "changed annotation", mutate: func(service *corev1.Service) { + if service.Annotations == nil { + service.Annotations = map[string]string{} + } service.Annotations["foo"] = "bar" }, expected: true, diff --git a/pkg/operator/controller/certificate/controller.go b/pkg/operator/controller/certificate/controller.go index 5e9b129142..eae1276018 100644 --- a/pkg/operator/controller/certificate/controller.go +++ b/pkg/operator/controller/certificate/controller.go @@ -10,6 +10,7 @@ import ( "time" logf "github.com/openshift/cluster-ingress-operator/pkg/log" + "github.com/openshift/cluster-ingress-operator/pkg/manifests" "github.com/openshift/cluster-ingress-operator/pkg/operator/controller" ingresscontroller "github.com/openshift/cluster-ingress-operator/pkg/operator/controller/ingress" @@ -105,6 +106,33 @@ func (r *reconciler) Reconcile(ctx context.Context, request reconcile.Request) ( if _, err := r.ensureDefaultCertificateForIngress(ca, deployment.Namespace, deploymentRef, ingress); err != nil { errs = append(errs, fmt.Errorf("failed to ensure default cert for %s: %v", ingress.Name, err)) } + if ingress.Name == manifests.DefaultIngressControllerName { + log.Info("ensuring canary certificate") + daemonset := &appsv1.DaemonSet{} + err = r.client.Get(ctx, controller.CanaryDaemonSetName(), daemonset) + if err != nil { + if errors.IsNotFound(err) { + // All ingresses should have a deployment, so this one may not have been + // created yet. Retry after a reasonable amount of time. + log.Info("canary daemonset not found; will retry default cert sync") + result.RequeueAfter = 5 * time.Second + } else { + errs = append(errs, fmt.Errorf("failed to get daemonset: %v", err)) + } + } else { + trueVar := true + canaryRef := metav1.OwnerReference{ + APIVersion: "apps/v1", + Kind: "Daemonset", + Name: daemonset.Name, + UID: daemonset.UID, + Controller: &trueVar, + } + if _, err := r.ensureDefaultCertificateForIngress(ca, "openshift-ingress-canary", canaryRef, ingress); err != nil { + errs = append(errs, fmt.Errorf("failed to ensure canary cert for %s: %v", ingress.Name, err)) + } + } + } } } diff --git a/pkg/operator/controller/certificate/default_cert.go b/pkg/operator/controller/certificate/default_cert.go index 8ab2886ef7..3aeafcc460 100644 --- a/pkg/operator/controller/certificate/default_cert.go +++ b/pkg/operator/controller/certificate/default_cert.go @@ -48,14 +48,14 @@ func (r *reconciler) ensureDefaultCertificateForIngress(caSecret *corev1.Secret, if deleted, err := r.deleteRouterDefaultCertificate(current); err != nil { return true, fmt.Errorf("failed to delete default certificate: %v", err) } else if deleted { - r.recorder.Eventf(ci, "Normal", "DeletedDefaultCertificate", "Deleted default wildcard certificate %q", current.Name) + r.recorder.Eventf(ci, "Normal", "DeletedDefaultCertificate", "Deleted default wildcard certificate %q in namespace %q", current.Name, current.Namespace) return false, nil } case wantCert && !haveCert: if created, err := r.createRouterDefaultCertificate(desired); err != nil { return false, fmt.Errorf("failed to create default certificate: %v", err) } else if created { - r.recorder.Eventf(ci, "Normal", "CreatedDefaultCertificate", "Created default wildcard certificate %q", desired.Name) + r.recorder.Eventf(ci, "Normal", "CreatedDefaultCertificate", "Created default wildcard certificate %q in namespace %q", desired.Name, desired.Namespace) return true, nil } case wantCert && haveCert: