diff --git a/pkg/controller/bundle/bundle_unpacker.go b/pkg/controller/bundle/bundle_unpacker.go index 5f2d94d26e..7d2614bb01 100644 --- a/pkg/controller/bundle/bundle_unpacker.go +++ b/pkg/controller/bundle/bundle_unpacker.go @@ -117,8 +117,9 @@ func (c *ConfigMapUnpacker) job(cmRef *corev1.ObjectReference, bundlePath string // By setting restartPolicy = "Never" the pods don't get cleaned up since they're not running after a failure. // Keeping the pods around after failures helps in inspecting the logs of a failed bundle unpack job. // See: https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy - RestartPolicy: corev1.RestartPolicyNever, - ImagePullSecrets: secrets, + RestartPolicy: corev1.RestartPolicyNever, + ServiceAccountName: cmRef.Name, + ImagePullSecrets: secrets, SecurityContext: &corev1.PodSecurityContext{ SeccompProfile: &corev1.SeccompProfile{ Type: corev1.SeccompProfileTypeRuntimeDefault, @@ -337,6 +338,7 @@ type ConfigMapUnpacker struct { podLister listerscorev1.PodLister roleLister listersrbacv1.RoleLister rbLister listersrbacv1.RoleBindingLister + saLister listerscorev1.ServiceAccountLister loader *configmap.BundleLoader now func() metav1.Time unpackTimeout time.Duration @@ -424,6 +426,12 @@ func WithRoleBindingLister(rbLister listersrbacv1.RoleBindingLister) ConfigMapUn } } +func WithServiceAccountLister(saLister listerscorev1.ServiceAccountLister) ConfigMapUnpackerOption { + return func(unpacker *ConfigMapUnpacker) { + unpacker.saLister = saLister + } +} + func WithNow(now func() metav1.Time) ConfigMapUnpackerOption { return func(unpacker *ConfigMapUnpacker) { unpacker.now = now @@ -536,6 +544,11 @@ func (c *ConfigMapUnpacker) UnpackBundle(lookup *operatorsv1alpha1.BundleLookup, return } + _, err = c.ensureServiceAccount(cmRef) + if err != nil { + return + } + _, err = c.ensureRoleBinding(cmRef) if err != nil { return @@ -791,13 +804,36 @@ func (c *ConfigMapUnpacker) ensureRole(cmRef *corev1.ObjectReference) (role *rba return } +func (c *ConfigMapUnpacker) ensureServiceAccount(cmRef *corev1.ObjectReference) (serviceAccount *corev1.ServiceAccount, err error) { + fresh := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: cmRef.Name, + Namespace: cmRef.Namespace, + }, + } + + fresh.SetOwnerReferences([]metav1.OwnerReference{ownerRef(cmRef)}) + fresh.SetLabels(map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}) + + serviceAccount, err = c.saLister.ServiceAccounts(fresh.GetNamespace()).Get(fresh.GetName()) + + if err != nil { + if apierrors.IsNotFound(err) { + serviceAccount, err = c.client.CoreV1().ServiceAccounts(fresh.GetNamespace()).Create(context.TODO(), fresh, metav1.CreateOptions{}) + } + return + } + + return +} + func (c *ConfigMapUnpacker) ensureRoleBinding(cmRef *corev1.ObjectReference) (roleBinding *rbacv1.RoleBinding, err error) { fresh := &rbacv1.RoleBinding{ Subjects: []rbacv1.Subject{ { Kind: "ServiceAccount", APIGroup: "", - Name: "default", + Name: cmRef.Name, Namespace: cmRef.Namespace, }, }, diff --git a/pkg/controller/bundle/bundle_unpacker_test.go b/pkg/controller/bundle/bundle_unpacker_test.go index f9ec614d5c..c2b53dd354 100644 --- a/pkg/controller/bundle/bundle_unpacker_test.go +++ b/pkg/controller/bundle/bundle_unpacker_test.go @@ -274,8 +274,9 @@ func TestConfigMapUnpacker(t *testing.T) { }, }, Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - ImagePullSecrets: []corev1.LocalObjectReference{{Name: "my-secret"}}, + RestartPolicy: corev1.RestartPolicyNever, + ServiceAccountName: pathHash, + ImagePullSecrets: []corev1.LocalObjectReference{{Name: "my-secret"}}, SecurityContext: &corev1.PodSecurityContext{ RunAsNonRoot: ptr.To(bool(true)), RunAsUser: ptr.To(int64(runAsUser)), @@ -450,7 +451,7 @@ func TestConfigMapUnpacker(t *testing.T) { { Kind: "ServiceAccount", APIGroup: "", - Name: "default", + Name: pathHash, Namespace: "ns-a", }, }, @@ -494,7 +495,8 @@ func TestConfigMapUnpacker(t *testing.T) { }, }, Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, + RestartPolicy: corev1.RestartPolicyNever, + ServiceAccountName: digestHash, SecurityContext: &corev1.PodSecurityContext{ RunAsNonRoot: ptr.To(bool(true)), RunAsUser: ptr.To(int64(runAsUser)), @@ -753,7 +755,8 @@ func TestConfigMapUnpacker(t *testing.T) { }, }, Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, + RestartPolicy: corev1.RestartPolicyNever, + ServiceAccountName: digestHash, SecurityContext: &corev1.PodSecurityContext{ RunAsNonRoot: ptr.To(bool(true)), RunAsUser: ptr.To(int64(runAsUser)), @@ -941,7 +944,7 @@ func TestConfigMapUnpacker(t *testing.T) { { Kind: "ServiceAccount", APIGroup: "", - Name: "default", + Name: digestHash, Namespace: "ns-a", }, }, @@ -1007,7 +1010,8 @@ func TestConfigMapUnpacker(t *testing.T) { }, }, Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, + RestartPolicy: corev1.RestartPolicyNever, + ServiceAccountName: pathHash, SecurityContext: &corev1.PodSecurityContext{ RunAsNonRoot: ptr.To(bool(true)), RunAsUser: ptr.To(int64(runAsUser)), @@ -1231,7 +1235,8 @@ func TestConfigMapUnpacker(t *testing.T) { }, }, Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, + RestartPolicy: corev1.RestartPolicyNever, + ServiceAccountName: pathHash, SecurityContext: &corev1.PodSecurityContext{ RunAsNonRoot: ptr.To(bool(true)), RunAsUser: ptr.To(int64(runAsUser)), @@ -1468,7 +1473,8 @@ func TestConfigMapUnpacker(t *testing.T) { }, }, Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, + RestartPolicy: corev1.RestartPolicyNever, + ServiceAccountName: pathHash, SecurityContext: &corev1.PodSecurityContext{ RunAsNonRoot: ptr.To(bool(true)), RunAsUser: ptr.To(int64(runAsUser)), @@ -1618,6 +1624,7 @@ func TestConfigMapUnpacker(t *testing.T) { podLister := factory.Core().V1().Pods().Lister() roleLister := factory.Rbac().V1().Roles().Lister() rbLister := factory.Rbac().V1().RoleBindings().Lister() + saLister := factory.Core().V1().ServiceAccounts().Lister() stop := make(chan struct{}) defer close(stop) @@ -1639,6 +1646,7 @@ func TestConfigMapUnpacker(t *testing.T) { WithPodLister(podLister), WithRoleLister(roleLister), WithRoleBindingLister(rbLister), + WithServiceAccountLister(saLister), WithOPMImage(opmImage), WithUtilImage(utilImage), WithNow(now), diff --git a/pkg/controller/operators/catalog/operator.go b/pkg/controller/operators/catalog/operator.go index 24336fbd95..069e08ab76 100644 --- a/pkg/controller/operators/catalog/operator.go +++ b/pkg/controller/operators/catalog/operator.go @@ -736,6 +736,7 @@ func NewOperator(ctx context.Context, kubeconfigPath string, clock utilclock.Clo bundle.WithPodLister(buPodInformer.Lister()), bundle.WithRoleLister(roleInformer.Lister()), bundle.WithRoleBindingLister(roleBindingInformer.Lister()), + bundle.WithServiceAccountLister(serviceAccountInformer.Lister()), bundle.WithOPMImage(opmImage), bundle.WithUtilImage(utilImage), bundle.WithNow(op.now),