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

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

commit 6b8e113c4ce5a4cd7d6d91551033b12b0f375f6e
Author: Nicola Ferraro <[email protected]>
AuthorDate: Sat Feb 8 00:47:35 2020 +0100

    Fix #1223: add OLM install options
---
 go.mod                                             |   1 +
 go.sum                                             |   3 +
 ...v1alpha1.go => addtoscheme_knative_eventing.go} |   0
 ..._v1alpha1.go => addtoscheme_knative_serving.go} |   0
 ...tive_serving_v1alpha1.go => addtoscheme_olm.go} |   4 +-
 pkg/client/fastmapper.go                           |   1 +
 pkg/cmd/install.go                                 |  73 ++++++--
 pkg/util/olm/available.go                          |  59 ++++++
 pkg/util/olm/operator.go                           | 201 +++++++++++++++++++++
 9 files changed, 328 insertions(+), 14 deletions(-)

diff --git a/go.mod b/go.mod
index 9d88d7a..52f4532 100644
--- a/go.mod
+++ b/go.mod
@@ -22,6 +22,7 @@ require (
        github.com/mitchellh/mapstructure v1.1.2
        github.com/onsi/gomega v1.7.0
        github.com/openshift/api 
v3.9.1-0.20190927182313-d4a64ec2cbd8+incompatible
+       github.com/operator-framework/operator-lifecycle-manager 
v0.0.0-20191115003340-16619cd27fa5
        github.com/operator-framework/operator-sdk v0.15.0
        github.com/pkg/errors v0.8.1
        github.com/radovskyb/watcher v1.0.6
diff --git a/go.sum b/go.sum
index 5a419be..a3675c8 100644
--- a/go.sum
+++ b/go.sum
@@ -103,6 +103,7 @@ github.com/bifurcation/mint 
v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3
 github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod 
h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
 github.com/bitly/go-simplejson v0.5.0/go.mod 
h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
 github.com/blang/semver v3.5.0+incompatible/go.mod 
h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
+github.com/blang/semver v3.5.1+incompatible 
h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
 github.com/blang/semver v3.5.1+incompatible/go.mod 
h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod 
h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
 github.com/boltdb/bolt v1.3.1/go.mod 
h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
@@ -588,7 +589,9 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod 
h1:UkNAQd3GIcIGf0SeVgPpRdFSt
 github.com/openzipkin/zipkin-go v0.1.6 
h1:yXiysv1CSK7Q5yjGy1710zZGnsbMUIjluWBxtLXHPBo=
 github.com/openzipkin/zipkin-go v0.1.6/go.mod 
h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
 github.com/operator-framework/api v0.0.0-20200120235816-80fd2f1a09c9/go.mod 
h1:S5IdlJvmKkF84K2tBvsrqJbI2FVy03P88R75snpRxJo=
+github.com/operator-framework/operator-lifecycle-manager 
v0.0.0-20191115003340-16619cd27fa5 
h1:rjaihxY50c5C+kbQIK4s36R8zxByATYrgRbua4eiG6o=
 github.com/operator-framework/operator-lifecycle-manager 
v0.0.0-20191115003340-16619cd27fa5/go.mod 
h1:zL34MNy92LPutBH5gQK+gGhtgTUlZZX03I2G12vWHF4=
+github.com/operator-framework/operator-lifecycle-manager v3.11.0+incompatible 
h1:Po8C8RVLRWq7pNQ5pKonM9CXpC/osoBWbmsuf+HJnSI=
 github.com/operator-framework/operator-registry v1.5.1/go.mod 
h1:agrQlkWOo1q8U1SAaLSS2WQ+Z9vswNT2M2HFib9iuLY=
 github.com/operator-framework/operator-registry v1.5.3/go.mod 
h1:agrQlkWOo1q8U1SAaLSS2WQ+Z9vswNT2M2HFib9iuLY=
 github.com/operator-framework/operator-registry 
v1.5.7-0.20200121213444-d8e2ec52c19a/go.mod 
h1:ekexcV4O8YMxdQuPb+Xco7MHfVmRIq7Jvj5e6NU7dHI=
diff --git a/pkg/apis/addtoscheme_knative_eventing_v1alpha1.go 
b/pkg/apis/addtoscheme_knative_eventing.go
similarity index 100%
rename from pkg/apis/addtoscheme_knative_eventing_v1alpha1.go
rename to pkg/apis/addtoscheme_knative_eventing.go
diff --git a/pkg/apis/addtoscheme_knative_serving_v1alpha1.go 
b/pkg/apis/addtoscheme_knative_serving.go
similarity index 100%
copy from pkg/apis/addtoscheme_knative_serving_v1alpha1.go
copy to pkg/apis/addtoscheme_knative_serving.go
diff --git a/pkg/apis/addtoscheme_knative_serving_v1alpha1.go 
b/pkg/apis/addtoscheme_olm.go
similarity index 84%
rename from pkg/apis/addtoscheme_knative_serving_v1alpha1.go
rename to pkg/apis/addtoscheme_olm.go
index f270608..a69aa84 100644
--- a/pkg/apis/addtoscheme_knative_serving_v1alpha1.go
+++ b/pkg/apis/addtoscheme_olm.go
@@ -18,10 +18,10 @@ limitations under the License.
 package apis
 
 import (
-       serving "knative.dev/serving/pkg/apis/serving/v1"
+       olmv1alpha1 
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
 )
 
 func init() {
        // Register the types with the Scheme so the components can map objects 
to GroupVersionKinds and back
-       AddToSchemes = append(AddToSchemes, serving.AddToScheme)
+       AddToSchemes = append(AddToSchemes, olmv1alpha1.AddToScheme)
 }
diff --git a/pkg/client/fastmapper.go b/pkg/client/fastmapper.go
index 346603d..82b33b8 100644
--- a/pkg/client/fastmapper.go
+++ b/pkg/client/fastmapper.go
@@ -38,6 +38,7 @@ var FastMapperAllowedAPIGroups = map[string]bool{
        "camel.apache.org":          true,
        "rbac.authorization.k8s.io": true,
        "console.openshift.io":      true, // OpenShift console resources
+       "operators.coreos.com":      true, // Operator SDK OLM
 }
 
 // newFastDiscoveryRESTMapper comes from 
https://github.com/kubernetes-sigs/controller-runtime/pull/592.
diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go
index f9a3481..8e9c669 100644
--- a/pkg/cmd/install.go
+++ b/pkg/cmd/install.go
@@ -23,6 +23,7 @@ import (
        "strings"
        "time"
 
+       "github.com/apache/camel-k/pkg/util/olm"
        "github.com/apache/camel-k/pkg/util/registry"
        "go.uber.org/multierr"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -93,6 +94,16 @@ func newCmdInstall(rootCmdOptions *RootCmdOptions) 
(*cobra.Command, *installCmdO
        cmd.Flags().String("http-proxy-secret", "", "Configure the source of 
the secret holding HTTP proxy server details "+
                "(HTTP_PROXY|HTTPS_PROXY|NO_PROXY)")
 
+       // olm
+       cmd.Flags().Bool("olm", true, "Try to install everything via OLM 
(Operator Lifecycle Manager) if available")
+       cmd.Flags().String("olm-operator-name", olm.DefaultOperatorName, "Name 
of the Camel K operator in the OLM source or marketplace")
+       cmd.Flags().String("olm-package", olm.DefaultPackage, "Name of the 
Camel K package in the OLM source or marketplace")
+       cmd.Flags().String("olm-channel", olm.DefaultChannel, "Name of the 
Camel K channel in the OLM source or marketplace")
+       cmd.Flags().String("olm-source", olm.DefaultSource, "Name of the OLM 
source providing the Camel K package (defaults to the standard Operator Hub 
source)")
+       cmd.Flags().String("olm-source-namespace", olm.DefaultSourceNamespace, 
"Namespace where the OLM source is available")
+       cmd.Flags().String("olm-starting-csv", olm.DefaultStartingCSV, "Allow 
to install a specific version from the operator source instead of latest 
available from the channel")
+       cmd.Flags().String("olm-global-namespace", olm.DefaultGlobalNamespace, 
"A namespace containing an OperatorGroup that defines global scope for the 
operator (used in combination with the --global flag)")
+
        // maven settings
        cmd.Flags().String("local-repository", "", "Location of the local maven 
repository")
        cmd.Flags().String("maven-settings", "", "Configure the source of the 
maven settings (configmap|secret:name[/key])")
@@ -123,6 +134,7 @@ type installCmdOptions struct {
        Global            bool     `mapstructure:"global"`
        KanikoBuildCache  bool     `mapstructure:"kaniko-build-cache"`
        Save              bool     `mapstructure:"save"`
+       Olm               bool    `mapstructure:"olm"`
        ClusterType       string   `mapstructure:"cluster-type"`
        OutputFormat      string   `mapstructure:"output"`
        RuntimeVersion    string   `mapstructure:"runtime-version"`
@@ -140,6 +152,7 @@ type installCmdOptions struct {
 
        registry     v1.IntegrationPlatformRegistrySpec
        registryAuth registry.Auth
+       olmOptions   olm.Options
 }
 
 // nolint: gocyclo
@@ -149,13 +162,36 @@ func (o *installCmdOptions) install(cobraCmd 
*cobra.Command, _ []string) error {
                collection = kubernetes.NewCollection()
        }
 
-       if !o.SkipClusterSetup {
-               // Let's use a client provider during cluster installation, to 
eliminate the problem of CRD object caching
-               clientProvider := client.Provider{Get: o.NewCmdClient}
+       // Let's use a client provider during cluster installation, to 
eliminate the problem of CRD object caching
+       clientProvider := client.Provider{Get: o.NewCmdClient}
+
+       installViaOLM := false
+       if o.Olm {
+               var err error
+               var olmClient client.Client
+               if olmClient, err = clientProvider.Get(); err != nil {
+                       return err
+               }
+               if installViaOLM, err = olm.IsAvailable(o.Context, olmClient); 
err != nil {
+                       return errors.Wrap(err, "error while checking OLM 
availability. Run with '--olm=false' to skip this check")
+               }
 
+               if installViaOLM {
+                       fmt.Fprintln(cobraCmd.OutOrStdout(), "OLM is available 
in the cluster");
+                       if err = olm.Install(o.Context, olmClient, o.Namespace, 
o.Global, o.olmOptions, collection); err != nil {
+                               return err
+                       }
+               }
+
+               if err = install.WaitForAllCRDInstallation(o.Context, 
clientProvider, 90 * time.Second); err != nil {
+                       return err
+               }
+       }
+
+       if !o.SkipClusterSetup && !installViaOLM {
                err := install.SetupClusterWideResourcesOrCollect(o.Context, 
clientProvider, collection)
                if err != nil && k8serrors.IsForbidden(err) {
-                       fmt.Println("Current user is not authorized to create 
cluster-wide objects like custom resource definitions or cluster roles: ", err)
+                       fmt.Fprintln(cobraCmd.OutOrStdout(), "Current user is 
not authorized to create cluster-wide objects like custom resource definitions 
or cluster roles: ", 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)
@@ -166,7 +202,7 @@ func (o *installCmdOptions) install(cobraCmd 
*cobra.Command, _ []string) error {
 
        if o.ClusterSetupOnly {
                if collection == nil {
-                       fmt.Println("Camel K cluster setup completed 
successfully")
+                       fmt.Fprintln(cobraCmd.OutOrStdout(),"Camel K cluster 
setup completed successfully")
                }
        } else {
                c, err := o.GetCmdClient()
@@ -176,7 +212,7 @@ func (o *installCmdOptions) install(cobraCmd 
*cobra.Command, _ []string) error {
 
                namespace := o.Namespace
 
-               if !o.SkipOperatorSetup {
+               if !o.SkipOperatorSetup && !installViaOLM {
                        cfg := install.OperatorConfiguration{
                                CustomImage: o.OperatorImage,
                                Namespace:   namespace,
@@ -187,8 +223,8 @@ func (o *installCmdOptions) install(cobraCmd 
*cobra.Command, _ []string) error {
                        if err != nil {
                                return err
                        }
-               } else {
-                       fmt.Println("Camel K operator installation skipped")
+               } else if o.SkipOperatorSetup {
+                       fmt.Fprintln(cobraCmd.OutOrStdout(), "Camel K operator 
installation skipped")
                }
 
                generatedSecretName := ""
@@ -288,8 +324,9 @@ func (o *installCmdOptions) install(cobraCmd 
*cobra.Command, _ []string) error {
                platform.Spec.Resources.Kits = o.Kits
 
                // Do not create an integration platform in global mode as 
platforms are expected
-               // to be created in other namespaces
-               if !o.Global {
+               // to be created in other namespaces.
+               // In OLM mode, the operator is installed in an external 
namespace, so it's ok to install the platform locally.
+               if !o.Global || installViaOLM {
                        err = install.RuntimeObjectOrCollect(o.Context, c, 
namespace, collection, platform)
                        if err != nil {
                                return err
@@ -311,10 +348,14 @@ func (o *installCmdOptions) install(cobraCmd 
*cobra.Command, _ []string) error {
                                }
                        }
 
+                       strategy := ""
+                       if installViaOLM {
+                               strategy = "via OLM subscription"
+                       }
                        if o.Global {
-                               fmt.Println("Camel K installed in namespace", 
namespace, "(global mode)")
+                               fmt.Println("Camel K installed in namespace", 
namespace, strategy, "(global mode)")
                        } else {
-                               fmt.Println("Camel K installed in namespace", 
namespace)
+                               fmt.Println("Camel K installed in namespace", 
namespace, strategy)
                        }
                }
        }
@@ -389,6 +430,14 @@ func (o *installCmdOptions) decode(cmd *cobra.Command, _ 
[]string) error {
        o.registryAuth.Password = viper.GetString(path + 
".registry-auth-password")
        o.registryAuth.Server = viper.GetString(path + ".registry-auth-server")
 
+       o.olmOptions.OperatorName = viper.GetString(path + ".olm-operator-name")
+       o.olmOptions.Package = viper.GetString(path + ".olm-package")
+       o.olmOptions.Channel = viper.GetString(path + ".olm-channel")
+       o.olmOptions.Source = viper.GetString(path + ".olm-source")
+       o.olmOptions.SourceNamespace = viper.GetString(path + 
".olm-source-namespace")
+       o.olmOptions.StartingCSV = viper.GetString(path + ".olm-starting-csv")
+       o.olmOptions.GlobalNamespace = viper.GetString(path + 
".olm-global-namespace")
+
        return nil
 }
 
diff --git a/pkg/util/olm/available.go b/pkg/util/olm/available.go
new file mode 100644
index 0000000..2d7636f
--- /dev/null
+++ b/pkg/util/olm/available.go
@@ -0,0 +1,59 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package olm
+
+import (
+       "context"
+
+       kubernetesutils "github.com/apache/camel-k/pkg/util/kubernetes"
+       olmv1alpha1 
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
+       k8serrors "k8s.io/apimachinery/pkg/api/errors"
+       "k8s.io/apimachinery/pkg/runtime/schema"
+       "k8s.io/client-go/kubernetes"
+)
+
+// IsAvailable 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 IsAvailable(ctx context.Context, c kubernetes.Interface) (bool, error) {
+       // check some Knative APIs
+       for _, api := range getOLMGroupVersions() {
+               if installed, err := isAvailable(c, api); err != nil {
+                       return false, err
+               } else if installed {
+                       return true, nil
+               }
+       }
+       return false, nil
+}
+
+func isAvailable(c kubernetes.Interface, api schema.GroupVersion) (bool, 
error) {
+       _, err := c.Discovery().ServerResourcesForGroupVersion(api.String())
+       if err != nil && (k8serrors.IsNotFound(err) || 
kubernetesutils.IsUnknownAPIError(err)) {
+               return false, nil
+       } else if err != nil {
+               return false, err
+       }
+       return true, nil
+}
+
+func getOLMGroupVersions() []schema.GroupVersion {
+       return []schema.GroupVersion{
+               olmv1alpha1.SchemeGroupVersion,
+       }
+}
diff --git a/pkg/util/olm/operator.go b/pkg/util/olm/operator.go
new file mode 100644
index 0000000..c5bda90
--- /dev/null
+++ b/pkg/util/olm/operator.go
@@ -0,0 +1,201 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package olm
+
+import (
+       "context"
+       "strings"
+
+       "github.com/apache/camel-k/pkg/client"
+       "github.com/apache/camel-k/pkg/util/kubernetes"
+       olmv1alpha1 
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
+       v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+       runtime "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+// The following properties can be overridden at build time via ldflags
+
+// DefaultOperatorName is the Camel K operator name in OLM
+var DefaultOperatorName = "camel-k-operator"
+
+// DefaultPackage is the Camel K package in OLM
+var DefaultPackage = "camel-k"
+
+// DefaultChannel is the distribution channel in Operator Hub
+var DefaultChannel = "alpha"
+
+// DefaultSource is the name of the operator source where the operator is 
published
+var DefaultSource = "community-operators"
+
+// DefaultSourceNamespace is the namespace of the operator source
+var DefaultSourceNamespace = "openshift-marketplace"
+
+// DefaultStartingCSV contains the specific version to install
+var DefaultStartingCSV = ""
+
+// DefaultGlobalNamespace indicates a namespace containing an OperatorGroup 
that enables the operator to watch all namespaces.
+// It will be used in global installation mode.
+var DefaultGlobalNamespace = "openshift-operators"
+
+// Options contains information about an operator in OLM
+type Options struct {
+       OperatorName        string
+       Package             string
+       Channel             string
+       Source              string
+       SourceNamespace     string
+       StartingCSV         string
+       GlobalNamespace     string
+}
+
+// IsOperatorInstalled tells if a OLM CSV or a Subscription is already 
installed in the namespace
+func IsOperatorInstalled(ctx context.Context, client client.Client, namespace 
string, global bool, options Options) (bool, error) {
+       options = fillDefaults(options)
+       // CSV is present in current namespace for both local and global 
installation modes
+       if csv, err := findCSV(ctx, client, namespace, options); err != nil {
+               return false, err
+       } else if csv != nil {
+               return true, nil
+       }
+       // A subscription may indicate an in-progress installation
+       if sub, err := findSubscription(ctx, client, namespace, global, 
options); err != nil {
+               return false, err
+       } else if sub != nil {
+               return true, nil
+       }
+
+       return false, nil
+}
+
+// Install creates a subscription for the OLM package
+func Install(ctx context.Context, client client.Client, namespace string, 
global bool, options Options, collection *kubernetes.Collection) error {
+       options = fillDefaults(options)
+       if installed, err := IsOperatorInstalled(ctx, client, namespace, 
global, options); err != nil {
+               return err
+       } else if installed {
+               // Already installed
+               return nil
+       }
+
+       targetNamespace := namespace
+       if global {
+               targetNamespace = options.GlobalNamespace
+       }
+
+       sub := olmv1alpha1.Subscription{
+               ObjectMeta: v1.ObjectMeta{
+                       Name:      options.Package,
+                       Namespace: targetNamespace,
+               },
+               Spec: &olmv1alpha1.SubscriptionSpec{
+                       CatalogSource:          options.Source,
+                       CatalogSourceNamespace: options.SourceNamespace,
+                       Package:                options.Package,
+                       Channel:                options.Channel,
+                       StartingCSV:            options.StartingCSV,
+                       InstallPlanApproval:    olmv1alpha1.ApprovalAutomatic,
+               },
+       }
+       if collection != nil {
+               collection.Add(&sub)
+               return nil
+       }
+       return client.Create(ctx, &sub)
+}
+
+// Uninstall removes CSV and subscription from the namespace
+func Uninstall(ctx context.Context, client client.Client, namespace string, 
global bool, options Options) error {
+       sub, err := findSubscription(ctx, client, namespace, global, options)
+       if err != nil {
+               return err
+       }
+       if sub != nil {
+               if err := client.Delete(ctx, sub); err != nil {
+                       return err
+               }
+       }
+
+       csv, err := findCSV(ctx, client, namespace, options)
+       if err != nil {
+               return err
+       }
+       if csv != nil {
+               if err := client.Delete(ctx, csv); err != nil {
+                       return err
+               }
+       }
+       return nil
+}
+
+func findSubscription(ctx context.Context, client client.Client, namespace 
string, global bool, options Options) (*olmv1alpha1.Subscription, error) {
+       subNamespace := namespace
+       if global {
+               // In case of global installation, global subscription must be 
removed
+               subNamespace = options.GlobalNamespace
+       }
+       subscriptionList := olmv1alpha1.SubscriptionList{}
+       if err := client.List(ctx, &subscriptionList, 
runtime.InNamespace(subNamespace)); err != nil {
+               return nil, err
+       }
+
+       for _, item := range subscriptionList.Items {
+               if item.Spec.Package == options.Package {
+                       return &item, nil
+               }
+       }
+       return nil, nil
+}
+
+func findCSV(ctx context.Context, client client.Client, namespace string, 
options Options) (*olmv1alpha1.ClusterServiceVersion, error) {
+       csvList := olmv1alpha1.ClusterServiceVersionList{}
+       if err := client.List(ctx, &csvList, runtime.InNamespace(namespace)); 
err != nil {
+               return nil, err
+       }
+
+       for _, item := range csvList.Items {
+               if strings.HasPrefix(item.Name, options.OperatorName) {
+                       return &item, nil
+               }
+       }
+       return nil, nil
+}
+
+func fillDefaults(o Options) Options {
+       if o.OperatorName == "" {
+               o.OperatorName = DefaultOperatorName
+       }
+       if o.Package == "" {
+               o.Package = DefaultPackage
+       }
+       if o.Channel == "" {
+               o.Channel = DefaultChannel
+       }
+       if o.Source == "" {
+               o.Source = DefaultSource
+       }
+       if o.SourceNamespace == "" {
+               o.SourceNamespace = DefaultSourceNamespace
+       }
+       if o.StartingCSV == "" {
+               o.StartingCSV = DefaultStartingCSV
+       }
+       if o.GlobalNamespace == "" {
+               o.GlobalNamespace = DefaultGlobalNamespace
+       }
+       return o
+}

Reply via email to