diff --git a/images/operator-helm-artifact/internal/reconcile/helmclusteraddon/reconciler.go b/images/operator-helm-artifact/internal/reconcile/helmclusteraddon/reconciler.go index 5e52034..3aaf261 100644 --- a/images/operator-helm-artifact/internal/reconcile/helmclusteraddon/reconciler.go +++ b/images/operator-helm-artifact/internal/reconcile/helmclusteraddon/reconciler.go @@ -23,6 +23,7 @@ import ( "github.com/opencontainers/go-digest" "github.com/werf/3p-fluxcd-pkg/chartutil" helmchartutil "helm.sh/helm/v3/pkg/chartutil" + corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -91,7 +92,8 @@ func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reco return reconcile.Result{}, nil } - err := r.statusManager.InitializeConditions(ctx, addon, + err := r.statusManager.InitializeConditions( + ctx, addon, helmv1alpha1.ConditionTypeReady, helmv1alpha1.ConditionTypeManaged, helmv1alpha1.ConditionTypeInstalled, @@ -132,6 +134,15 @@ func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reco )}) } + if err := r.reconcileAddonNamespace(ctx, addon); err != nil { + return reconcile.Result{}, r.statusManager.Update(ctx, addon, status.NoopStatusMutator, status.NoopStatusMapper, services.ReleaseResult{Status: status.Failed( + addon, + helmv1alpha1.ReasonFailed, + fmt.Sprintf("Failed to reconcile target namespace: %s", err.Error()), + err, + )}) + } + var chartRes services.ChartResult var repoRes services.OCIRepoResult var releaseRes services.ReleaseResult @@ -245,6 +256,33 @@ func (r *Reconciler) reconcileDelete(ctx context.Context, addon *helmv1alpha1.He return reconcile.Result{}, nil } +func (r *Reconciler) reconcileAddonNamespace(ctx context.Context, addon *helmv1alpha1.HelmClusterAddon) error { + ns := &corev1.Namespace{} + + err := r.Get(ctx, client.ObjectKey{Name: addon.Spec.Namespace}, ns) + if err != nil { + if !apierrors.IsNotFound(err) { + return fmt.Errorf("getting namespace: %w", err) + } + + ns = &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: addon.Spec.Namespace, + }, + } + + err = r.Create(ctx, ns) + if err != nil { + if apierrors.IsAlreadyExists(err) { + return nil + } + return fmt.Errorf("creating namespace: %w", err) + } + } + + return nil +} + func (r *Reconciler) reconcileForceAnnotation(ctx context.Context, req reconcile.Request) error { var addon helmv1alpha1.HelmClusterAddon diff --git a/templates/operator-helm-controller/rbac-for-us.yaml b/templates/operator-helm-controller/rbac-for-us.yaml index 1fd890f..1b8db98 100644 --- a/templates/operator-helm-controller/rbac-for-us.yaml +++ b/templates/operator-helm-controller/rbac-for-us.yaml @@ -28,6 +28,14 @@ metadata: {{- include "helm_lib_module_labels" (list .) | nindent 2 }} name: d8:{{ .Chart.Name }}:operator-helm-controller rules: +- apiGroups: + - "" + resources: + - namespaces + verbs: + - create + - get + - list - apiGroups: - authentication.k8s.io resources: diff --git a/tests/e2e/internal/framework/cleanup.go b/tests/e2e/internal/framework/cleanup.go index 567417e..7df80dd 100644 --- a/tests/e2e/internal/framework/cleanup.go +++ b/tests/e2e/internal/framework/cleanup.go @@ -18,7 +18,7 @@ package framework import "os" -const PostCleanUpEnv = "POST_CLEANUP" +const PostCleanUpEnv = "E2E_POST_CLEANUP" func IsCleanUpNeeded() bool { return os.Getenv(PostCleanUpEnv) != "no"