Skip to content

Commit cd19736

Browse files
committed
test(certs): add a test the ensures services do not get the same
ownerref added twice
1 parent 4869be8 commit cd19736

File tree

1 file changed

+254
-7
lines changed

1 file changed

+254
-7
lines changed

pkg/controller/install/certresources_test.go

Lines changed: 254 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,17 @@ func newFakeLister(state fakeState) *operatorlisterfakes.FakeOperatorLister {
106106
}
107107

108108
func TestInstallCertRequirementsForDeployment(t *testing.T) {
109+
owner := ownerutil.Owner(&v1alpha1.ClusterServiceVersion{
110+
TypeMeta: metav1.TypeMeta{
111+
Kind: v1alpha1.ClusterServiceVersionKind,
112+
APIVersion: v1alpha1.ClusterServiceVersionAPIVersion,
113+
},
114+
ObjectMeta: metav1.ObjectMeta{
115+
Name: "owner",
116+
Namespace: "test-namespace",
117+
UID: "123-uid",
118+
},
119+
})
109120
ca := keyPair(t, time.Now().Add(time.Hour))
110121
caPEM, _, err := ca.ToPEM()
111122
assert.NoError(t, err)
@@ -143,7 +154,7 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) {
143154
mockOpClient.EXPECT().DeleteService(namespace, "test-service", &metav1.DeleteOptions{}).Return(nil)
144155
service := corev1.Service{
145156
ObjectMeta: metav1.ObjectMeta{
146-
Name: "test-service",
157+
Name: "test-service",
147158
OwnerReferences: []metav1.OwnerReference{
148159
ownerutil.NonBlockingOwner(&v1alpha1.ClusterServiceVersion{}),
149160
},
@@ -168,13 +179,14 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) {
168179

169180
secret := &corev1.Secret{
170181
ObjectMeta: metav1.ObjectMeta{
171-
Name: "test-service-cert",
172-
Namespace: namespace,
182+
Name: "test-service-cert",
183+
Namespace: namespace,
173184
Annotations: map[string]string{OLMCAHashAnnotationKey: caHash},
174185
},
175186
Data: map[string][]byte{
176-
"tls.crt": certPEM,
177-
"tls.key": privPEM,
187+
"tls.crt": certPEM,
188+
"tls.key": privPEM,
189+
OLMCAPEMKey: caPEM,
178190
},
179191
Type: corev1.SecretTypeTLS,
180192
}
@@ -328,6 +340,241 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) {
328340
},
329341
},
330342
},
343+
{
344+
Name: "webhook-cert",
345+
VolumeSource: corev1.VolumeSource{
346+
Secret: &corev1.SecretVolumeSource{
347+
SecretName: "test-service-cert",
348+
Items: []corev1.KeyToPath{
349+
{
350+
Key: "tls.crt",
351+
Path: "tls.crt",
352+
},
353+
{
354+
Key: "tls.key",
355+
Path: "tls.key",
356+
},
357+
},
358+
},
359+
},
360+
},
361+
},
362+
},
363+
},
364+
},
365+
},
366+
{
367+
name: "doesn't add duplicate service ownerrefs",
368+
mockExternal: func(mockOpClient *operatorclientmocks.MockClientInterface, fakeLister *operatorlisterfakes.FakeOperatorLister, namespace string, args args) {
369+
mockOpClient.EXPECT().DeleteService(namespace, "test-service", &metav1.DeleteOptions{}).Return(nil)
370+
service := corev1.Service{
371+
ObjectMeta: metav1.ObjectMeta{
372+
Name: "test-service",
373+
Namespace: owner.GetNamespace(),
374+
OwnerReferences: []metav1.OwnerReference{
375+
ownerutil.NonBlockingOwner(owner),
376+
},
377+
},
378+
Spec: corev1.ServiceSpec{
379+
Ports: args.ports,
380+
Selector: selector(t, "test=label").MatchLabels,
381+
},
382+
}
383+
mockOpClient.EXPECT().CreateService(&service).Return(&service, nil)
384+
385+
hosts := []string{
386+
fmt.Sprintf("%s.%s", service.GetName(), namespace),
387+
fmt.Sprintf("%s.%s.svc", service.GetName(), namespace),
388+
}
389+
servingPair, err := certGenerator.Generate(args.rotateAt, Organization, args.ca, hosts)
390+
require.NoError(t, err)
391+
392+
// Create Secret for serving cert
393+
certPEM, privPEM, err := servingPair.ToPEM()
394+
require.NoError(t, err)
395+
396+
secret := &corev1.Secret{
397+
ObjectMeta: metav1.ObjectMeta{
398+
Name: "test-service-cert",
399+
Namespace: namespace,
400+
Annotations: map[string]string{OLMCAHashAnnotationKey: caHash},
401+
},
402+
Data: map[string][]byte{
403+
"tls.crt": certPEM,
404+
"tls.key": privPEM,
405+
OLMCAPEMKey: caPEM,
406+
},
407+
Type: corev1.SecretTypeTLS,
408+
}
409+
mockOpClient.EXPECT().UpdateSecret(secret).Return(secret, nil)
410+
411+
secretRole := &rbacv1.Role{
412+
ObjectMeta: metav1.ObjectMeta{
413+
Name: secret.GetName(),
414+
Namespace: namespace,
415+
},
416+
Rules: []rbacv1.PolicyRule{
417+
{
418+
Verbs: []string{"get"},
419+
APIGroups: []string{""},
420+
Resources: []string{"secrets"},
421+
ResourceNames: []string{secret.GetName()},
422+
},
423+
},
424+
}
425+
mockOpClient.EXPECT().UpdateRole(secretRole).Return(secretRole, nil)
426+
427+
roleBinding := &rbacv1.RoleBinding{
428+
ObjectMeta: metav1.ObjectMeta{
429+
Name: secret.GetName(),
430+
Namespace: namespace,
431+
},
432+
Subjects: []rbacv1.Subject{
433+
{
434+
Kind: "ServiceAccount",
435+
APIGroup: "",
436+
Name: "test-sa",
437+
Namespace: namespace,
438+
},
439+
},
440+
RoleRef: rbacv1.RoleRef{
441+
APIGroup: "rbac.authorization.k8s.io",
442+
Kind: "Role",
443+
Name: secretRole.GetName(),
444+
},
445+
}
446+
mockOpClient.EXPECT().UpdateRoleBinding(roleBinding).Return(roleBinding, nil)
447+
448+
authDelegatorClusterRoleBinding := &rbacv1.ClusterRoleBinding{
449+
ObjectMeta: metav1.ObjectMeta{
450+
Name: service.GetName() + "-system:auth-delegator",
451+
},
452+
Subjects: []rbacv1.Subject{
453+
{
454+
Kind: "ServiceAccount",
455+
APIGroup: "",
456+
Name: "test-sa",
457+
Namespace: namespace,
458+
},
459+
},
460+
RoleRef: rbacv1.RoleRef{
461+
APIGroup: "rbac.authorization.k8s.io",
462+
Kind: "ClusterRole",
463+
Name: "system:auth-delegator",
464+
},
465+
}
466+
467+
mockOpClient.EXPECT().UpdateClusterRoleBinding(authDelegatorClusterRoleBinding).Return(authDelegatorClusterRoleBinding, nil)
468+
469+
authReaderRoleBinding := &rbacv1.RoleBinding{
470+
Subjects: []rbacv1.Subject{
471+
{
472+
Kind: "ServiceAccount",
473+
APIGroup: "",
474+
Name: args.depSpec.Template.Spec.ServiceAccountName,
475+
Namespace: namespace,
476+
},
477+
},
478+
RoleRef: rbacv1.RoleRef{
479+
APIGroup: "rbac.authorization.k8s.io",
480+
Kind: "Role",
481+
Name: "extension-apiserver-authentication-reader",
482+
},
483+
}
484+
authReaderRoleBinding.SetName(service.GetName() + "-auth-reader")
485+
authReaderRoleBinding.SetNamespace(KubeSystem)
486+
487+
mockOpClient.EXPECT().UpdateRoleBinding(authReaderRoleBinding).Return(authReaderRoleBinding, nil)
488+
},
489+
state: fakeState{
490+
existingService: &corev1.Service{
491+
ObjectMeta: metav1.ObjectMeta{
492+
Namespace: owner.GetNamespace(),
493+
OwnerReferences: []metav1.OwnerReference{
494+
ownerutil.NonBlockingOwner(owner),
495+
},
496+
},
497+
},
498+
existingSecret: &corev1.Secret{
499+
ObjectMeta: metav1.ObjectMeta{},
500+
},
501+
existingRole: &rbacv1.Role{
502+
ObjectMeta: metav1.ObjectMeta{},
503+
},
504+
existingRoleBinding: &rbacv1.RoleBinding{
505+
ObjectMeta: metav1.ObjectMeta{},
506+
},
507+
existingClusterRoleBinding: &rbacv1.ClusterRoleBinding{
508+
ObjectMeta: metav1.ObjectMeta{},
509+
},
510+
},
511+
fields: fields{
512+
owner: owner,
513+
previousStrategy: nil,
514+
templateAnnotations: nil,
515+
initializers: nil,
516+
apiServiceDescriptions: []certResource{},
517+
webhookDescriptions: []certResource{},
518+
},
519+
args: args{
520+
deploymentName: "test",
521+
ca: ca,
522+
rotateAt: time.Now().Add(time.Hour),
523+
ports: []corev1.ServicePort{},
524+
depSpec: appsv1.DeploymentSpec{
525+
Selector: selector(t, "test=label"),
526+
Template: corev1.PodTemplateSpec{
527+
Spec: corev1.PodSpec{
528+
ServiceAccountName: "test-sa",
529+
},
530+
},
531+
},
532+
},
533+
want: &appsv1.DeploymentSpec{
534+
Selector: selector(t, "test=label"),
535+
Template: corev1.PodTemplateSpec{
536+
ObjectMeta: metav1.ObjectMeta{
537+
Annotations: map[string]string{OLMCAHashAnnotationKey: caHash},
538+
},
539+
Spec: corev1.PodSpec{
540+
ServiceAccountName: "test-sa",
541+
Volumes: []corev1.Volume{
542+
{
543+
Name: "apiservice-cert",
544+
VolumeSource: corev1.VolumeSource{
545+
Secret: &corev1.SecretVolumeSource{
546+
SecretName: "test-service-cert",
547+
Items: []corev1.KeyToPath{
548+
{
549+
Key: "tls.crt",
550+
Path: "apiserver.crt",
551+
},
552+
{
553+
Key: "tls.key",
554+
Path: "apiserver.key",
555+
},
556+
},
557+
},
558+
},
559+
},
560+
{
561+
Name: "webhook-cert",
562+
VolumeSource: corev1.VolumeSource{
563+
Secret: &corev1.SecretVolumeSource{
564+
SecretName: "test-service-cert",
565+
Items: []corev1.KeyToPath{
566+
{
567+
Key: "tls.crt",
568+
Path: "tls.crt",
569+
},
570+
{
571+
Key: "tls.key",
572+
Path: "tls.key",
573+
},
574+
},
575+
},
576+
},
577+
},
331578
},
332579
},
333580
},
@@ -355,13 +602,13 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) {
355602
apiServiceDescriptions: tt.fields.apiServiceDescriptions,
356603
webhookDescriptions: tt.fields.webhookDescriptions,
357604
}
358-
got, err := i.installCertRequirementsForDeployment(tt.args.deploymentName, tt.args.ca, tt.args.rotateAt, tt.args.depSpec, tt.args.ports)
605+
got, _, err := i.installCertRequirementsForDeployment(tt.args.deploymentName, tt.args.ca, tt.args.rotateAt, tt.args.depSpec, tt.args.ports)
359606
if (err != nil) != tt.wantErr {
360607
t.Errorf("installCertRequirementsForDeployment() error = %v, wantErr %v", err, tt.wantErr)
361608
return
362609
}
363610
if !reflect.DeepEqual(got, tt.want) {
364-
t.Errorf("installCertRequirementsForDeployment() got = %v, want %v", got, tt.want)
611+
t.Errorf("installCertRequirementsForDeployment() \n got = %v \n want = %v", got, tt.want)
365612
}
366613
})
367614
}

0 commit comments

Comments
 (0)