From ddeeea18dec92e6d4ccf3d02f10156c849cf3236 Mon Sep 17 00:00:00 2001 From: Disaiah Bennett Date: Tue, 5 Sep 2023 15:00:28 -0400 Subject: [PATCH] [ACM-6913] Add SubmarinerAddon as sub-component to MCH (#1090) * add submariner-addon as sub-component to MCH Signed-off-by: Disaiah Bennett * updated console enable logic Signed-off-by: Disaiah Bennett * updated multiclusterhub_controller.go Signed-off-by: Disaiah Bennett --------- Signed-off-by: Disaiah Bennett --- .github/pull_request_template.md | 42 +++ api/v1/methods_test.go | 4 +- api/v1/multiclusterhub_methods.go | 95 ++++--- controllers/finalizers.go | 4 +- controllers/multiclusterhub_controller.go | 264 +++++------------- .../multiclusterhub_controller_test.go | 40 ++- hack/bundle-automation/config.yaml | 38 ++- .../charts/toggle/submariner-addon/Chart.yaml | 6 + .../submariner-addon-clusterrole.yaml | 251 +++++++++++++++++ .../submariner-addon-clusterrolebinding.yaml | 12 + .../submariner-addon-serviceaccount.yaml | 4 + .../templates/submariner-addon.yaml | 111 ++++++++ .../toggle/submariner-addon/values.yaml | 11 + ...uster-management.io_submarinerconfigs.yaml | 256 +++++++++++++++++ ...nagement.io_submarinerdiagnoseconfigs.yaml | 143 ++++++++++ pkg/utils/utils.go | 22 +- 16 files changed, 1022 insertions(+), 281 deletions(-) create mode 100644 .github/pull_request_template.md create mode 100644 pkg/templates/charts/toggle/submariner-addon/Chart.yaml create mode 100644 pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon-clusterrole.yaml create mode 100644 pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon-clusterrolebinding.yaml create mode 100644 pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon-serviceaccount.yaml create mode 100644 pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon.yaml create mode 100644 pkg/templates/charts/toggle/submariner-addon/values.yaml create mode 100644 pkg/templates/crds/submariner-addon/submarineraddon.open-cluster-management.io_submarinerconfigs.yaml create mode 100644 pkg/templates/crds/submariner-addon/submarineraddon.open-cluster-management.io_submarinerdiagnoseconfigs.yaml diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000000..f033b3cd9b --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,42 @@ +# Description + +Please provide a brief description of the purpose of this pull request. + +## Related Issue + +If applicable, please reference the issue(s) that this pull request addresses. + +## Changes Made + +Provide a clear and concise overview of the changes made in this pull request. + +## Screenshots (if applicable) + +Add screenshots or GIFs that demonstrate the changes visually, if relevant. + +## Checklist + +- [ ] I have tested the changes locally and they are functioning as expected. +- [ ] I have updated the documentation (if necessary) to reflect the changes. +- [ ] I have added/updated relevant unit tests (if applicable). +- [ ] I have ensured that my code follows the project's coding standards. +- [ ] I have checked for any potential security issues and addressed them. +- [ ] I have added necessary comments to the code, especially in complex or unclear sections. +- [ ] I have rebased my branch on top of the latest main/master branch. + +## Additional Notes + +Add any additional notes, context, or information that might be helpful for reviewers. + +## Reviewers + +Tag the appropriate reviewers who should review this pull request. To add reviewers, please add the following line: `/cc @reviewer1 @reviewer2` + +## Definition of Done + +- [ ] Code is reviewed. +- [ ] Code is tested. +- [ ] Documentation is updated. +- [ ] All checks and tests pass. +- [ ] Approved by at least one reviewer. +- [ ] Merged into the main/master branch. diff --git a/api/v1/methods_test.go b/api/v1/methods_test.go index 101df16e2b..9f9dbb28c1 100644 --- a/api/v1/methods_test.go +++ b/api/v1/methods_test.go @@ -138,10 +138,10 @@ var _ = Describe("V1 API Methods", func() { Expect(api.ValidComponent(config("invalid", true))).To(BeFalse()) }) - It("gets the correct number of default enabled components", func() { + It("gets the correct number of default enabled components", func() { components, err := api.GetDefaultEnabledComponents() - Expect(len(components)).To(Equal(10)) + Expect(len(components)).To(Equal(11)) Expect(err).To(BeNil()) }) }) diff --git a/api/v1/multiclusterhub_methods.go b/api/v1/multiclusterhub_methods.go index fd0b902901..ee77cde44c 100644 --- a/api/v1/multiclusterhub_methods.go +++ b/api/v1/multiclusterhub_methods.go @@ -8,93 +8,112 @@ import ( const ( // MCH Appsub string = "app-lifecycle" - Search string = "search" + ClusterBackup string = "cluster-backup" + ClusterLifecycle string = "cluster-lifecycle" ClusterPermission string = "cluster-permission" - ManagementIngress string = "management-ingress" Console string = "console" - Insights string = "insights" GRC string = "grc" - ClusterLifecycle string = "cluster-lifecycle" - ClusterBackup string = "cluster-backup" - Repo string = "multiclusterhub-repo" + Insights string = "insights" + ManagementIngress string = "management-ingress" MultiClusterEngine string = "multicluster-engine" + MultiClusterObservability string = "multicluster-observability" + Repo string = "multiclusterhub-repo" + Search string = "search" + SubmarinerAddon string = "submariner-addon" Volsync string = "volsync" - MultiClusterObservability string = "observability" // MCE - MCEManagedServiceAccount string = "managedserviceaccount-preview" - MCEConsole string = "console-mce" - MCEDiscovery string = "discovery" - MCEHive string = "hive" MCEAssistedService string = "assisted-service" MCEClusterLifecycle string = "cluster-lifecycle-mce" MCEClusterManager string = "cluster-manager" - MCEServerFoundation string = "server-foundation" - MCEHypershift string = "hypershift" - MCEHypershiftPreview string = "hypershift-preview" - MCEHypershiftLocalHosting string = "hypershift-local-hosting" MCEClusterProxyAddon string = "cluster-proxy-addon" + MCEConsole string = "console-mce" + MCEDiscovery string = "discovery" + MCEHive string = "hive" + MCEHypershiftLocalHosting string = "hypershift-local-hosting" + MCEHypershiftPreview string = "hypershift-preview" + MCEHypershift string = "hypershift" MCELocalCluster string = "local-cluster" + MCEManagedServiceAccount string = "managedserviceaccount-preview" + MCEServerFoundation string = "server-foundation" ) var allComponents = []string{ // MCH - Repo, - Search, - ClusterPermission, Appsub, - ManagementIngress, + ClusterBackup, + ClusterLifecycle, + ClusterPermission, Console, - Insights, GRC, - ClusterLifecycle, - ClusterBackup, - Volsync, + Insights, + ManagementIngress, MultiClusterEngine, MultiClusterObservability, + Repo, + Search, + SubmarinerAddon, + Volsync, // MCE MCEAssistedService, MCEClusterLifecycle, MCEClusterManager, + MCEClusterProxyAddon, + MCEConsole, MCEDiscovery, MCEHive, - MCEServerFoundation, - MCEConsole, - MCEManagedServiceAccount, MCEHypershift, - MCEHypershiftPreview, MCEHypershiftLocalHosting, - MCEClusterProxyAddon, + MCEHypershiftPreview, + MCEManagedServiceAccount, + MCEServerFoundation, +} + +var MCHComponents = []string{ + Appsub, + ClusterBackup, + ClusterLifecycle, + ClusterPermission, + Console, + GRC, + Insights, + // MultiClusterEngine, + MultiClusterObservability, + //Repo, + Search, + SubmarinerAddon, + Volsync, } var MCEComponents = []string{ MCEAssistedService, MCEClusterLifecycle, MCEClusterManager, + MCEConsole, MCEDiscovery, MCEHive, - MCEServerFoundation, - MCEConsole, - MCEManagedServiceAccount, MCEHypershift, - MCEHypershiftPreview, MCEHypershiftLocalHosting, + MCEHypershiftPreview, + MCEManagedServiceAccount, + MCEServerFoundation, } func GetDefaultEnabledComponents() ([]string, error) { var defaultEnabledComponents = []string{ //Repo, + Appsub, + ClusterLifecycle, + ClusterPermission, Console, - Insights, GRC, - ClusterLifecycle, - Volsync, + Insights, MultiClusterEngine, - Search, - Appsub, MultiClusterObservability, - ClusterPermission, + Search, + SubmarinerAddon, + Volsync, } return defaultEnabledComponents, nil diff --git a/controllers/finalizers.go b/controllers/finalizers.go index c4a9a832a0..b404b85ba7 100644 --- a/controllers/finalizers.go +++ b/controllers/finalizers.go @@ -172,7 +172,7 @@ func (r *MultiClusterHubReconciler) cleanupMultiClusterEngine(log logr.Logger, m return nil } -func (r *MultiClusterHubReconciler) cleanupNamespaces(reqLogger logr.Logger) error { +func (r *MultiClusterHubReconciler) cleanupNamespaces(reqLogger logr.Logger, m *operatorsv1.MultiClusterHub) error { ctx := context.Background() clusterBackupNamespace := &corev1.Namespace{} err := r.Client.Get(ctx, types.NamespacedName{Name: utils.ClusterSubscriptionNamespace}, clusterBackupNamespace) @@ -274,7 +274,7 @@ func (r *MultiClusterHubReconciler) cleanupAppSubscriptions(reqLogger logr.Logge return nil } -func (r *MultiClusterHubReconciler) orphanOwnedMultiClusterEngine(m *operatorsv1.MultiClusterHub) error { +func (r *MultiClusterHubReconciler) orphanOwnedMultiClusterEngine(reqLogger logr.Logger, m *operatorsv1.MultiClusterHub) error { ctx := context.Background() mce, err := multiclusterengine.GetManagedMCE(ctx, r.Client) diff --git a/controllers/multiclusterhub_controller.go b/controllers/multiclusterhub_controller.go index d8aff92e6e..0481d04a44 100644 --- a/controllers/multiclusterhub_controller.go +++ b/controllers/multiclusterhub_controller.go @@ -125,7 +125,6 @@ var ( // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.8.3/pkg/reconcile func (r *MultiClusterHubReconciler) Reconcile(ctx context.Context, req ctrl.Request) (retQueue ctrl.Result, retError error) { r.Log = log.FromContext(ctx) - r.Log.Info("Reconciling MultiClusterHub") // Fetch the MultiClusterHub instance @@ -366,99 +365,12 @@ func (r *MultiClusterHubReconciler) Reconcile(ctx context.Context, req ctrl.Requ } // Install the rest of the subscriptions in no particular order - - if multiClusterHub.Enabled(operatorv1.Console) && ocpConsole { - result, err = r.ensureComponent(ctx, multiClusterHub, operatorv1.Console, r.CacheSpec.ImageOverrides) - } else { - result, err = r.ensureNoComponent(ctx, multiClusterHub, operatorv1.Console, r.CacheSpec.ImageOverrides) - } - if result != (ctrl.Result{}) { - return result, err - } - if multiClusterHub.Enabled(operatorv1.Insights) { - result, err = r.ensureComponent(ctx, multiClusterHub, operatorv1.Insights, r.CacheSpec.ImageOverrides) - } else { - result, err = r.ensureNoComponent(ctx, multiClusterHub, operatorv1.Insights, r.CacheSpec.ImageOverrides) - } - if result != (ctrl.Result{}) { - return result, err - } - if multiClusterHub.Enabled(operatorv1.Search) { - result, err = r.ensureComponent(ctx, multiClusterHub, operatorv1.Search, r.CacheSpec.ImageOverrides) - } else { - result, err = r.ensureNoComponent(ctx, multiClusterHub, operatorv1.Search, r.CacheSpec.ImageOverrides) - } - if result != (ctrl.Result{}) { - return result, err - } - if multiClusterHub.Enabled(operatorv1.GRC) { - result, err = r.ensureComponent(ctx, multiClusterHub, operatorv1.GRC, r.CacheSpec.ImageOverrides) - } else { - result, err = r.ensureNoComponent(ctx, multiClusterHub, operatorv1.GRC, r.CacheSpec.ImageOverrides) - } - if result != (ctrl.Result{}) { - return result, err - } - if multiClusterHub.Enabled(operatorv1.ClusterLifecycle) { - result, err = r.ensureComponent(ctx, multiClusterHub, operatorv1.ClusterLifecycle, r.CacheSpec.ImageOverrides) - } else { - result, err = r.ensureNoComponent(ctx, multiClusterHub, operatorv1.ClusterLifecycle, r.CacheSpec.ImageOverrides) - } - if result != (ctrl.Result{}) { - return result, err - } - if multiClusterHub.Enabled(operatorv1.MultiClusterObservability) { - result, err = r.ensureComponent(ctx, multiClusterHub, operatorv1.MultiClusterObservability, r.CacheSpec.ImageOverrides) - } else { - result, err = r.ensureNoComponent(ctx, multiClusterHub, operatorv1.MultiClusterObservability, r.CacheSpec.ImageOverrides) - } - if result != (ctrl.Result{}) { - return result, err - } - if multiClusterHub.Enabled(operatorv1.Volsync) { - result, err = r.ensureComponent(ctx, multiClusterHub, operatorv1.Volsync, r.CacheSpec.ImageOverrides) - } else { - result, err = r.ensureNoComponent(ctx, multiClusterHub, operatorv1.Volsync, r.CacheSpec.ImageOverrides) - } - if result != (ctrl.Result{}) { - return result, err - } - // Create Cluster Permissions if enabled - if multiClusterHub.Enabled(operatorv1.ClusterPermission) { - result, err = r.ensureClusterPermission(ctx, multiClusterHub, r.CacheSpec.ImageOverrides) - } else { - result, err = r.ensureNoClusterPermission(ctx, multiClusterHub, r.CacheSpec.ImageOverrides) - } - if result != (ctrl.Result{}) { - return result, err - } - if multiClusterHub.Enabled(operatorv1.ClusterBackup) { - ns := BackupNamespace() - result, err = r.ensureNamespace(multiClusterHub, ns) - if result != (ctrl.Result{}) { - return result, err - } - result, err = r.ensurePullSecret(multiClusterHub, ns.Name) - if result != (ctrl.Result{}) { - return result, err - } - result, err = r.ensureComponent(ctx, multiClusterHub, operatorv1.ClusterBackup, r.CacheSpec.ImageOverrides) - if result != (ctrl.Result{}) { - return result, err - } - } else { - result, err = r.ensureNoComponent(ctx, multiClusterHub, operatorv1.ClusterBackup, r.CacheSpec.ImageOverrides) - if result != (ctrl.Result{}) { - return result, err - } - result, err = r.ensureNoNamespace(multiClusterHub, BackupNamespaceUnstructured()) + for _, c := range operatorv1.MCHComponents { + result, err = r.ensureComponentOrNoComponent(ctx, multiClusterHub, c, r.CacheSpec.ImageOverrides, ocpConsole) if result != (ctrl.Result{}) { return result, err } } - if result != (ctrl.Result{}) { - return result, err - } if !multiClusterHub.Spec.DisableHubSelfManagement { result, err = r.ensureKlusterletAddonConfig(multiClusterHub) @@ -668,6 +580,9 @@ func (r *MultiClusterHubReconciler) fetchChartLocation(ctx context.Context, comp case operatorv1.Search: return utils.SearchV2ChartLocation + case operatorv1.SubmarinerAddon: + return utils.SubmarinerAddonChartLocation + case operatorv1.Volsync: return utils.VolsyncChartLocation @@ -677,6 +592,58 @@ func (r *MultiClusterHubReconciler) fetchChartLocation(ctx context.Context, comp } } +func (r *MultiClusterHubReconciler) ensureComponentOrNoComponent(ctx context.Context, m *operatorv1.MultiClusterHub, + component string, imageOverrides map[string]string, ocpConsole bool) (ctrl.Result, error) { + var result ctrl.Result + var err error + + log := log.FromContext(ctx) + + if !m.Enabled(component) { + if component == operatorv1.ClusterBackup { + result, err = r.ensureNoComponent(ctx, m, component, imageOverrides) + if result != (ctrl.Result{}) || err != nil { + return result, err + } + return r.ensureNoNamespace(m, BackupNamespaceUnstructured()) + } + return r.ensureNoComponent(ctx, m, component, imageOverrides) + + } else { + if component == operatorv1.ClusterBackup { + result, err = r.ensureNamespaceAndPullSecret(m, BackupNamespace()) + if result != (ctrl.Result{}) || err != nil { + return result, err + } + } + + if component == operatorv1.Console && !ocpConsole { + log.Info("OCP console is not enabled") + return r.ensureNoComponent(ctx, m, component, imageOverrides) + } + + return r.ensureComponent(ctx, m, component, imageOverrides) + } +} + +func (r *MultiClusterHubReconciler) ensureNamespaceAndPullSecret(m *operatorv1.MultiClusterHub, ns *corev1.Namespace) ( + ctrl.Result, error) { + var result ctrl.Result + var err error + + result, err = r.ensureNamespace(m, ns) + if result != (ctrl.Result{}) { + return result, err + } + + result, err = r.ensurePullSecret(m, ns.Name) + if result != (ctrl.Result{}) { + return result, err + } + + return result, err +} + func (r *MultiClusterHubReconciler) ensureComponent(ctx context.Context, m *operatorv1.MultiClusterHub, component string, images map[string]string) (ctrl.Result, error) { @@ -763,57 +730,6 @@ func (r *MultiClusterHubReconciler) ensureNoComponent(ctx context.Context, m *op return ctrl.Result{}, nil } -func (r *MultiClusterHubReconciler) ensureClusterPermission(ctx context.Context, m *operatorv1.MultiClusterHub, images map[string]string) (ctrl.Result, error) { - - log := log.FromContext(ctx) - - // Render temmplates from file location - templates, errs := renderer.RenderChart(utils.ClusterPermissionChartLocation, m, images) - // Will capture errors if the templates are not formatted correctly - if len(errs) > 0 { - for _, err := range errs { - log.Info(err.Error()) - } - return ctrl.Result{RequeueAfter: resyncPeriod}, nil - } - - // Applies all templates - for _, template := range templates { - result, err := r.applyTemplate(ctx, m, template) - // Will capture k8s errors - if err != nil { - return result, err - } - } - - return ctrl.Result{}, nil -} - -func (r *MultiClusterHubReconciler) ensureNoClusterPermission(ctx context.Context, m *operatorv1.MultiClusterHub, images map[string]string) (ctrl.Result, error) { - log := log.FromContext(ctx) - - // Renders all templates from charts - templates, errs := renderer.RenderChart(utils.ClusterPermissionChartLocation, m, images) - // Will capture errors if the templates are not formatted correctly - if len(errs) > 0 { - for _, err := range errs { - log.Info(err.Error()) - } - return ctrl.Result{RequeueAfter: resyncPeriod}, nil - } - - // Deletes all templates - for _, template := range templates { - result, err := r.deleteTemplate(ctx, m, template) - // Will capture k8s errors - if err != nil { - log.Error(err, fmt.Sprintf("Failed to delete template: %s", template.GetName())) - return result, err - } - } - return ctrl.Result{}, nil -} - func (r *MultiClusterHubReconciler) updateSearchEnablement(ctx context.Context, m *operatorv1.MultiClusterHub) (ctrl.Result, error) { m.Disable(operatorv1.Search) err := r.Client.Update(ctx, m) @@ -932,65 +848,27 @@ func (r *MultiClusterHubReconciler) ingressDomain(m *operatorv1.MultiClusterHub) } func (r *MultiClusterHubReconciler) finalizeHub(reqLogger logr.Logger, m *operatorv1.MultiClusterHub, ocpConsole bool) error { + imageOverrides := r.CacheSpec.ImageOverrides + if err := r.cleanupAppSubscriptions(reqLogger, m); err != nil { return err } - _, err := r.ensureNoComponent(context.TODO(), m, operatorv1.ClusterBackup, r.CacheSpec.ImageOverrides) - if err != nil { - return err - } - if err := r.cleanupNamespaces(reqLogger); err != nil { - return err - } - _, err = r.ensureNoComponent(context.TODO(), m, operatorv1.Appsub, r.CacheSpec.ImageOverrides) - if err != nil { - return err - } - _, err = r.ensureNoComponent(context.TODO(), m, operatorv1.ClusterLifecycle, r.CacheSpec.ImageOverrides) - if err != nil { - return err - } - _, err = r.ensureNoComponent(context.TODO(), m, operatorv1.ClusterPermission, r.CacheSpec.ImageOverrides) - if err != nil { - return err - } - _, err = r.ensureNoComponent(context.TODO(), m, operatorv1.Console, r.CacheSpec.ImageOverrides) - if err != nil { - return err - } - _, err = r.ensureNoComponent(context.TODO(), m, operatorv1.GRC, r.CacheSpec.ImageOverrides) - if err != nil { - return err - } - _, err = r.ensureNoComponent(context.TODO(), m, operatorv1.Insights, r.CacheSpec.ImageOverrides) - if err != nil { - return err - } - _, err = r.ensureNoComponent(context.TODO(), m, operatorv1.MultiClusterObservability, r.CacheSpec.ImageOverrides) - if err != nil { - return err - } - _, err = r.ensureNoComponent(context.TODO(), m, operatorv1.Search, r.CacheSpec.ImageOverrides) - if err != nil { - return err - } - _, err = r.ensureNoComponent(context.TODO(), m, operatorv1.Volsync, r.CacheSpec.ImageOverrides) - if err != nil { - return err - } - if err := r.cleanupClusterRoles(reqLogger, m); err != nil { - return err - } - if err := r.cleanupClusterRoleBindings(reqLogger, m); err != nil { - return err + + for _, c := range operatorv1.MCHComponents { + if _, err := r.ensureNoComponent(context.TODO(), m, c, imageOverrides); err != nil { + return err + } } - if err := r.cleanupMultiClusterEngine(reqLogger, m); err != nil { - return err + cleanupFunctions := []func(reqLogger logr.Logger, m *operatorv1.MultiClusterHub) error{ + r.cleanupNamespaces, r.cleanupClusterRoles, r.cleanupClusterRoleBindings, + r.cleanupMultiClusterEngine, r.orphanOwnedMultiClusterEngine, } - if err := r.orphanOwnedMultiClusterEngine(m); err != nil { - return err + for _, cleanupFn := range cleanupFunctions { + if err := cleanupFn(reqLogger, m); err != nil { + return err + } } reqLogger.Info("Successfully finalized multiClusterHub") diff --git a/controllers/multiclusterhub_controller_test.go b/controllers/multiclusterhub_controller_test.go index de3d1f7f7a..5783704522 100644 --- a/controllers/multiclusterhub_controller_test.go +++ b/controllers/multiclusterhub_controller_test.go @@ -710,13 +710,11 @@ var _ = Describe("MultiClusterHub controller", func() { Expect(err).To(BeNil()) By("Ensuring No Insights") - result, err = reconciler.ensureNoComponent(ctx, mch, operatorv1.Insights, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring Cluster Backup") - ns := BackupNamespace() result, err = reconciler.ensureNamespace(mch, ns) Expect(err).To(BeNil()) @@ -726,111 +724,105 @@ var _ = Describe("MultiClusterHub controller", func() { Expect(err).To(BeNil()) By("Ensuring No Cluster Backup") - result, err = reconciler.ensureNoComponent(ctx, mch, operatorv1.ClusterBackup, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring Search-v2") - result, err = reconciler.ensureComponent(ctx, mch, operatorv1.Search, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring No Search-v2") - Eventually(func() bool { result, err := reconciler.ensureNoComponent(ctx, mch, operatorv1.Search, testImages) return (err == nil && result == ctrl.Result{}) }, timeout, interval).Should(BeTrue()) By("Ensuring CLC") - result, err = reconciler.ensureComponent(ctx, mch, operatorv1.ClusterLifecycle, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring No CLC") - result, err = reconciler.ensureNoComponent(ctx, mch, operatorv1.ClusterLifecycle, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring App-Lifecycle") - result, err = reconciler.ensureComponent(ctx, mch, operatorv1.Appsub, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring No App-Lifecycle") - result, err = reconciler.ensureNoComponent(ctx, mch, operatorv1.Appsub, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring GRC") - result, err = reconciler.ensureComponent(ctx, mch, operatorv1.GRC, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring No GRC") - result, err = reconciler.ensureNoComponent(ctx, mch, operatorv1.GRC, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring Console") - result, err = reconciler.ensureComponent(ctx, mch, operatorv1.Console, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring No Console") - result, err = reconciler.ensureNoComponent(ctx, mch, operatorv1.Console, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring Volsync") - result, err = reconciler.ensureComponent(ctx, mch, operatorv1.Volsync, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring No Volsync") - result, err = reconciler.ensureNoComponent(ctx, mch, operatorv1.Volsync, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring MultiClusterObservability") - result, err = reconciler.ensureComponent(ctx, mch, operatorv1.MultiClusterObservability, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring No MultiClusterObservability") - result, err = reconciler.ensureNoComponent(ctx, mch, operatorv1.MultiClusterObservability, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) - By("Ensuring No Unregistered Component") - result, err = reconciler.ensureNoComponent(ctx, mch, "unknown", testImages) - Expect(result).To(Equal(ctrl.Result{RequeueAfter: resyncPeriod})) - Expect(err).To(BeNil()) By("Ensuring ClusterPermission") - - result, err = reconciler.ensureClusterPermission(ctx, mch, testImages) + result, err = reconciler.ensureComponent(ctx, mch, operatorv1.ClusterPermission, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) By("Ensuring No ClusterPermission") + result, err = reconciler.ensureNoComponent(ctx, mch, operatorv1.ClusterPermission, testImages) + Expect(result).To(Equal(ctrl.Result{})) + Expect(err).To(BeNil()) - result, err = reconciler.ensureNoClusterPermission(ctx, mch, testImages) + By("Ensuring SubmarinerAddon") + result, err = reconciler.ensureComponent(ctx, mch, operatorv1.SubmarinerAddon, testImages) Expect(result).To(Equal(ctrl.Result{})) Expect(err).To(BeNil()) + + By("Ensuring No SubmarinerAddon") + result, err = reconciler.ensureNoComponent(ctx, mch, operatorv1.SubmarinerAddon, testImages) + Expect(result).To(Equal(ctrl.Result{})) + Expect(err).To(BeNil()) + + By("Ensuring No Unregistered Component") + result, err = reconciler.ensureNoComponent(ctx, mch, "unknown", testImages) + Expect(result).To(Equal(ctrl.Result{RequeueAfter: resyncPeriod})) + Expect(err).To(BeNil()) }) }) diff --git a/hack/bundle-automation/config.yaml b/hack/bundle-automation/config.yaml index 91d6891e7c..b019d497d8 100644 --- a/hack/bundle-automation/config.yaml +++ b/hack/bundle-automation/config.yaml @@ -1,16 +1,4 @@ -- repo_name: search-v2-operator - github_ref: "https://github.com/stolostron/search-v2-operator.git" - branch: "release-2.9" - operators: - - name: search-v2-operator - bundlePath: "bundle/manifests/" - imageMappings: - search-v2-operator: search_v2_operator - kube-rbac-proxy: kube_rbac_proxy - postgresql-13: postgresql_13 - search-indexer: search_indexer - search-collector: search_collector - search-v2-api: search_v2_api + - repo_name: multicloud-operators-subscription github_ref: "https://github.com/stolostron/multicloud-operators-subscription.git" branch: "release-2.9" @@ -24,6 +12,7 @@ multicluster-operators-channel: multicluster_operators_channel exclusions: - readOnlyRootFilesystem + - repo_name: multicluster-observability-operator github_ref: "https://github.com/stolostron/multicluster-observability-operator.git" branch: "release-2.9" @@ -32,3 +21,26 @@ bundlePath: "operators/multiclusterobservability/bundle/manifests/" imageMappings: multicluster-observability-operator: multicluster_observability_operator + +- repo_name: search-v2-operator + github_ref: "https://github.com/stolostron/search-v2-operator.git" + branch: "release-2.9" + operators: + - name: search-v2-operator + bundlePath: "bundle/manifests/" + imageMappings: + search-v2-operator: search_v2_operator + kube-rbac-proxy: kube_rbac_proxy + postgresql-13: postgresql_13 + search-indexer: search_indexer + search-collector: search_collector + search-v2-api: search_v2_api + +- repo_name: submariner-addon + github_ref: "https://github.com/stolostron/submariner-addon.git" + branch: "release-2.9" + operators: + - name: submariner-addon + bundlePath: "deploy/olm-catalog/manifests/" + imageMappings: + submariner-addon: submariner_addon diff --git a/pkg/templates/charts/toggle/submariner-addon/Chart.yaml b/pkg/templates/charts/toggle/submariner-addon/Chart.yaml new file mode 100644 index 0000000000..1da548def3 --- /dev/null +++ b/pkg/templates/charts/toggle/submariner-addon/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +appVersion: 1.16.0 +description: A Helm chart for Kubernetes +name: submariner-addon +type: application +version: 2.3.0 diff --git a/pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon-clusterrole.yaml b/pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon-clusterrole.yaml new file mode 100644 index 0000000000..fd300e789e --- /dev/null +++ b/pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon-clusterrole.yaml @@ -0,0 +1,251 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: '{{ .Values.org }}:{{ .Chart.Name }}:submariner-addon' +rules: +- apiGroups: + - '' + resources: + - configmaps + verbs: + - create + - get + - list + - watch + - delete + - update +- apiGroups: + - '' + resources: + - pods + verbs: + - get +- apiGroups: + - apps + resources: + - replicasets + verbs: + - get +- apiGroups: + - '' + - events.k8s.io + resources: + - events + verbs: + - create + - patch + - update +- apiGroups: + - '' + resources: + - namespaces + - serviceaccounts + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - create + - get + - list + - watch + - update + - patch + - delete + - bind + - escalate +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - create + - get + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + - customresourcedefinitions/finalizers + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - submariner.io + resources: + - brokers + verbs: + - create + - get + - update + - delete +- apiGroups: + - '' + resources: + - secrets + verbs: + - create + - get + - list + - watch +- apiGroups: + - cluster.open-cluster-management.io + resources: + - managedclusters + - managedclustersets + verbs: + - get + - list + - watch + - update + - patch +- apiGroups: + - work.open-cluster-management.io + resources: + - manifestworks + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - config.openshift.io + resources: + - apiservers + - infrastructures + - infrastructures/status + verbs: + - get +- apiGroups: + - submarineraddon.open-cluster-management.io + resources: + - submarinerconfigs + verbs: + - get + - list + - watch + - update + - patch +- apiGroups: + - submarineraddon.open-cluster-management.io + resources: + - submarinerconfigs/status + verbs: + - update + - patch +- apiGroups: + - addon.open-cluster-management.io + resources: + - addondeploymentconfigs + verbs: + - get + - list + - watch +- apiGroups: + - addon.open-cluster-management.io + resources: + - clustermanagementaddons + verbs: + - create + - get + - list + - watch +- apiGroups: + - addon.open-cluster-management.io + resources: + - clustermanagementaddons/finalizers + verbs: + - update +- apiGroups: + - addon.open-cluster-management.io + resources: + - clustermanagementaddons/status + verbs: + - patch + - update +- apiGroups: + - addon.open-cluster-management.io + resources: + - managedclusteraddons + verbs: + - get + - list + - watch + - patch + - update + - delete +- apiGroups: + - addon.open-cluster-management.io + resources: + - managedclusteraddons/finalizers + verbs: + - update +- apiGroups: + - addon.open-cluster-management.io + resources: + - managedclusteraddons/status + verbs: + - patch + - update +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests + verbs: + - get + - list + - watch +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests/approval + verbs: + - update + - patch +- apiGroups: + - certificates.k8s.io + resourceNames: + - kubernetes.io/kube-apiserver-client + resources: + - signers + verbs: + - approve +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - delete diff --git a/pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon-clusterrolebinding.yaml b/pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon-clusterrolebinding.yaml new file mode 100644 index 0000000000..5ccb6dee2d --- /dev/null +++ b/pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon-clusterrolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: '{{ .Values.org }}:{{ .Chart.Name }}:submariner-addon' +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: '{{ .Values.org }}:{{ .Chart.Name }}:submariner-addon' +subjects: +- kind: ServiceAccount + name: submariner-addon + namespace: '{{ .Values.global.namespace }}' diff --git a/pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon-serviceaccount.yaml b/pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon-serviceaccount.yaml new file mode 100644 index 0000000000..4cb69bb249 --- /dev/null +++ b/pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon-serviceaccount.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: submariner-addon diff --git a/pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon.yaml b/pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon.yaml new file mode 100644 index 0000000000..397b603b9a --- /dev/null +++ b/pkg/templates/charts/toggle/submariner-addon/templates/submariner-addon.yaml @@ -0,0 +1,111 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: submariner-addon +spec: + replicas: 1 + selector: + matchLabels: + app: submariner-addon + strategy: {} + template: + metadata: + labels: + app: submariner-addon + ocm-antiaffinity-selector: submariner-addon + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: ocm-antiaffinity-selector + operator: In + values: + - submariner-addon + topologyKey: topology.kubernetes.io/zone + weight: 70 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: ocm-antiaffinity-selector + operator: In + values: + - submariner-addon + topologyKey: kubernetes.io/hostname + weight: 35 + containers: + - args: + - /submariner + - controller + env: +{{- if .Values.hubconfig.proxyConfigs }} + - name: HTTP_PROXY + value: {{ .Values.hubconfig.proxyConfigs.HTTP_PROXY }} + - name: HTTPS_PROXY + value: {{ .Values.hubconfig.proxyConfigs.HTTPS_PROXY }} + - name: NO_PROXY + value: {{ .Values.hubconfig.proxyConfigs.NO_PROXY }} +{{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + image: '{{ .Values.global.imageOverrides.submariner_addon }}' + imagePullPolicy: '{{ .Values.global.pullPolicy }}' + livenessProbe: + httpGet: + path: /healthz + port: 8443 + scheme: HTTPS + initialDelaySeconds: 2 + periodSeconds: 10 + name: submariner-addon + readinessProbe: + httpGet: + path: /healthz + port: 8443 + scheme: HTTPS + initialDelaySeconds: 2 + resources: + limits: + memory: 270Mi + requests: + cpu: 100m + memory: 128Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + hostIPC: false + hostNetwork: false + hostPID: false +{{- if .Values.global.pullSecret }} + imagePullSecrets: + - name: {{ .Values.global.pullSecret }} +{{- end }} +{{- with .Values.hubconfig.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} +{{- end }} + securityContext: + runAsNonRoot: true +{{- if semverCompare ">=4.11.0" .Values.hubconfig.ocpVersion }} + seccompProfile: + type: RuntimeDefault +{{- end }} + serviceAccountName: submariner-addon +{{- with .Values.hubconfig.tolerations }} + tolerations: + {{- range . }} + - {{ if .Key }} key: {{ .Key }} {{- end }} + {{ if .Operator }} operator: {{ .Operator }} {{- end }} + {{ if .Value }} value: {{ .Value }} {{- end }} + {{ if .Effect }} effect: {{ .Effect }} {{- end }} + {{ if .TolerationSeconds }} tolerationSeconds: {{ .TolerationSeconds }} {{- end }} + {{- end }} +{{- end }} diff --git a/pkg/templates/charts/toggle/submariner-addon/values.yaml b/pkg/templates/charts/toggle/submariner-addon/values.yaml new file mode 100644 index 0000000000..a32b87475c --- /dev/null +++ b/pkg/templates/charts/toggle/submariner-addon/values.yaml @@ -0,0 +1,11 @@ +global: + imageOverrides: + submariner_addon: '' + namespace: default + pullSecret: null +hubconfig: + nodeSelector: null + proxyConfigs: {} + replicaCount: 1 + tolerations: [] +org: open-cluster-management diff --git a/pkg/templates/crds/submariner-addon/submarineraddon.open-cluster-management.io_submarinerconfigs.yaml b/pkg/templates/crds/submariner-addon/submarineraddon.open-cluster-management.io_submarinerconfigs.yaml new file mode 100644 index 0000000000..04cefb6e78 --- /dev/null +++ b/pkg/templates/crds/submariner-addon/submarineraddon.open-cluster-management.io_submarinerconfigs.yaml @@ -0,0 +1,256 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: submarinerconfigs.submarineraddon.open-cluster-management.io +spec: + group: submarineraddon.open-cluster-management.io + names: + kind: SubmarinerConfig + listKind: SubmarinerConfigList + plural: submarinerconfigs + singular: submarinerconfig + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: SubmarinerConfig represents the configuration for Submariner, the submariner-addon will use it to configure the Submariner. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the configuration of the Submariner + properties: + Debug: + default: false + description: Debug enables Submariner debugging (in the logs). + type: boolean + IPSecDebug: + default: false + description: IPSecDebug enables IPSec debugging. + type: boolean + IPSecIKEPort: + default: 500 + description: IPSecIKEPort represents IPsec IKE port (default 500). + type: integer + IPSecNATTPort: + default: 4500 + description: IPSecNATTPort represents IPsec NAT-T port (default 4500). + type: integer + NATTDiscoveryPort: + default: 4900 + description: NATTDiscoveryPort specifies the port used for NAT-T Discovery (default UDP/4900). + type: integer + NATTEnable: + default: true + description: NATTEnable represents IPsec NAT-T enabled (default true). + type: boolean + airGappedDeployment: + default: false + description: AirGappedDeployment specifies that the cluster is in an air-gapped environment without access to external servers. + type: boolean + cableDriver: + default: libreswan + description: CableDriver represents the submariner cable driver implementation. Available options are libreswan (default) strongswan, wireguard, and vxlan. + type: string + credentialsSecret: + description: CredentialsSecret is a reference to the secret with a certain cloud platform credentials, the supported platform includes AWS, GCP, Azure, ROKS and OSD. The submariner-addon will use these credentials to prepare Submariner cluster environment. If the submariner cluster environment requires submariner-addon preparation, this field should be specified. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + gatewayConfig: + description: GatewayConfig represents the gateways configuration of the Submariner. + properties: + aws: + description: AWS represents the configuration for Amazon Web Services. If the platform of managed cluster is not Amazon Web Services, this field will be ignored. + properties: + instanceType: + default: m5n.large + description: InstanceType represents the Amazon Web Services EC2 instance type of the gateway node that will be created on the managed cluster. The default value is `m5n.large`. + type: string + type: object + azure: + description: Azure represents the configuration for Azure Cloud Platform. If the platform of managed cluster is not Azure Cloud Platform, this field will be ignored. + properties: + instanceType: + default: Standard_F4s_v2 + description: InstanceType represents the Azure Cloud Platform instance type of the gateway node that will be created on the managed cluster. The default value is `Standard_F4s_v2`. + type: string + type: object + gateways: + default: 1 + description: Gateways represents the count of worker nodes that will be used to deploy the Submariner gateway component on the managed cluster. The default value is 1, if the value is greater than 1, the Submariner gateway HA will be enabled automatically. + type: integer + gcp: + description: GCP represents the configuration for Google Cloud Platform. If the platform of managed cluster is not Google Cloud Platform, this field will be ignored. + properties: + instanceType: + default: n1-standard-4 + description: InstanceType represents the Google Cloud Platform instance type of the gateway node that will be created on the managed cluster. The default value is `n1-standard-4`. + type: string + type: object + rhos: + description: RHOS represents the configuration for Redhat Openstack Platform. If the platform of managed cluster is not Redhat Openstack Platform, this field will be ignored. + properties: + instanceType: + default: PnTAE.CPU_4_Memory_8192_Disk_50 + description: InstanceType represents the Redhat Openstack instance type of the gateway node that will be created on the managed cluster. The default value is `PnTAE.CPU_4_Memory_8192_Disk_50`. + type: string + type: object + type: object + globalCIDR: + description: GlobalCIDR specifies the global CIDR used by the cluster. + type: string + imagePullSpecs: + description: ImagePullSpecs represents the desired images of submariner components installed on the managed cluster. If not specified, the default submariner images that was defined by submariner operator will be used. + properties: + lighthouseAgentImagePullSpec: + description: LighthouseAgentImagePullSpec represents the desired image of the lighthouse agent. + type: string + lighthouseCoreDNSImagePullSpec: + description: LighthouseCoreDNSImagePullSpec represents the desired image of lighthouse coredns. + type: string + metricsProxyImagePullSpec: + description: MetricsProxyImagePullSpec represents the desired image of the metrics proxy. + type: string + nettestImagePullSpec: + description: NettestImagePullSpec represents the desired image of nettest. + type: string + submarinerGlobalnetImagePullSpec: + description: SubmarinerGlobalnetImagePullSpec represents the desired image of the submariner globalnet. + type: string + submarinerImagePullSpec: + description: SubmarinerImagePullSpec represents the desired image of submariner. + type: string + submarinerNetworkPluginSyncerImagePullSpec: + description: 'SubmarinerNetworkPluginSyncerImagePullSpec represents the desired image of the submariner networkplugin syncer. Deprecated: The networkplugin syncer was removed in v0.16.0.' + type: string + submarinerRouteAgentImagePullSpec: + description: SubmarinerRouteAgentImagePullSpec represents the desired image of the submariner route agent. + type: string + type: object + insecureBrokerConnection: + default: false + description: InsecureBrokerConnection disables certificate validation when contacting the broker. This is useful for scenarios where the certificate chain isn't the same everywhere, e.g. with self-signed certificates with a different trust chain in each cluster. + type: boolean + loadBalancerEnable: + default: false + description: LoadBalancerEnable enables or disables load balancer mode. When enabled, a LoadBalancer is created in the submariner-operator namespace (default false). + type: boolean + subscriptionConfig: + description: SubscriptionConfig represents a Submariner subscription. SubscriptionConfig can be used to customize the Submariner subscription. + properties: + channel: + description: Channel represents the channel of a submariner subscription. + type: string + installPlanApproval: + description: InstallPlanApproval determines whether subscription installation plans are applied automatically. + type: string + source: + default: redhat-operators + description: Source represents the catalog source of a submariner subscription. The default value is redhat-operators + type: string + sourceNamespace: + default: openshift-marketplace + description: SourceNamespace represents the catalog source namespace of a submariner subscription. The default value is openshift-marketplace + type: string + startingCSV: + description: StartingCSV represents the startingCSV of a submariner subscription. + type: string + type: object + type: object + status: + description: Status represents the current status of submariner configuration + properties: + conditions: + description: Conditions contain the different condition statuses for this configuration. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + managedClusterInfo: + description: ManagedClusterInfo represents the information of a managed cluster. + properties: + clusterName: + description: ClusterName represents the name of the managed cluster. + type: string + infraId: + description: InfraId represents the infrastructure id of the managed cluster. + type: string + networkType: + description: NetworkType represents the network type (cni) of the managed cluster. + type: string + platform: + description: Platform represents the cloud provider of the managed cluster. + type: string + region: + description: Region represents the cloud region of the managed cluster. + type: string + vendor: + description: Vendor represents the kubernetes vendor of the managed cluster. + type: string + vendorVersion: + description: VendorVersion represents k8s vendor version of the managed cluster. + type: string + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/pkg/templates/crds/submariner-addon/submarineraddon.open-cluster-management.io_submarinerdiagnoseconfigs.yaml b/pkg/templates/crds/submariner-addon/submarineraddon.open-cluster-management.io_submarinerdiagnoseconfigs.yaml new file mode 100644 index 0000000000..f3cb000e79 --- /dev/null +++ b/pkg/templates/crds/submariner-addon/submarineraddon.open-cluster-management.io_submarinerdiagnoseconfigs.yaml @@ -0,0 +1,143 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: submarinerdiagnoseconfigs.submarineraddon.open-cluster-management.io +spec: + group: submarineraddon.open-cluster-management.io + names: + kind: SubmarinerDiagnoseConfig + listKind: SubmarinerDiagnoseConfigList + plural: submarinerdiagnoseconfigs + singular: submarinerdiagnoseconfig + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: SubmarinerDiagnoseConfig represents the configuration to run SubmarinerDiagnose Job. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the configuration of the Submariner + properties: + CNI: + type: boolean + all: + type: boolean + connections: + type: boolean + deployment: + type: boolean + firewall: + type: boolean + firewallOptions: + properties: + interCluster: + type: boolean + intraCluster: + type: boolean + metrics: + type: boolean + remoteCluster: + type: string + remoteK8sAPIServer: + type: string + remoteK8sAPIServerToken: + type: string + remoteK8sCA: + type: string + remoteK8sRemoteNamespace: + type: string + remoteK8sSecret: + type: string + type: object + gatherLogs: + type: boolean + k8sVersion: + type: boolean + kubeProxyMode: + type: boolean + type: object + status: + description: Status represents the current status of SubmarinerDiagnose + properties: + cniType: + type: string + conditions: + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + firewallStatus: + properties: + IPSecTunnel: + type: string + metricsStatus: + type: string + vxlanTunnel: + type: string + type: object + k8sVersion: + type: string + kubeProxyMode: + type: boolean + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 362a5104e8..7796a41e2b 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -48,17 +48,19 @@ const ( MCESubscriptionNamespace = "multicluster-engine" ClusterSubscriptionNamespace = "open-cluster-management-backup" - MCEManagedByLabel = "multiclusterhubs.operator.open-cluster-management.io/managed-by" - InsightsChartLocation = "/charts/toggle/insights" + MCEManagedByLabel = "multiclusterhubs.operator.open-cluster-management.io/managed-by" + AppsubChartLocation = "/charts/toggle/multicloud-operators-subscription" - SearchV2ChartLocation = "/charts/toggle/search-v2-operator" CLCChartLocation = "/charts/toggle/cluster-lifecycle" ClusterBackupChartLocation = "/charts/toggle/cluster-backup" - GRCChartLocation = "/charts/toggle/grc" - ConsoleChartLocation = "/charts/toggle/console" - VolsyncChartLocation = "/charts/toggle/volsync-controller" ClusterPermissionChartLocation = "/charts/toggle/cluster-permission" + ConsoleChartLocation = "/charts/toggle/console" + GRCChartLocation = "/charts/toggle/grc" + InsightsChartLocation = "/charts/toggle/insights" MCOChartLocation = "/charts/toggle/multicluster-observability-operator" + SearchV2ChartLocation = "/charts/toggle/search-v2-operator" + SubmarinerAddonChartLocation = "/charts/toggle/submariner-addon" + VolsyncChartLocation = "/charts/toggle/volsync-controller" ) var ( @@ -271,7 +273,8 @@ func IsUnitTest() bool { } func GetTestImages() []string { - return []string{"LIFECYCLE_BACKEND_E2E", "BAILER", "CERT_POLICY_CONTROLLER", "CLUSTER_BACKUP_CONTROLLER", + return []string{ + "LIFECYCLE_BACKEND_E2E", "BAILER", "CERT_POLICY_CONTROLLER", "CLUSTER_BACKUP_CONTROLLER", "CLUSTER_LIFECYCLE_E2E", "CLUSTER_PROXY", "CLUSTER_PROXY_ADDON", "CONSOLE", "ENDPOINT_MONITORING_OPERATOR", "GRAFANA", "GRAFANA_DASHBOARD_LOADER", "GRC_POLICY_FRAMEWORK_TESTS", "HELLOPROW_GO", "HELLOWORLD", "HYPERSHIFT_DEPLOYMENT_CONTROLLER", "IAM_POLICY_CONTROLLER", "INSIGHTS_CLIENT", "INSIGHTS_METRICS", @@ -289,8 +292,9 @@ func GetTestImages() []string { "governance_policy_propagator", "governance_policy_addon_controller", "cert_policy_controller", "iam_policy_controller", "config_policy_controller", "governance_policy_framework_addon", "cluster_backup_controller", "console", "volsync_addon_controller", "multicluster_operators_application", - "multicloud_integrations", "multicluster_operators_channel", "multicluster_operators_subscription", "multicluster_observability_operator", "cluster_permission"} - + "multicloud_integrations", "multicluster_operators_channel", "multicluster_operators_subscription", + "multicluster_observability_operator", "cluster_permission", "submariner_addon", + } } // FormatSSLCiphers converts an array of ciphers into a string consumed by the management