You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ts...@apache.org on 2022/12/15 01:17:54 UTC

[camel-k] 01/02: fix(cmd): refactor install cmd to remove maintidx lint

This is an automated email from the ASF dual-hosted git repository.

tsato pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 72eb49181a2ad984a4fbcc50393d837faf504606
Author: Tadayoshi Sato <sa...@gmail.com>
AuthorDate: Wed Dec 14 17:25:31 2022 +0900

    fix(cmd): refactor install cmd to remove maintidx lint
---
 pkg/cmd/install.go        | 609 +++++++++++++++++++++++++---------------------
 pkg/install/cluster.go    |  55 +++--
 pkg/install/operator.go   |   8 +-
 pkg/util/olm/available.go |   2 +-
 4 files changed, 369 insertions(+), 305 deletions(-)

diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go
index fccea5ba8..002e53d45 100644
--- a/pkg/cmd/install.go
+++ b/pkg/cmd/install.go
@@ -215,16 +215,53 @@ type installCmdOptions struct {
 	olmOptions olm.Options
 }
 
-// nolint: gocyclo,maintidx // TODO: refactor the code
-func (o *installCmdOptions) install(cobraCmd *cobra.Command, _ []string) error {
-	var collection *kubernetes.Collection
+func (o *installCmdOptions) install(cmd *cobra.Command, _ []string) error {
+	var output *kubernetes.Collection
 	if o.OutputFormat != "" {
-		collection = kubernetes.NewCollection()
+		output = kubernetes.NewCollection()
 	}
 
 	// Let's use a client provider during cluster installation, to eliminate the problem of CRD object caching
 	clientProvider := client.Provider{Get: o.NewCmdClient}
 
+	o.setupEnvVars()
+
+	installViaOLM := false
+	if o.Olm {
+		installed, err := o.tryInstallViaOLM(cmd, clientProvider, output)
+		if err != nil {
+			return err
+		}
+		installViaOLM = installed
+	}
+
+	if !o.SkipClusterSetup && !installViaOLM {
+		if err := install.SetupClusterWideResourcesOrCollect(o.Context, clientProvider,
+			output, o.ClusterType, o.Force); err != nil {
+			if k8serrors.IsForbidden(err) {
+				fmt.Fprintln(cmd.OutOrStdout(),
+					"Current user is not authorized to create cluster-wide objects like custom resource definitions or cluster roles:",
+					err)
+				msg := `please login as cluster-admin and execute "kamel install --cluster-setup" to install cluster-wide resources (one-time operation)`
+				return errors.New(msg)
+			}
+			return err
+		}
+	}
+
+	if o.ClusterSetupOnly {
+		if output != nil {
+			return o.printOutput(cmd, output)
+		}
+		fmt.Fprintln(cmd.OutOrStdout(), "Camel K cluster setup completed successfully")
+		return nil
+	}
+
+	return o.installOperator(cmd, output, installViaOLM)
+}
+
+// setupEnvVars sets up additional env vars from the command options.
+func (o *installCmdOptions) setupEnvVars() {
 	// --operator-id={id} is a syntax sugar for '--operator-env-vars KAMEL_OPERATOR_ID={id}'
 	o.EnvVars = append(o.EnvVars, fmt.Sprintf("KAMEL_OPERATOR_ID=%s", strings.TrimSpace(o.OperatorID)))
 
@@ -237,347 +274,342 @@ func (o *installCmdOptions) install(cobraCmd *cobra.Command, _ []string) error {
 	if len(o.LogLevel) > 0 {
 		o.EnvVars = append(o.EnvVars, fmt.Sprintf("LOG_LEVEL=%s", strings.TrimSpace(o.LogLevel)))
 	}
+}
 
-	installViaOLM := false
-	if o.Olm {
-		var err error
-		var olmClient client.Client
-		if olmClient, err = clientProvider.Get(); err != nil {
-			return err
-		}
-		var olmAvailable bool
-		if olmAvailable, err = olm.IsAPIAvailable(o.Context, olmClient, o.Namespace); err != nil {
-			return errors.Wrap(err, "error while checking OLM availability. Run with '--olm=false' to skip this check")
-		}
-		if olmAvailable {
-			if installViaOLM, err = olm.HasPermissionToInstall(o.Context, olmClient, o.Namespace, o.Global, o.olmOptions); err != nil {
-				return errors.Wrap(err, "error while checking permissions to install operator via OLM. Run with '--olm=false' to skip this check")
-			}
-			if !installViaOLM {
-				fmt.Fprintln(cobraCmd.OutOrStdout(), "OLM is available but current user has not enough permissions to create the operator. "+
-					"You can either ask your administrator to provide permissions (preferred) or run the install command with the `--olm=false` flag.")
-				os.Exit(1)
-			}
-		} else {
-			fmt.Fprintln(cobraCmd.OutOrStdout(), "OLM is not available in the cluster. Fallback to regular installation.")
-		}
+func (o *installCmdOptions) tryInstallViaOLM(
+	cmd *cobra.Command, clientProvider client.Provider, output *kubernetes.Collection,
+) (bool, error) {
+	olmClient, err := clientProvider.Get()
+	if err != nil {
+		return false, err
+	}
+	if olmAvailable, err := olm.IsAPIAvailable(o.Context, olmClient, o.Namespace); err != nil {
+		return false, errors.Wrap(err,
+			"error while checking OLM availability. Run with '--olm=false' to skip this check")
+	} else if !olmAvailable {
+		fmt.Fprintln(cmd.OutOrStdout(), "OLM is not available in the cluster. Fallback to regular installation.")
+		return false, nil
+	}
 
-		if installViaOLM {
-			fmt.Fprintln(cobraCmd.OutOrStdout(), "OLM is available in the cluster")
-			var installed bool
-			if installed, err = olm.Install(o.Context, olmClient, o.Namespace, o.Global, o.olmOptions, collection,
-				o.Tolerations, o.NodeSelectors, o.ResourcesRequirements, o.EnvVars); err != nil {
-				return err
-			}
-			if !installed {
-				fmt.Fprintln(cobraCmd.OutOrStdout(), "OLM resources are already available: skipping installation")
-			}
+	if hasPermission, err := olm.HasPermissionToInstall(o.Context, olmClient,
+		o.Namespace, o.Global, o.olmOptions); err != nil {
+		return false, errors.Wrap(err,
+			"error while checking permissions to install operator via OLM. Run with '--olm=false' to skip this check")
+	} else if !hasPermission {
+		return false, errors.New(
+			"OLM is available but current user has not enough permissions to create the operator. " +
+				"You can either ask your administrator to provide permissions (preferred) " +
+				"or run the install command with the '--olm=false' flag.")
+	}
 
-			if err = install.WaitForAllCrdInstallation(o.Context, clientProvider, 90*time.Second); err != nil {
-				return err
-			}
-		}
+	// Install or collect via OLM
+	fmt.Fprintln(cmd.OutOrStdout(), "OLM is available in the cluster")
+	if installed, err := olm.Install(o.Context, olmClient, o.Namespace, o.Global, o.olmOptions, output,
+		o.Tolerations, o.NodeSelectors, o.ResourcesRequirements, o.EnvVars); err != nil {
+		return false, err
+	} else if !installed {
+		fmt.Fprintln(cmd.OutOrStdout(), "OLM resources are already available; skipping installation")
 	}
 
-	if !o.SkipClusterSetup && !installViaOLM {
-		err := install.SetupClusterWideResourcesOrCollect(o.Context, clientProvider, collection, o.ClusterType, o.Force)
-		if err != nil && k8serrors.IsForbidden(err) {
-			fmt.Fprintln(cobraCmd.OutOrStdout(), "Current user is not authorized to create cluster-wide objects like custom resource definitions or cluster roles: ", err)
+	if err := install.WaitForAllCrdInstallation(o.Context, clientProvider, 90*time.Second); err != nil {
+		return false, err
+	}
 
-			meg := `please login as cluster-admin and execute "kamel install --cluster-setup" to install cluster-wide resources (one-time operation)`
-			return errors.New(meg)
-		} else if err != nil {
-			return err
-		}
+	return true, nil
+}
+
+func (o *installCmdOptions) installOperator(cmd *cobra.Command, output *kubernetes.Collection, olm bool) error {
+	operatorID, err := getOperatorID(o.EnvVars)
+	if err != nil {
+		return err
 	}
 
-	if o.ClusterSetupOnly {
-		if collection == nil {
-			fmt.Fprintln(cobraCmd.OutOrStdout(), "Camel K cluster setup completed successfully")
-		}
+	c, err := o.GetCmdClient()
+	if err != nil {
+		return err
+	}
+
+	namespace := o.Namespace
+
+	var platformName string
+	if operatorID != "" {
+		platformName = operatorID
 	} else {
-		operatorID, err := getOperatorID(o.EnvVars)
-		if err != nil {
-			return err
+		platformName = platformutil.DefaultPlatformName
+	}
+
+	// Set up operator
+	if !olm {
+		if !o.SkipOperatorSetup {
+			if err := o.setupOperator(cmd, c, namespace, platformName, output); err != nil {
+				return err
+			}
+		} else {
+			fmt.Fprintln(cmd.OutOrStdout(), "Camel K operator installation skipped")
 		}
+	}
 
-		c, err := o.GetCmdClient()
+	// Set up registry secret
+	registrySecretName := ""
+	if !o.SkipRegistrySetup {
+		registrySecretName, err = o.setupRegistrySecret(c, namespace, output)
 		if err != nil {
 			return err
 		}
+	} else {
+		fmt.Fprintln(cmd.OutOrStdout(), "Camel K operator registry setup skipped")
+	}
 
-		namespace := o.Namespace
-
-		var platformName string
-		if operatorID != "" {
-			platformName = operatorID
-		} else {
-			platformName = platformutil.DefaultPlatformName
-		}
+	// Set up IntegrationPlatform
+	platform, err := o.setupIntegrationPlatform(cmd, c, namespace, platformName, registrySecretName, output)
+	if err != nil {
+		return err
+	}
 
-		if !o.SkipOperatorSetup && !installViaOLM {
-			if ok, err := isInstallAllowed(o.Context, c, platformName, o.Force, cobraCmd.OutOrStdout()); err != nil {
-				if k8serrors.IsForbidden(err) {
-					o.PrintfVerboseOutf(cobraCmd, "Unable to verify existence of operator id [%s] due to lack of user privileges\n", platformName)
-				} else {
-					return err
-				}
-			} else if !ok {
-				return fmt.Errorf("installation not allowed because operator with id '%s' already exists, use the --force option to skip this check", platformName)
-			}
+	if output != nil {
+		return o.printOutput(cmd, output)
+	}
 
-			cfg := install.OperatorConfiguration{
-				CustomImage:           o.OperatorImage,
-				CustomImagePullPolicy: o.OperatorImagePullPolicy,
-				Namespace:             namespace,
-				Global:                o.Global,
-				ClusterType:           o.ClusterType,
-				Health: install.OperatorHealthConfiguration{
-					Port: o.HealthPort,
-				},
-				Monitoring: install.OperatorMonitoringConfiguration{
-					Enabled: o.Monitoring,
-					Port:    o.MonitoringPort,
-				},
-				Tolerations:           o.Tolerations,
-				NodeSelectors:         o.NodeSelectors,
-				ResourcesRequirements: o.ResourcesRequirements,
-				EnvVars:               o.EnvVars,
-			}
-			err = install.OperatorOrCollect(o.Context, cobraCmd, c, cfg, collection, o.Force)
-			if err != nil {
-				return err
-			}
-		} else if o.SkipOperatorSetup {
-			fmt.Fprintln(cobraCmd.OutOrStdout(), "Camel K operator installation skipped")
+	if o.Wait {
+		if err := o.waitForPlatformReady(cmd, platform); err != nil {
+			return err
 		}
+	}
 
-		generatedSecretName := ""
+	strategy := ""
+	if olm {
+		strategy = "via OLM subscription"
+	}
+	if o.Global {
+		fmt.Fprintln(cmd.OutOrStdout(), "Camel K installed in namespace", namespace, strategy, "(global mode)")
+	} else {
+		fmt.Fprintln(cmd.OutOrStdout(), "Camel K installed in namespace", namespace, strategy)
+	}
 
-		if !o.SkipRegistrySetup {
-			if o.registryAuth.IsSet() {
-				regData := o.registryAuth
-				regData.Registry = o.registry.Address
-				generatedSecretName, err = install.RegistrySecretOrCollect(o.Context, c, namespace, regData, collection, o.Force)
-				if err != nil {
-					return err
-				}
-			} else if o.RegistryAuthFile != "" {
-				generatedSecretName, err = install.RegistrySecretFromFileOrCollect(o.Context, c, namespace, o.RegistryAuthFile, collection, o.Force)
-				if err != nil {
-					return err
-				}
-			}
-		} else if o.SkipRegistrySetup {
-			fmt.Fprintln(cobraCmd.OutOrStdout(), "Camel K operator registry setup skipped")
+	return nil
+}
+
+func getOperatorID(vars []string) (string, error) {
+	envs, _, _, err := env.ParseEnv(vars, nil)
+	if err != nil {
+		return "", err
+	}
+	for _, e := range envs {
+		if e.Name == "KAMEL_OPERATOR_ID" {
+			return e.Value, nil
 		}
+	}
 
-		platform, err := install.NewPlatform(o.Context, c, o.ClusterType, o.SkipRegistrySetup, o.registry, platformName)
-		if err != nil {
+	return "", nil
+}
+
+func (o *installCmdOptions) setupOperator(
+	cmd *cobra.Command, c client.Client, namespace string, platformName string, output *kubernetes.Collection,
+) error {
+	if ok, err := isInstallAllowed(o.Context, c, platformName, o.Force, cmd.OutOrStdout()); err != nil {
+		if k8serrors.IsForbidden(err) {
+			o.PrintfVerboseOutf(cmd,
+				"Unable to verify existence of operator id %q due to lack of user privileges\n",
+				platformName)
+		} else {
 			return err
 		}
+	} else if !ok {
+		return fmt.Errorf(
+			"installation not allowed because operator with id %q already exists; use the --force option to skip this check",
+			platformName)
+	}
 
-		if generatedSecretName != "" {
-			platform.Spec.Build.Registry.Secret = generatedSecretName
-		}
+	cfg := install.OperatorConfiguration{
+		CustomImage:           o.OperatorImage,
+		CustomImagePullPolicy: o.OperatorImagePullPolicy,
+		Namespace:             namespace,
+		Global:                o.Global,
+		ClusterType:           o.ClusterType,
+		Health: install.OperatorHealthConfiguration{
+			Port: o.HealthPort,
+		},
+		Monitoring: install.OperatorMonitoringConfiguration{
+			Enabled: o.Monitoring,
+			Port:    o.MonitoringPort,
+		},
+		Tolerations:           o.Tolerations,
+		NodeSelectors:         o.NodeSelectors,
+		ResourcesRequirements: o.ResourcesRequirements,
+		EnvVars:               o.EnvVars,
+	}
 
-		if len(o.MavenProperties) > 0 {
-			platform.Spec.Build.Maven.Properties = make(map[string]string)
-			for _, property := range o.MavenProperties {
-				kv := strings.Split(property, "=")
-				if len(kv) == 2 {
-					platform.Spec.Build.Maven.Properties[kv[0]] = kv[1]
-				}
-			}
-		}
+	return install.OperatorOrCollect(o.Context, cmd, c, cfg, output, o.Force)
+}
 
-		if size := len(o.MavenExtensions); size > 0 {
-			platform.Spec.Build.Maven.Extension = make([]v1.MavenArtifact, 0, size)
-			for _, extension := range o.MavenExtensions {
-				gav := strings.Split(extension, ":")
-				if len(gav) != 2 && len(gav) != 3 {
-					meg := fmt.Sprintf("Maven build extension GAV must match <groupId>:<artifactId>:<version>, found: %s", extension)
-					return errors.New(meg)
-				}
-				ext := v1.MavenArtifact{
-					GroupID:    gav[0],
-					ArtifactID: gav[1],
-				}
-				if len(gav) == 3 {
-					ext.Version = gav[2]
-				}
-				platform.Spec.Build.Maven.Extension = append(platform.Spec.Build.Maven.Extension, ext)
-			}
-		}
+func isInstallAllowed(ctx context.Context, c client.Client, operatorID string, force bool, out io.Writer) (bool, error) {
+	// find existing platform with given name in any namespace
+	pl, err := platformutil.LookupForPlatformName(ctx, c, operatorID)
 
-		if o.MavenLocalRepository != "" {
-			platform.Spec.Build.Maven.LocalRepository = o.MavenLocalRepository
-		}
+	if pl != nil && force {
+		fmt.Fprintf(out, "Overwriting existing operator with id %q\n", operatorID)
+		return true, nil
+	}
 
-		if len(o.MavenCLIOptions) > 0 {
-			platform.Spec.Build.Maven.CLIOptions = o.MavenCLIOptions
-		}
+	// only allow installation when platform with given name is not found
+	return pl == nil, err
+}
 
-		if o.RuntimeVersion != "" {
-			platform.Spec.Build.RuntimeVersion = o.RuntimeVersion
-		}
-		if o.BaseImage != "" {
-			platform.Spec.Build.BaseImage = o.BaseImage
-		}
-		if o.BuildStrategy != "" {
-			platform.Spec.Build.BuildStrategy = v1.BuildStrategy(o.BuildStrategy)
-		}
-		if o.BuildPublishStrategy != "" {
-			platform.Spec.Build.PublishStrategy = v1.IntegrationPlatformBuildPublishStrategy(o.BuildPublishStrategy)
-		}
-		if o.BuildTimeout != "" {
-			d, err := time.ParseDuration(o.BuildTimeout)
-			if err != nil {
-				return err
-			}
+func (o *installCmdOptions) setupRegistrySecret(c client.Client, namespace string, output *kubernetes.Collection) (string, error) {
+	if o.registryAuth.IsSet() {
+		regData := o.registryAuth
+		regData.Registry = o.registry.Address
+		return install.RegistrySecretOrCollect(o.Context, c, namespace, regData, output, o.Force)
+	} else if o.RegistryAuthFile != "" {
+		return install.RegistrySecretFromFileOrCollect(o.Context, c, namespace, o.RegistryAuthFile, output, o.Force)
+	}
+
+	return "", nil
+}
+
+func (o *installCmdOptions) setupIntegrationPlatform(
+	cmd *cobra.Command, c client.Client, namespace string, platformName string, registrySecretName string,
+	output *kubernetes.Collection,
+) (*v1.IntegrationPlatform, error) {
+	platform, err := install.NewPlatform(o.Context, c, o.ClusterType, o.SkipRegistrySetup, o.registry, platformName)
+	if err != nil {
+		return nil, err
+	}
+
+	if registrySecretName != "" {
+		platform.Spec.Build.Registry.Secret = registrySecretName
+	}
 
-			platform.Spec.Build.Timeout = &metav1.Duration{
-				Duration: d,
+	if len(o.MavenProperties) > 0 {
+		platform.Spec.Build.Maven.Properties = make(map[string]string)
+		for _, property := range o.MavenProperties {
+			kv := strings.Split(property, "=")
+			if len(kv) == 2 {
+				platform.Spec.Build.Maven.Properties[kv[0]] = kv[1]
 			}
 		}
-		if o.TraitProfile != "" {
-			platform.Spec.Profile = v1.TraitProfileByName(o.TraitProfile)
-		}
-
-		if len(o.MavenRepositories) > 0 {
-			settings, err := maven.NewSettings(maven.Repositories(o.MavenRepositories...), maven.DefaultRepositories)
+	}
 
-			if err != nil {
-				return err
+	if size := len(o.MavenExtensions); size > 0 {
+		platform.Spec.Build.Maven.Extension = make([]v1.MavenArtifact, 0, size)
+		for _, extension := range o.MavenExtensions {
+			gav := strings.Split(extension, ":")
+			if len(gav) != 2 && len(gav) != 3 {
+				msg := fmt.Sprintf("Maven build extension GAV must match <groupId>:<artifactId>:<version>, found: %s", extension)
+				return nil, errors.New(msg)
 			}
-			err = createDefaultMavenSettingsConfigMap(o.Context, c, namespace, platform.Name, settings)
-			if err != nil {
-				return err
+			ext := v1.MavenArtifact{
+				GroupID:    gav[0],
+				ArtifactID: gav[1],
 			}
-			platform.Spec.Build.Maven.Settings.ConfigMapKeyRef = &corev1.ConfigMapKeySelector{
-				LocalObjectReference: corev1.LocalObjectReference{
-					Name: platform.Name + "-maven-settings",
-				},
-				Key: "settings.xml",
+			if len(gav) == 3 {
+				ext.Version = gav[2]
 			}
+			platform.Spec.Build.Maven.Extension = append(platform.Spec.Build.Maven.Extension, ext)
 		}
+	}
 
-		if o.MavenSettings != "" {
-			mavenSettings, err := decodeMavenSettings(o.MavenSettings)
-			if err != nil {
-				return err
-			}
-			platform.Spec.Build.Maven.Settings = mavenSettings
-		}
+	if o.MavenLocalRepository != "" {
+		platform.Spec.Build.Maven.LocalRepository = o.MavenLocalRepository
+	}
 
-		if o.MavenCASecret != "" {
-			secret, err := decodeSecretKeySelector(o.MavenCASecret)
-			if err != nil {
-				return err
-			}
-			platform.Spec.Build.Maven.CASecrets = append(platform.Spec.Build.Maven.CASecrets, *secret)
-		}
+	if len(o.MavenCLIOptions) > 0 {
+		platform.Spec.Build.Maven.CLIOptions = o.MavenCLIOptions
+	}
 
-		if o.ClusterType != "" {
-			for _, c := range v1.AllIntegrationPlatformClusters {
-				if strings.EqualFold(string(c), o.ClusterType) {
-					platform.Spec.Cluster = c
-				}
-			}
+	if o.RuntimeVersion != "" {
+		platform.Spec.Build.RuntimeVersion = o.RuntimeVersion
+	}
+	if o.BaseImage != "" {
+		platform.Spec.Build.BaseImage = o.BaseImage
+	}
+	if o.BuildStrategy != "" {
+		platform.Spec.Build.BuildStrategy = v1.BuildStrategy(o.BuildStrategy)
+	}
+	if o.BuildPublishStrategy != "" {
+		platform.Spec.Build.PublishStrategy = v1.IntegrationPlatformBuildPublishStrategy(o.BuildPublishStrategy)
+	}
+	if o.BuildTimeout != "" {
+		d, err := time.ParseDuration(o.BuildTimeout)
+		if err != nil {
+			return nil, err
 		}
-		if platform.Spec.Build.PublishStrategy == v1.IntegrationPlatformBuildPublishStrategyKaniko && cobraCmd.Flags().Lookup("kaniko-build-cache").Changed {
-			fmt.Fprintln(cobraCmd.OutOrStdout(), "Warn: the flag --kaniko-build-cache is deprecated, use --build-publish-strategy-option KanikoBuildCacheEnabled=true instead")
-			platform.Spec.Build.AddOption(builder.KanikoBuildCacheEnabled, strconv.FormatBool(o.KanikoBuildCache))
+
+		platform.Spec.Build.Timeout = &metav1.Duration{
+			Duration: d,
 		}
-		if len(o.BuildPublishStrategyOptions) > 0 {
-			if err = o.addBuildPublishStrategyOptions(&platform.Spec.Build); err != nil {
-				return err
-			}
+	}
+	if o.TraitProfile != "" {
+		platform.Spec.Profile = v1.TraitProfileByName(o.TraitProfile)
+	}
+
+	if len(o.MavenRepositories) > 0 {
+		settings, err := maven.NewSettings(maven.Repositories(o.MavenRepositories...), maven.DefaultRepositories)
+		if err != nil {
+			return nil, err
 		}
-		// Always create a platform in the namespace where the operator is located
-		err = install.ObjectOrCollect(o.Context, c, namespace, collection, o.Force, platform)
+		err = createDefaultMavenSettingsConfigMap(o.Context, c, namespace, platform.Name, settings)
 		if err != nil {
-			return err
+			return nil, err
 		}
-
-		if err := install.IntegrationPlatformViewerRole(o.Context, c, namespace); err != nil && !k8serrors.IsAlreadyExists(err) {
-			return errors.Wrap(err, "Error while installing global IntegrationPlatform viewer role")
+		platform.Spec.Build.Maven.Settings.ConfigMapKeyRef = &corev1.ConfigMapKeySelector{
+			LocalObjectReference: corev1.LocalObjectReference{
+				Name: platform.Name + "-maven-settings",
+			},
+			Key: "settings.xml",
 		}
+	}
 
-		if o.ExampleSetup {
-			err = install.ExampleOrCollect(o.Context, c, namespace, collection, o.Force)
-			if err != nil {
-				return err
-			}
+	if o.MavenSettings != "" {
+		mavenSettings, err := decodeMavenSettings(o.MavenSettings)
+		if err != nil {
+			return nil, err
 		}
+		platform.Spec.Build.Maven.Settings = mavenSettings
+	}
 
-		if collection == nil {
-			if o.Wait {
-				err = o.waitForPlatformReady(cobraCmd, platform)
-				if err != nil {
-					return err
-				}
-			}
+	if o.MavenCASecret != "" {
+		secret, err := decodeSecretKeySelector(o.MavenCASecret)
+		if err != nil {
+			return nil, err
+		}
+		platform.Spec.Build.Maven.CASecrets = append(platform.Spec.Build.Maven.CASecrets, *secret)
+	}
 
-			strategy := ""
-			if installViaOLM {
-				strategy = "via OLM subscription"
-			}
-			if o.Global {
-				fmt.Fprintln(cobraCmd.OutOrStdout(), "Camel K installed in namespace", namespace, strategy, "(global mode)")
-			} else {
-				fmt.Fprintln(cobraCmd.OutOrStdout(), "Camel K installed in namespace", namespace, strategy)
+	if o.ClusterType != "" {
+		for _, c := range v1.AllIntegrationPlatformClusters {
+			if strings.EqualFold(string(c), o.ClusterType) {
+				platform.Spec.Cluster = c
 			}
 		}
 	}
-
-	if collection != nil {
-		return o.printOutput(cobraCmd, collection)
+	if platform.Spec.Build.PublishStrategy == v1.IntegrationPlatformBuildPublishStrategyKaniko && cmd.Flags().Lookup("kaniko-build-cache").Changed {
+		fmt.Fprintln(cmd.OutOrStdout(), "Warn: the flag --kaniko-build-cache is deprecated, use --build-publish-strategy-option KanikoBuildCacheEnabled=true instead")
+		platform.Spec.Build.AddOption(builder.KanikoBuildCacheEnabled, strconv.FormatBool(o.KanikoBuildCache))
 	}
-
-	return nil
-}
-
-func isInstallAllowed(ctx context.Context, c client.Client, operatorID string, force bool, out io.Writer) (bool, error) {
-	// find existing platform with given name in any namespace
-	pl, err := platformutil.LookupForPlatformName(ctx, c, operatorID)
-
-	if pl != nil && force {
-		fmt.Fprintf(out, "Overwriting existing operator with id '%s'\n", operatorID)
-		return true, nil
+	if len(o.BuildPublishStrategyOptions) > 0 {
+		if err = o.addBuildPublishStrategyOptions(&platform.Spec.Build); err != nil {
+			return nil, err
+		}
 	}
-
-	// only allow installation when platform with given name is not found
-	return pl == nil, err
-}
-
-func getOperatorID(vars []string) (string, error) {
-	envs, _, _, err := env.ParseEnv(vars, nil)
+	// Always create a platform in the namespace where the operator is located
+	err = install.ObjectOrCollect(o.Context, c, namespace, output, o.Force, platform)
 	if err != nil {
-		return "", err
-	}
-	for _, e := range envs {
-		if e.Name == "KAMEL_OPERATOR_ID" {
-			return e.Value, nil
-		}
+		return nil, err
 	}
 
-	return "", nil
-}
+	if err := install.IntegrationPlatformViewerRole(o.Context, c, namespace); err != nil && !k8serrors.IsAlreadyExists(err) {
+		return nil, errors.Wrap(err, "Error while installing global IntegrationPlatform viewer role")
+	}
 
-func (o *installCmdOptions) postRun(cmd *cobra.Command, _ []string) error {
-	if o.Save {
-		cfg, err := LoadConfiguration()
+	if o.ExampleSetup {
+		err = install.ExampleOrCollect(o.Context, c, namespace, output, o.Force)
 		if err != nil {
-			return err
+			return nil, err
 		}
-
-		cfg.Update(cmd, pathToRoot(cmd), o, true)
-
-		return cfg.Save()
 	}
 
-	return nil
+	return platform, nil
 }
 
 func (o *installCmdOptions) printOutput(cmd *cobra.Command, collection *kubernetes.Collection) error {
@@ -623,6 +655,21 @@ func (o *installCmdOptions) waitForPlatformReady(cmd *cobra.Command, platform *v
 	return watch.HandlePlatformStateChanges(o.Context, c, platform, handler)
 }
 
+func (o *installCmdOptions) postRun(cmd *cobra.Command, _ []string) error {
+	if o.Save {
+		cfg, err := LoadConfiguration()
+		if err != nil {
+			return err
+		}
+
+		cfg.Update(cmd, pathToRoot(cmd), o, true)
+
+		return cfg.Save()
+	}
+
+	return nil
+}
+
 func (o *installCmdOptions) decode(cmd *cobra.Command, _ []string) error {
 	path := pathToRoot(cmd)
 	if err := decodeKey(o, path); err != nil {
diff --git a/pkg/install/cluster.go b/pkg/install/cluster.go
index 5eb0c26b9..fd704759a 100644
--- a/pkg/install/cluster.go
+++ b/pkg/install/cluster.go
@@ -40,7 +40,10 @@ import (
 )
 
 // nolint: maintidx // TODO: refactor the code
-func SetupClusterWideResourcesOrCollect(ctx context.Context, clientProvider client.Provider, collection *kubernetes.Collection, clusterType string, force bool) error {
+func SetupClusterWideResourcesOrCollect(
+	ctx context.Context, clientProvider client.Provider,
+	collection *kubernetes.Collection, clusterType string, force bool,
+) error {
 	// Get a client to install the CRD
 	c, err := clientProvider.Get()
 	if err != nil {
@@ -48,23 +51,22 @@ func SetupClusterWideResourcesOrCollect(ctx context.Context, clientProvider clie
 	}
 
 	isAPIExtensionsV1 := true
-	_, err = c.Discovery().ServerResourcesForGroupVersion("apiextensions.k8s.io/v1")
-	if err != nil && k8serrors.IsNotFound(err) {
-		isAPIExtensionsV1 = false
-	} else if err != nil {
-		return err
+	if _, err := c.Discovery().ServerResourcesForGroupVersion("apiextensions.k8s.io/v1"); err != nil {
+		if k8serrors.IsNotFound(err) {
+			isAPIExtensionsV1 = false
+		} else {
+			return err
+		}
 	}
 
 	// Convert the CRD to apiextensions.k8s.io/v1beta1 in case v1 is not available.
 	// This is mainly required to support OpenShift 3, and older versions of Kubernetes.
 	// It can be removed as soon as these versions are not supported anymore.
-	err = apiextensionsv1.AddToScheme(c.GetScheme())
-	if err != nil {
+	if err := apiextensionsv1.AddToScheme(c.GetScheme()); err != nil {
 		return err
 	}
 	if !isAPIExtensionsV1 {
-		err = apiextensionsv1beta1.AddToScheme(c.GetScheme())
-		if err != nil {
+		if err := apiextensionsv1beta1.AddToScheme(c.GetScheme()); err != nil {
 			return err
 		}
 	}
@@ -114,37 +116,44 @@ func SetupClusterWideResourcesOrCollect(ctx context.Context, clientProvider clie
 	}
 
 	// Install CRD for Integration Platform (if needed)
-	if err := installCRD(ctx, c, "IntegrationPlatform", "v1", "camel.apache.org_integrationplatforms.yaml", downgradeToCRDv1beta1, collection, force); err != nil {
+	if err := installCRD(ctx, c, "IntegrationPlatform", "v1", "camel.apache.org_integrationplatforms.yaml",
+		downgradeToCRDv1beta1, collection, force); err != nil {
 		return err
 	}
 
 	// Install CRD for Integration Kit (if needed)
-	if err := installCRD(ctx, c, "IntegrationKit", "v1", "camel.apache.org_integrationkits.yaml", downgradeToCRDv1beta1, collection, force); err != nil {
+	if err := installCRD(ctx, c, "IntegrationKit", "v1", "camel.apache.org_integrationkits.yaml",
+		downgradeToCRDv1beta1, collection, force); err != nil {
 		return err
 	}
 
 	// Install CRD for Integration (if needed)
-	if err := installCRD(ctx, c, "Integration", "v1", "camel.apache.org_integrations.yaml", downgradeToCRDv1beta1, collection, force); err != nil {
+	if err := installCRD(ctx, c, "Integration", "v1", "camel.apache.org_integrations.yaml",
+		downgradeToCRDv1beta1, collection, force); err != nil {
 		return err
 	}
 
 	// Install CRD for Camel Catalog (if needed)
-	if err := installCRD(ctx, c, "CamelCatalog", "v1", "camel.apache.org_camelcatalogs.yaml", downgradeToCRDv1beta1, collection, force); err != nil {
+	if err := installCRD(ctx, c, "CamelCatalog", "v1", "camel.apache.org_camelcatalogs.yaml",
+		downgradeToCRDv1beta1, collection, force); err != nil {
 		return err
 	}
 
 	// Install CRD for Build (if needed)
-	if err := installCRD(ctx, c, "Build", "v1", "camel.apache.org_builds.yaml", downgradeToCRDv1beta1, collection, force); err != nil {
+	if err := installCRD(ctx, c, "Build", "v1", "camel.apache.org_builds.yaml",
+		downgradeToCRDv1beta1, collection, force); err != nil {
 		return err
 	}
 
 	// Install CRD for Kamelet (if needed)
-	if err := installCRD(ctx, c, "Kamelet", "v1alpha1", "camel.apache.org_kamelets.yaml", downgradeToCRDv1beta1, collection, force); err != nil {
+	if err := installCRD(ctx, c, "Kamelet", "v1alpha1", "camel.apache.org_kamelets.yaml",
+		downgradeToCRDv1beta1, collection, force); err != nil {
 		return err
 	}
 
 	// Install CRD for KameletBinding (if needed)
-	if err := installCRD(ctx, c, "KameletBinding", "v1alpha1", "camel.apache.org_kameletbindings.yaml", downgradeToCRDv1beta1, collection, force); err != nil {
+	if err := installCRD(ctx, c, "KameletBinding", "v1alpha1", "camel.apache.org_kameletbindings.yaml",
+		downgradeToCRDv1beta1, collection, force); err != nil {
 		return err
 	}
 
@@ -173,7 +182,8 @@ func SetupClusterWideResourcesOrCollect(ctx context.Context, clientProvider clie
 		return err
 	}
 	if !ok {
-		if err := installResource(ctx, c, collection, "/rbac/operator-cluster-role-custom-resource-definitions.yaml"); err != nil {
+		if err := installResource(ctx, c, collection,
+			"/rbac/operator-cluster-role-custom-resource-definitions.yaml"); err != nil {
 			return err
 		}
 	}
@@ -237,7 +247,9 @@ func WaitForAllCrdInstallation(ctx context.Context, clientProvider client.Provid
 		}
 		// Check after 2 seconds if not expired
 		if time.Now().After(deadline) {
-			return errors.New("cannot check CRD installation after " + strconv.FormatInt(timeout.Nanoseconds()/1000000000, 10) + " seconds")
+			return fmt.Errorf(
+				"cannot check CRD installation after %s seconds",
+				strconv.FormatInt(timeout.Nanoseconds()/1000000000, 10))
 		}
 		time.Sleep(2 * time.Second)
 	}
@@ -292,7 +304,10 @@ func isCrdInstalled(c client.Client, kind string, version string) (bool, error)
 	return false, nil
 }
 
-func installCRD(ctx context.Context, c client.Client, kind string, version string, resourceName string, converter ResourceCustomizer, collection *kubernetes.Collection, force bool) error {
+func installCRD(
+	ctx context.Context, c client.Client, kind string, version string, resourceName string,
+	converter ResourceCustomizer, collection *kubernetes.Collection, force bool,
+) error {
 	content, err := resources.ResourceAsString("/crd/bases/" + resourceName)
 	if err != nil {
 		return err
diff --git a/pkg/install/operator.go b/pkg/install/operator.go
index 00d01f1d0..f48ac3ba5 100644
--- a/pkg/install/operator.go
+++ b/pkg/install/operator.go
@@ -509,9 +509,11 @@ func installLeaseBindings(ctx context.Context, c client.Client, namespace string
 	)
 }
 
-// NewPlatform --
-// nolint: lll
-func NewPlatform(ctx context.Context, c client.Client, clusterType string, skipRegistrySetup bool, registry v1.RegistrySpec, operatorID string) (*v1.IntegrationPlatform, error) {
+// NewPlatform creates a new IntegrationPlatform instance.
+func NewPlatform(
+	ctx context.Context, c client.Client,
+	clusterType string, skipRegistrySetup bool, registry v1.RegistrySpec, operatorID string,
+) (*v1.IntegrationPlatform, error) {
 	isOpenShift, err := isOpenShift(c, clusterType)
 	if err != nil {
 		return nil, err
diff --git a/pkg/util/olm/available.go b/pkg/util/olm/available.go
index 9f5445506..69125edb1 100644
--- a/pkg/util/olm/available.go
+++ b/pkg/util/olm/available.go
@@ -31,7 +31,7 @@ import (
 	kubernetesutils "github.com/apache/camel-k/pkg/util/kubernetes"
 )
 
-// IsAPIAvailable returns true if we are connected to a cluster with OLM installed
+// IsAPIAvailable returns true if we are connected to a cluster with OLM installed.
 //
 // This method should not be called from the operator, as it might require permissions that are not available.
 func IsAPIAvailable(ctx context.Context, c kubernetes.Interface, namespace string) (bool, error) {