Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/manifests/assets/canary/daemonset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ spec:
volumes:
- name: cert
secret:
secretName: canary-serving-cert
# secret name is set at runtime
defaultMode: 0420
updateStrategy:
type: RollingUpdate
Expand Down
4 changes: 1 addition & 3 deletions pkg/manifests/assets/canary/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
# Specific values are applied at runtime
kind: Service
apiVersion: v1
metadata:
metadata: {}
# name and namespace are set at runtime.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
# name and namespace are set at runtime.
# metadata values are set at runtime.

annotations:
service.beta.openshift.io/serving-cert-secret-name: canary-serving-cert
spec:
type: ClusterIP
ports:
Expand Down
24 changes: 22 additions & 2 deletions pkg/operator/controller/canary/daemonset.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Comment on lines +22 to +25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not get the secretName within desiredCanaryDaemonSet? Then you don't need to pass it in as a parameter.

desired := desiredCanaryDaemonSet(r.config.CanaryImage, secretName.Name)
haveDs, current, err := r.currentCanaryDaemonSet()
if err != nil {
return false, nil, err
Expand Down Expand Up @@ -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
Expand All @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to call canarySecretName right here instead of in the ensure function, and then passing it in here.

Suggested change
daemonset.Spec.Template.Spec.Volumes[0].Secret.SecretName = secretName
daemonset.Spec.Template.Spec.Volumes[0].Secret.SecretName, err := canarySecretName(name.Namespace)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And then you could test the secret generation in Test_desiredCanaryDaemonSet instead of writing a new test for ensureCanaryDaemonSet.


return daemonset
}

Expand Down Expand Up @@ -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
}
22 changes: 20 additions & 2 deletions pkg/operator/controller/canary/daemonset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down
10 changes: 6 additions & 4 deletions pkg/operator/controller/canary/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
}

Expand Down Expand Up @@ -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,
Expand Down
28 changes: 28 additions & 0 deletions pkg/operator/controller/certificate/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't there need to be a different function to ensure a canary cert rather than ensure a default cert? Does this ensure the correct cert?

errs = append(errs, fmt.Errorf("failed to ensure canary cert for %s: %v", ingress.Name, err))
}
}
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/operator/controller/certificate/default_cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down