diff --git a/pkg/component/component.go b/pkg/component/component.go index 7b58b4e6bb0..2d2c1791b07 100644 --- a/pkg/component/component.go +++ b/pkg/component/component.go @@ -25,7 +25,6 @@ import ( "github.com/openshift/odo/pkg/exec" "github.com/openshift/odo/pkg/log" "github.com/openshift/odo/pkg/occlient" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/odo/util/validation" "github.com/openshift/odo/pkg/preference" "github.com/openshift/odo/pkg/storage" @@ -545,7 +544,6 @@ func ValidateComponentCreateRequest(client *occlient.Client, componentSettings c // Returns: // err: Errors if any else nil func ApplyConfig(client *occlient.Client, kClient *kclient.Client, componentConfig config.LocalConfigInfo, envSpecificInfo envinfo.EnvSpecificInfo, stdout io.Writer, cmpExist bool) (err error) { - isExperimentalModeEnabled := experimental.IsExperimentalModeEnabled() if client == nil { var err error @@ -556,23 +554,20 @@ func ApplyConfig(client *occlient.Client, kClient *kclient.Client, componentConf client.Namespace = envSpecificInfo.GetNamespace() } - if !isExperimentalModeEnabled { - // if component exist then only call the update function - if cmpExist { - if err = Update(client, componentConfig, componentConfig.GetSourceLocation(), stdout); err != nil { - return err - } + // if component exist then only call the update function + if cmpExist { + if err = Update(client, componentConfig, componentConfig.GetSourceLocation(), stdout); err != nil { + return err } } var componentName string var applicationName string - if !isExperimentalModeEnabled || kClient == nil { - componentName = componentConfig.GetName() - applicationName = componentConfig.GetApplication() - } else { - componentName = envSpecificInfo.GetName() - } + // Devfile + componentName = componentConfig.GetName() + applicationName = componentConfig.GetApplication() + // NOTE: This used to be an if statement, use this for s2i only: + componentName = envSpecificInfo.GetName() isRouteSupported := false isRouteSupported, err = client.IsRouteSupported() @@ -581,12 +576,11 @@ func ApplyConfig(client *occlient.Client, kClient *kclient.Client, componentConf } return urlpkg.Push(client, kClient, urlpkg.PushParameters{ - ComponentName: componentName, - ApplicationName: applicationName, - ConfigURLs: componentConfig.GetURL(), - EnvURLS: envSpecificInfo.GetURL(), - IsRouteSupported: isRouteSupported, - IsExperimentalModeEnabled: isExperimentalModeEnabled, + ComponentName: componentName, + ApplicationName: applicationName, + ConfigURLs: componentConfig.GetURL(), + EnvURLS: envSpecificInfo.GetURL(), + IsRouteSupported: isRouteSupported, }) } diff --git a/pkg/component/component_full_description.go b/pkg/component/component_full_description.go index 8b92dfd725a..71b9459e254 100644 --- a/pkg/component/component_full_description.go +++ b/pkg/component/component_full_description.go @@ -8,7 +8,6 @@ import ( "github.com/openshift/odo/pkg/config" "github.com/openshift/odo/pkg/log" "github.com/openshift/odo/pkg/occlient" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/storage" urlpkg "github.com/openshift/odo/pkg/url" corev1 "k8s.io/api/core/v1" @@ -190,20 +189,18 @@ func (cfd *ComponentFullDescription) Print(client *occlient.Client) error { if len(cfd.Spec.URL.Items) > 0 { var output string - if !experimental.IsExperimentalModeEnabled() { - // if the component is not pushed - for i, componentURL := range cfd.Spec.URL.Items { - if componentURL.Status.State == urlpkg.StateTypePushed { - output += fmt.Sprintf(" · %v exposed via %v\n", urlpkg.GetURLString(componentURL.Spec.Protocol, componentURL.Spec.Host, "", experimental.IsExperimentalModeEnabled()), componentURL.Spec.Port) + // if the component is not pushed + for i, componentURL := range cfd.Spec.URL.Items { + if componentURL.Status.State == urlpkg.StateTypePushed { + output += fmt.Sprintf(" · %v exposed via %v\n", urlpkg.GetURLString(componentURL.Spec.Protocol, componentURL.Spec.Host, ""), componentURL.Spec.Port) + } else { + var p string + if i >= len(cfd.Spec.Ports) { + p = cfd.Spec.Ports[len(cfd.Spec.Ports)-1] } else { - var p string - if i >= len(cfd.Spec.Ports) { - p = cfd.Spec.Ports[len(cfd.Spec.Ports)-1] - } else { - p = cfd.Spec.Ports[i] - } - output += fmt.Sprintf(" · URL named %s will be exposed via %v\n", componentURL.Name, p) + p = cfd.Spec.Ports[i] } + output += fmt.Sprintf(" · URL named %s will be exposed via %v\n", componentURL.Name, p) } } // Cut off the last newline and output diff --git a/pkg/occlient/occlient.go b/pkg/occlient/occlient.go index 71ac55dcb34..d9bc793b964 100644 --- a/pkg/occlient/occlient.go +++ b/pkg/occlient/occlient.go @@ -22,7 +22,6 @@ import ( "github.com/openshift/odo/pkg/config" "github.com/openshift/odo/pkg/devfile/adapters/common" "github.com/openshift/odo/pkg/log" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/preference" "github.com/openshift/odo/pkg/util" @@ -751,11 +750,7 @@ func (c *Client) GetImageStream(imageNS string, imageName string, imageTag strin } } if e != nil && err != nil { - // Imagestream not found in openshift and current namespaces - if experimental.IsExperimentalModeEnabled() { - return nil, fmt.Errorf("component type %q not found", imageName) - } - return nil, err + return nil, fmt.Errorf("component type %q not found", imageName) } // Required tag not in openshift and current namespaces diff --git a/pkg/odo/cli/catalog/describe/component.go b/pkg/odo/cli/catalog/describe/component.go index 743a9729cf7..95b2ac776ce 100644 --- a/pkg/odo/cli/catalog/describe/component.go +++ b/pkg/odo/cli/catalog/describe/component.go @@ -11,7 +11,6 @@ import ( "github.com/openshift/odo/pkg/log" "github.com/openshift/odo/pkg/machineoutput" "github.com/openshift/odo/pkg/odo/genericclioptions" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/odo/util/pushtarget" "github.com/openshift/odo/pkg/util" pkgUtil "github.com/openshift/odo/pkg/util" @@ -61,11 +60,14 @@ func (o *DescribeComponentOptions) Complete(name string, cmd *cobra.Command, arg tasks.Add(util.ConcurrentTask{ToRun: func(errChannel chan error) { catalogList, err := catalog.ListComponents(o.Client) if err != nil { - if experimental.IsExperimentalModeEnabled() { - klog.V(4).Info("Please log in to an OpenShift cluster to list OpenShift/s2i components") - } else { - errChannel <- err - } + klog.V(4).Info("Please log in to an OpenShift cluster to list OpenShift/s2i components") + + // S2I Only + /* + } else { + errChannel <- err + } + */ } for _, image := range catalogList.Items { if image.Name == o.componentName { @@ -75,18 +77,16 @@ func (o *DescribeComponentOptions) Complete(name string, cmd *cobra.Command, arg }}) } - if experimental.IsExperimentalModeEnabled() { - tasks.Add(util.ConcurrentTask{ToRun: func(errChannel chan error) { - catalogDevfileList, err := catalog.ListDevfileComponents("") - if catalogDevfileList.DevfileRegistries == nil { - log.Warning("Please run 'odo registry add ' to add registry for listing devfile components\n") - } - if err != nil { - errChannel <- err - } - o.GetDevfileComponentsByName(catalogDevfileList) - }}) - } + tasks.Add(util.ConcurrentTask{ToRun: func(errChannel chan error) { + catalogDevfileList, err := catalog.ListDevfileComponents("") + if catalogDevfileList.DevfileRegistries == nil { + log.Warning("Please run 'odo registry add ' to add registry for listing devfile components\n") + } + if err != nil { + errChannel <- err + } + o.GetDevfileComponentsByName(catalogDevfileList) + }}) return tasks.Run() } @@ -102,50 +102,48 @@ func (o *DescribeComponentOptions) Validate() (err error) { // Run contains the logic for the command associated with DescribeComponentOptions func (o *DescribeComponentOptions) Run() (err error) { - if experimental.IsExperimentalModeEnabled() { - w := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) - if log.IsJSON() { - if len(o.devfileComponents) > 0 { - for _, devfileComponent := range o.devfileComponents { - devObj, err := GetDevfile(devfileComponent) - if err != nil { - return err - } - - machineoutput.OutputSuccess(devObj) + w := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) + if log.IsJSON() { + if len(o.devfileComponents) > 0 { + for _, devfileComponent := range o.devfileComponents { + devObj, err := GetDevfile(devfileComponent) + if err != nil { + return err } + + machineoutput.OutputSuccess(devObj) } - } else { - if len(o.devfileComponents) > 1 { - log.Warningf("There are multiple components named \"%s\" in different multiple devfile registries.\n", o.componentName) - } - if len(o.devfileComponents) > 0 { - fmt.Fprintln(w, "Devfile Component(s):") + } + } else { + if len(o.devfileComponents) > 1 { + log.Warningf("There are multiple components named \"%s\" in different multiple devfile registries.\n", o.componentName) + } + if len(o.devfileComponents) > 0 { + fmt.Fprintln(w, "Devfile Component(s):") - for _, devfileComponent := range o.devfileComponents { - fmt.Fprintln(w, "\n* Registry: "+devfileComponent.Registry.Name) + for _, devfileComponent := range o.devfileComponents { + fmt.Fprintln(w, "\n* Registry: "+devfileComponent.Registry.Name) - devObj, err := GetDevfile(devfileComponent) - if err != nil { - return err - } + devObj, err := GetDevfile(devfileComponent) + if err != nil { + return err + } - projects := devObj.Data.GetProjects() - // only print project info if there is at least one project in the devfile - err = o.PrintDevfileProjects(w, projects, devObj) - if err != nil { - return err - } + projects := devObj.Data.GetProjects() + // only print project info if there is at least one project in the devfile + err = o.PrintDevfileProjects(w, projects, devObj) + if err != nil { + return err } - } else { - fmt.Fprintln(w, "There are no Odo devfile components with the name \""+o.componentName+"\"") } - if o.component != "" { - fmt.Fprintln(w, "\nS2I Based Components:") - fmt.Fprintln(w, "-"+o.component) - } - fmt.Fprintln(w) + } else { + fmt.Fprintln(w, "There are no Odo devfile components with the name \""+o.componentName+"\"") + } + if o.component != "" { + fmt.Fprintln(w, "\nS2I Based Components:") + fmt.Fprintln(w, "-"+o.component) } + fmt.Fprintln(w) } return nil diff --git a/pkg/odo/cli/catalog/describe/service.go b/pkg/odo/cli/catalog/describe/service.go index f80641e77ec..c30526c0da5 100644 --- a/pkg/odo/cli/catalog/describe/service.go +++ b/pkg/odo/cli/catalog/describe/service.go @@ -2,13 +2,14 @@ package describe import ( "fmt" + "os" + "strings" + "github.com/olekukonko/tablewriter" "github.com/openshift/odo/pkg/odo/genericclioptions" svc "github.com/openshift/odo/pkg/service" "github.com/spf13/cobra" ktemplates "k8s.io/kubectl/pkg/util/templates" - "os" - "strings" ) const serviceRecommendedCommandName = "service" diff --git a/pkg/odo/cli/catalog/list/components.go b/pkg/odo/cli/catalog/list/components.go index 3e5efe180e9..315a01816dc 100644 --- a/pkg/odo/cli/catalog/list/components.go +++ b/pkg/odo/cli/catalog/list/components.go @@ -12,7 +12,6 @@ import ( "github.com/openshift/odo/pkg/machineoutput" catalogutil "github.com/openshift/odo/pkg/odo/cli/catalog/util" "github.com/openshift/odo/pkg/odo/genericclioptions" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/odo/util/pushtarget" "github.com/openshift/odo/pkg/util" "github.com/spf13/cobra" @@ -51,28 +50,24 @@ func (o *ListComponentsOptions) Complete(name string, cmd *cobra.Command, args [ tasks.Add(util.ConcurrentTask{ToRun: func(errChannel chan error) { o.catalogList, err = catalog.ListComponents(o.Client) if err != nil { - if experimental.IsExperimentalModeEnabled() { - klog.V(4).Info("Please log in to an OpenShift cluster to list OpenShift/s2i components") - } else { - errChannel <- err - } + klog.V(4).Info("Please log in to an OpenShift cluster to list OpenShift/s2i components") + // S2I Only + // errChannel <- err } else { o.catalogList.Items = catalogutil.FilterHiddenComponents(o.catalogList.Items) } }}) } - if experimental.IsExperimentalModeEnabled() { - tasks.Add(util.ConcurrentTask{ToRun: func(errChannel chan error) { - o.catalogDevfileList, err = catalog.ListDevfileComponents("") - if o.catalogDevfileList.DevfileRegistries == nil { - log.Warning("Please run 'odo registry add ' to add registry for listing devfile components\n") - } - if err != nil { - errChannel <- err - } - }}) - } + tasks.Add(util.ConcurrentTask{ToRun: func(errChannel chan error) { + o.catalogDevfileList, err = catalog.ListDevfileComponents("") + if o.catalogDevfileList.DevfileRegistries == nil { + log.Warning("Please run 'odo registry add ' to add registry for listing devfile components\n") + } + if err != nil { + errChannel <- err + } + }}) return tasks.Run() } @@ -101,19 +96,17 @@ func (o *ListComponentsOptions) Run() (err error) { supported, _ := catalog.SliceSupportedTags(image) o.catalogList.Items[i].Spec.SupportedTags = supported } - if experimental.IsExperimentalModeEnabled() { - combinedList := combinedCatalogList{ - TypeMeta: metav1.TypeMeta{ - Kind: "List", - APIVersion: "odo.dev/v1alpha1", - }, - S2iItems: o.catalogList.Items, - DevfileItems: o.catalogDevfileList.Items, - } - machineoutput.OutputSuccess(combinedList) - } else { - machineoutput.OutputSuccess(o.catalogList) + combinedList := combinedCatalogList{ + TypeMeta: metav1.TypeMeta{ + Kind: "List", + APIVersion: "odo.dev/v1alpha1", + }, + S2iItems: o.catalogList.Items, + DevfileItems: o.catalogDevfileList.Items, } + machineoutput.OutputSuccess(combinedList) + // S2I Only + // machineoutput.OutputSuccess(o.catalogList) } else { w := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) var supCatalogList, unsupCatalogList []catalog.ComponentType diff --git a/pkg/odo/cli/catalog/list/list.go b/pkg/odo/cli/catalog/list/list.go index 5bf88b0100b..5b7b840487e 100644 --- a/pkg/odo/cli/catalog/list/list.go +++ b/pkg/odo/cli/catalog/list/list.go @@ -2,6 +2,7 @@ package list import ( "fmt" + "github.com/openshift/odo/pkg/odo/util" "github.com/spf13/cobra" ) diff --git a/pkg/odo/cli/catalog/list/services.go b/pkg/odo/cli/catalog/list/services.go index 0a3b4c2b513..e39e9fbd377 100644 --- a/pkg/odo/cli/catalog/list/services.go +++ b/pkg/odo/cli/catalog/list/services.go @@ -8,7 +8,6 @@ import ( "github.com/openshift/odo/pkg/machineoutput" "github.com/openshift/odo/pkg/odo/cli/catalog/util" "github.com/openshift/odo/pkg/odo/genericclioptions" - "github.com/openshift/odo/pkg/odo/util/experimental" olm "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" "github.com/spf13/cobra" ) @@ -35,58 +34,63 @@ func NewListServicesOptions() *ListServicesOptions { // Complete completes ListServicesOptions after they've been created func (o *ListServicesOptions) Complete(name string, cmd *cobra.Command, args []string) (err error) { - if experimental.IsExperimentalModeEnabled() { - var noCsvs, noServices bool - o.Context = genericclioptions.NewContext(cmd) - o.csvs, err = o.KClient.GetClusterServiceVersionList() - if err != nil { - // Error only occurs when OperatorHub is not installed/enabled on the - // Kubernetes or OpenShift 4.x cluster. It doesn't occur when there are - // no operators installed. - noCsvs = true - } + var noCsvs, noServices bool + o.Context = genericclioptions.NewContext(cmd) + o.csvs, err = o.KClient.GetClusterServiceVersionList() + if err != nil { + // Error only occurs when OperatorHub is not installed/enabled on the + // Kubernetes or OpenShift 4.x cluster. It doesn't occur when there are + // no operators installed. + noCsvs = true + } - o.services, err = catalog.ListServices(o.Client) - if err != nil { - // Error occurs if Service Catalog is not enabled on the OpenShift - // 3.x/4.x cluster - noServices = true - // But we don't care about the Service Catalog not being enabled if - // it's 4.x or k8s cluster - if !noCsvs { - err = nil - } + o.services, err = catalog.ListServices(o.Client) + if err != nil { + // Error occurs if Service Catalog is not enabled on the OpenShift + // 3.x/4.x cluster + noServices = true + // But we don't care about the Service Catalog not being enabled if + // it's 4.x or k8s cluster + if !noCsvs { + err = nil } + } - if noCsvs && noServices { - // Neither OperatorHub nor Service Catalog is enabled on the cluster - return fmt.Errorf("unable to list services because neither Service Catalog nor Operator Hub is enabled in your cluster: %v", err) - } - o.services = util.FilterHiddenServices(o.services) - } else { - o.Context = genericclioptions.NewContext(cmd) - o.services, err = catalog.ListServices(o.Client) - if err != nil { - return fmt.Errorf("unable to list services because Service Catalog is not enabled in your cluster: %v", err) + if noCsvs && noServices { + // Neither OperatorHub nor Service Catalog is enabled on the cluster + return fmt.Errorf("unable to list services because neither Service Catalog nor Operator Hub is enabled in your cluster: %v", err) + } + o.services = util.FilterHiddenServices(o.services) + // S2I Only + /* + } else { + o.Context = genericclioptions.NewContext(cmd) + o.services, err = catalog.ListServices(o.Client) + if err != nil { + return fmt.Errorf("unable to list services because Service Catalog is not enabled in your cluster: %v", err) + + } + o.services = util.FilterHiddenServices(o.services) } - o.services = util.FilterHiddenServices(o.services) - } + */ return } // Validate validates the ListServicesOptions based on completed values func (o *ListServicesOptions) Validate() (err error) { - if experimental.IsExperimentalModeEnabled() { - if len(o.services.Items) == 0 && len(o.csvs.Items) == 0 { - return fmt.Errorf("no deployable services/operators found") - } - } else { - if len(o.services.Items) == 0 { - return fmt.Errorf("no deployable services found") - } + if len(o.services.Items) == 0 && len(o.csvs.Items) == 0 { + return fmt.Errorf("no deployable services/operators found") } + // S2I Only + /* + } else { + if len(o.services.Items) == 0 { + return fmt.Errorf("no deployable services found") + } + } + */ return } @@ -95,14 +99,15 @@ func (o *ListServicesOptions) Run() (err error) { if log.IsJSON() { machineoutput.OutputSuccess(machineoutput.NewCatalogListOutput(&o.services, o.csvs)) } else { - if experimental.IsExperimentalModeEnabled() { - if len(o.csvs.Items) > 0 { - util.DisplayClusterServiceVersions(o.csvs) - } - } - if len(o.services.Items) > 0 { - util.DisplayServices(o.services) + if len(o.csvs.Items) > 0 { + util.DisplayClusterServiceVersions(o.csvs) } + // S2I Only + /* + if len(o.services.Items) > 0 { + util.DisplayServices(o.services) + } + */ } return } diff --git a/pkg/odo/cli/catalog/search/search.go b/pkg/odo/cli/catalog/search/search.go index e78c5a6a218..bd97d437ad3 100644 --- a/pkg/odo/cli/catalog/search/search.go +++ b/pkg/odo/cli/catalog/search/search.go @@ -2,6 +2,7 @@ package search import ( "fmt" + "github.com/openshift/odo/pkg/odo/util" "github.com/spf13/cobra" ) diff --git a/pkg/odo/cli/catalog/search/service.go b/pkg/odo/cli/catalog/search/service.go index 427f5c7062d..ab61c92a4db 100644 --- a/pkg/odo/cli/catalog/search/service.go +++ b/pkg/odo/cli/catalog/search/service.go @@ -6,7 +6,6 @@ import ( "github.com/openshift/odo/pkg/catalog" "github.com/openshift/odo/pkg/odo/cli/catalog/util" "github.com/openshift/odo/pkg/odo/genericclioptions" - "github.com/openshift/odo/pkg/odo/util/experimental" olm "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" "github.com/spf13/cobra" ) @@ -32,70 +31,74 @@ func NewSearchServiceOptions() *SearchServiceOptions { // Complete completes SearchServiceOptions after they've been created func (o *SearchServiceOptions) Complete(name string, cmd *cobra.Command, args []string) (err error) { - if experimental.IsExperimentalModeEnabled() { - var noCsvs, noServices bool - o.Context = genericclioptions.NewContext(cmd) - o.searchTerm = args[0] - o.csvs, err = o.KClient.SearchClusterServiceVersionList(o.searchTerm) - if err != nil { - // Error only occurs when OperatorHub is not installed/enabled on the - // Kubernetes or OpenShift 4.x cluster. It doesn't occur when there are - // no operators installed. - noCsvs = true - } + var noCsvs, noServices bool + o.Context = genericclioptions.NewContext(cmd) + o.searchTerm = args[0] + o.csvs, err = o.KClient.SearchClusterServiceVersionList(o.searchTerm) + if err != nil { + // Error only occurs when OperatorHub is not installed/enabled on the + // Kubernetes or OpenShift 4.x cluster. It doesn't occur when there are + // no operators installed. + noCsvs = true + } - o.services, err = catalog.SearchService(o.Client, o.searchTerm) - if err != nil { - // Error occurs if Service Catalog is not enabled on the OpenShift - // 3.x/4.x cluster - noServices = true - // But we don't care about the Service Catalog not being enabled if - // it's 4.x or k8s cluster - if !noCsvs { - err = nil - } + o.services, err = catalog.SearchService(o.Client, o.searchTerm) + if err != nil { + // Error occurs if Service Catalog is not enabled on the OpenShift + // 3.x/4.x cluster + noServices = true + // But we don't care about the Service Catalog not being enabled if + // it's 4.x or k8s cluster + if !noCsvs { + err = nil } + } - if noCsvs && noServices { - // Neither OperatorHub nor Service Catalog is enabled on the cluster - return fmt.Errorf("unable to list services because neither Service Catalog nor Operator Hub is enabled in your cluster: %v", err) - } - o.services = util.FilterHiddenServices(o.services) - } else { - o.Context = genericclioptions.NewContext(cmd) - o.searchTerm = args[0] - - o.services, err = catalog.SearchService(o.Client, o.searchTerm) - if err != nil { - return fmt.Errorf("unable to list services because Service Catalog is not enabled in your cluster: %v", err) - } - o.services = util.FilterHiddenServices(o.services) + if noCsvs && noServices { + // Neither OperatorHub nor Service Catalog is enabled on the cluster + return fmt.Errorf("unable to list services because neither Service Catalog nor Operator Hub is enabled in your cluster: %v", err) } + o.services = util.FilterHiddenServices(o.services) + + // S2I Only + /* + } else { + o.Context = genericclioptions.NewContext(cmd) + o.searchTerm = args[0] + + o.services, err = catalog.SearchService(o.Client, o.searchTerm) + if err != nil { + return fmt.Errorf("unable to list services because Service Catalog is not enabled in your cluster: %v", err) + } + o.services = util.FilterHiddenServices(o.services) + } + */ return err } // Validate validates the SearchServiceOptions based on completed values func (o *SearchServiceOptions) Validate() (err error) { - if experimental.IsExperimentalModeEnabled() { - if len(o.services.Items) == 0 && len(o.csvs.Items) == 0 { - return fmt.Errorf("no service matched the query: %s", o.searchTerm) - } - } else { - if len(o.services.Items) == 0 { - return fmt.Errorf("no service matched the query: %s", o.searchTerm) - } + if len(o.services.Items) == 0 && len(o.csvs.Items) == 0 { + return fmt.Errorf("no service matched the query: %s", o.searchTerm) } + // S2I Only + /* + } else { + if len(o.services.Items) == 0 { + return fmt.Errorf("no service matched the query: %s", o.searchTerm) + } + } + */ return } // Run contains the logic for the command associated with SearchServiceOptions func (o *SearchServiceOptions) Run() (err error) { - if experimental.IsExperimentalModeEnabled() { - if len(o.csvs.Items) > 0 { - util.DisplayClusterServiceVersions(o.csvs) - } + if len(o.csvs.Items) > 0 { + util.DisplayClusterServiceVersions(o.csvs) } + if len(o.services.Items) > 0 { util.DisplayServices(o.services) } diff --git a/pkg/odo/cli/cli.go b/pkg/odo/cli/cli.go index 9dbea1893c8..a84ffd123c0 100644 --- a/pkg/odo/cli/cli.go +++ b/pkg/odo/cli/cli.go @@ -9,7 +9,6 @@ import ( "github.com/openshift/odo/pkg/odo/cli/application" "github.com/openshift/odo/pkg/odo/cli/catalog" "github.com/openshift/odo/pkg/odo/cli/component" - "github.com/openshift/odo/pkg/odo/cli/config" "github.com/openshift/odo/pkg/odo/cli/debug" "github.com/openshift/odo/pkg/odo/cli/login" "github.com/openshift/odo/pkg/odo/cli/logout" @@ -18,13 +17,14 @@ import ( "github.com/openshift/odo/pkg/odo/cli/project" "github.com/openshift/odo/pkg/odo/cli/registry" "github.com/openshift/odo/pkg/odo/cli/service" - "github.com/openshift/odo/pkg/odo/cli/storage" + // NOT YET SUPPORTED BY DEVFILE. We must hide these. + // "github.com/openshift/odo/pkg/odo/cli/storage" + // "github.com/openshift/odo/pkg/odo/cli/config" "github.com/openshift/odo/pkg/odo/cli/url" "github.com/openshift/odo/pkg/odo/cli/utils" "github.com/openshift/odo/pkg/odo/cli/version" "github.com/openshift/odo/pkg/odo/util" odoutil "github.com/openshift/odo/pkg/odo/util" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -36,18 +36,18 @@ const OdoRecommendedName = "odo" var ( // We do not use ktemplates.Normalize here as it messed up the newlines.. - odoLong = `odo is a CLI tool for running OpenShift applications in a fast and automated manner. + odoLong = `odo is a CLI tool for running Kubernetes and OpenShift applications in a fast and automated manner. Reducing the complexity of deployment, odo adds iterative development without the worry of deploying your source code. -Find more information at https://github.com/openshift/odo` +Find more information at https://odo.dev` odoExample = ktemplates.Examples(` # Creating and deploying a Node.js project - git clone https://github.com/openshift/nodejs-ex && cd nodejs-ex - %[1]s create nodejs + %[1]s create nodejs --starter %[1]s push # Accessing your Node.js component - %[1]s url create`) + %[1]s url create + %[1]s push`) rootUsageTemplate = `Usage:{{if .Runnable}} {{if .HasAvailableFlags}}{{appendIfNotPresent .UseLine "[flags]"}}{{else}}{{.UseLine}}{{end}}{{end}}{{if .HasAvailableSubCommands}} @@ -184,33 +184,32 @@ func odoRootCmd(name, fullName string) *cobra.Command { component.NewCmdCreate(component.CreateRecommendedCommandName, util.GetFullName(fullName, component.CreateRecommendedCommandName)), component.NewCmdDelete(component.DeleteRecommendedCommandName, util.GetFullName(fullName, component.DeleteRecommendedCommandName)), component.NewCmdDescribe(component.DescribeRecommendedCommandName, util.GetFullName(fullName, component.DescribeRecommendedCommandName)), - component.NewCmdLink(component.LinkRecommendedCommandName, util.GetFullName(fullName, component.LinkRecommendedCommandName)), - component.NewCmdUnlink(component.UnlinkRecommendedCommandName, util.GetFullName(fullName, component.UnlinkRecommendedCommandName)), component.NewCmdList(component.ListRecommendedCommandName, util.GetFullName(fullName, component.ListRecommendedCommandName)), component.NewCmdLog(component.LogRecommendedCommandName, util.GetFullName(fullName, component.LogRecommendedCommandName)), component.NewCmdPush(component.PushRecommendedCommandName, util.GetFullName(fullName, component.PushRecommendedCommandName)), - component.NewCmdUpdate(component.UpdateRecommendedCommandName, util.GetFullName(fullName, component.UpdateRecommendedCommandName)), component.NewCmdWatch(component.WatchRecommendedCommandName, util.GetFullName(fullName, component.WatchRecommendedCommandName)), component.NewCmdExec(component.ExecRecommendedCommandName, util.GetFullName(fullName, component.ExecRecommendedCommandName)), login.NewCmdLogin(login.RecommendedCommandName, util.GetFullName(fullName, login.RecommendedCommandName)), logout.NewCmdLogout(logout.RecommendedCommandName, util.GetFullName(fullName, logout.RecommendedCommandName)), project.NewCmdProject(project.RecommendedCommandName, util.GetFullName(fullName, project.RecommendedCommandName)), service.NewCmdService(service.RecommendedCommandName, util.GetFullName(fullName, service.RecommendedCommandName)), - storage.NewCmdStorage(storage.RecommendedCommandName, util.GetFullName(fullName, storage.RecommendedCommandName)), url.NewCmdURL(url.RecommendedCommandName, util.GetFullName(fullName, url.RecommendedCommandName)), utils.NewCmdUtils(utils.RecommendedCommandName, util.GetFullName(fullName, utils.RecommendedCommandName)), version.NewCmdVersion(version.RecommendedCommandName, util.GetFullName(fullName, version.RecommendedCommandName)), - config.NewCmdConfiguration(config.RecommendedCommandName, util.GetFullName(fullName, config.RecommendedCommandName)), preference.NewCmdPreference(preference.RecommendedCommandName, util.GetFullName(fullName, preference.RecommendedCommandName)), debug.NewCmdDebug(debug.RecommendedCommandName, util.GetFullName(fullName, debug.RecommendedCommandName)), + // NOT SUPPORTED BY DEVFILE + // component.NewCmdUpdate(component.UpdateRecommendedCommandName, util.GetFullName(fullName, component.UpdateRecommendedCommandName)), + // config.NewCmdConfiguration(config.RecommendedCommandName, util.GetFullName(fullName, config.RecommendedCommandName)), + // storage.NewCmdStorage(storage.RecommendedCommandName, util.GetFullName(fullName, storage.RecommendedCommandName)), + // component.NewCmdLink(component.LinkRecommendedCommandName, util.GetFullName(fullName, component.LinkRecommendedCommandName)), + // component.NewCmdUnlink(component.UnlinkRecommendedCommandName, util.GetFullName(fullName, component.UnlinkRecommendedCommandName)), ) - if experimental.IsExperimentalModeEnabled() { - rootCmd.AddCommand( - registry.NewCmdRegistry(registry.RecommendedCommandName, util.GetFullName(fullName, registry.RecommendedCommandName)), - component.NewCmdTest(component.TestRecommendedCommandName, util.GetFullName(fullName, component.TestRecommendedCommandName)), - ) - } + rootCmd.AddCommand( + registry.NewCmdRegistry(registry.RecommendedCommandName, util.GetFullName(fullName, registry.RecommendedCommandName)), + component.NewCmdTest(component.TestRecommendedCommandName, util.GetFullName(fullName, component.TestRecommendedCommandName)), + ) odoutil.VisitCommands(rootCmd, reconfigureCmdWithSubcmd) diff --git a/pkg/odo/cli/component/create.go b/pkg/odo/cli/component/create.go index fc50925eb6e..0f718f9d39b 100644 --- a/pkg/odo/cli/component/create.go +++ b/pkg/odo/cli/component/create.go @@ -30,7 +30,6 @@ import ( "github.com/openshift/odo/pkg/odo/genericclioptions" odoutil "github.com/openshift/odo/pkg/odo/util" "github.com/openshift/odo/pkg/odo/util/completion" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/odo/util/pushtarget" "github.com/openshift/odo/pkg/util" @@ -333,200 +332,236 @@ func (co *CreateOptions) setResourceLimits() error { // Complete completes create args func (co *CreateOptions) Complete(name string, cmd *cobra.Command, args []string) (err error) { - if experimental.IsExperimentalModeEnabled() { - // Add a disclaimer that we are in *experimental mode* - log.Experimental("Experimental mode is enabled, use at your own risk") + // Configure the context + if co.componentContext != "" { + DevfilePath = filepath.Join(co.componentContext, devFile) + EnvFilePath = filepath.Join(co.componentContext, envFile) + ConfigFilePath = filepath.Join(co.componentContext, configFile) + co.CommonPushOptions.componentContext = co.componentContext + } + + if util.CheckPathExists(ConfigFilePath) || util.CheckPathExists(EnvFilePath) { + return errors.New("This directory already contains a component") + } - // Configure the context - if co.componentContext != "" { - DevfilePath = filepath.Join(co.componentContext, devFile) - EnvFilePath = filepath.Join(co.componentContext, envFile) - ConfigFilePath = filepath.Join(co.componentContext, configFile) - co.CommonPushOptions.componentContext = co.componentContext + if util.CheckPathExists(DevfilePath) && co.devfileMetadata.devfilePath.value != "" && !util.PathEqual(DevfilePath, co.devfileMetadata.devfilePath.value) { + return errors.New("This directory already contains a devfile, you can't specify devfile via --devfile") + } + + // Validate user specify devfile path + if co.devfileMetadata.devfilePath.value != "" { + fileErr := util.ValidateFile(co.devfileMetadata.devfilePath.value) + urlErr := util.ValidateURL(co.devfileMetadata.devfilePath.value) + if fileErr != nil && urlErr != nil { + return errors.Errorf("The devfile path you specify is invalid with either file error \"%v\" or url error \"%v\"", fileErr, urlErr) + } else if fileErr == nil { + co.devfileMetadata.devfilePath.protocol = "file" + } else if urlErr == nil { + co.devfileMetadata.devfilePath.protocol = "http(s)" } + } - if util.CheckPathExists(ConfigFilePath) || util.CheckPathExists(EnvFilePath) { - return errors.New("This directory already contains a component") + // Validate user specify registry + if co.devfileMetadata.devfileRegistry.Name != "" { + if co.devfileMetadata.devfilePath.value != "" { + return errors.New("You can't specify registry via --registry if you want to use the devfile that is specified via --devfile") } - if util.CheckPathExists(DevfilePath) && co.devfileMetadata.devfilePath.value != "" && !util.PathEqual(DevfilePath, co.devfileMetadata.devfilePath.value) { - return errors.New("This directory already contains a devfile, you can't specify devfile via --devfile") + registryList, err := catalog.GetDevfileRegistries(co.devfileMetadata.devfileRegistry.Name) + if err != nil { + return errors.Wrap(err, "Failed to get registry") + } + if len(registryList) == 0 { + return errors.Errorf("Registry %s doesn't exist, please specify a valid registry via --registry", co.devfileMetadata.devfileRegistry.Name) } + } - // Validate user specify devfile path - if co.devfileMetadata.devfilePath.value != "" { - fileErr := util.ValidateFile(co.devfileMetadata.devfilePath.value) - urlErr := util.ValidateURL(co.devfileMetadata.devfilePath.value) - if fileErr != nil && urlErr != nil { - return errors.Errorf("The devfile path you specify is invalid with either file error \"%v\" or url error \"%v\"", fileErr, urlErr) - } else if fileErr == nil { - co.devfileMetadata.devfilePath.protocol = "file" - } else if urlErr == nil { - co.devfileMetadata.devfilePath.protocol = "http(s)" - } + // Can't use the existing devfile or download devfile from registry, go to interactive mode + if len(args) == 0 && !util.CheckPathExists(DevfilePath) && co.devfileMetadata.devfilePath.value == "" { + co.interactive = true + } + + // Configure the default namespace + var defaultComponentNamespace string + // If the push target is set to Docker, we can't assume we have an active Kube context + if !pushtarget.IsPushTargetDocker() { + // Get current active namespace + client, err := kclient.New() + if err != nil { + return err } + defaultComponentNamespace = client.Namespace + } - // Validate user specify registry - if co.devfileMetadata.devfileRegistry.Name != "" { - if co.devfileMetadata.devfilePath.value != "" { - return errors.New("You can't specify registry via --registry if you want to use the devfile that is specified via --devfile") - } + var componentType string + var componentName string + var componentNamespace string + var catalogDevfileList catalog.DevfileComponentTypeList + isDevfileRegistryPresent := true // defaulted to true since odo ships with a default registry set - registryList, err := catalog.GetDevfileRegistries(co.devfileMetadata.devfileRegistry.Name) - if err != nil { - return errors.Wrap(err, "Failed to get registry") - } - if len(registryList) == 0 { - return errors.Errorf("Registry %s doesn't exist, please specify a valid registry via --registry", co.devfileMetadata.devfileRegistry.Name) - } + if co.interactive { + // Interactive mode + + // Get available devfile components for checking devfile compatibility + catalogDevfileList, err = catalog.ListDevfileComponents(co.devfileMetadata.devfileRegistry.Name) + if err != nil { + return err } - // Can't use the existing devfile or download devfile from registry, go to interactive mode - if len(args) == 0 && !util.CheckPathExists(DevfilePath) && co.devfileMetadata.devfilePath.value == "" { - co.interactive = true + if len(catalogDevfileList.DevfileRegistries) == 0 { + isDevfileRegistryPresent = false + log.Warning("Registry is empty, please run `odo registry add ` to add a registry\n") } - // Configure the default namespace - var defaultComponentNamespace string - // If the push target is set to Docker, we can't assume we have an active Kube context - if !pushtarget.IsPushTargetDocker() { - // Get current active namespace - client, err := kclient.New() - if err != nil { - return err + if isDevfileRegistryPresent { + // Component type: We provide devfile component list to let user choose + componentType = ui.SelectDevfileComponentType(catalogDevfileList.Items) + + // Component name: User needs to specify the componet name, by default it is component type that user chooses + componentName = ui.EnterDevfileComponentName(componentType) + + // Component namespace: User needs to specify component namespace, by default it is the current active namespace + if cmd.Flags().Changed("project") && !pushtarget.IsPushTargetDocker() { + componentNamespace, err = cmd.Flags().GetString("project") + if err != nil { + return err + } + } else if !pushtarget.IsPushTargetDocker() { + componentNamespace = ui.EnterDevfileComponentNamespace(defaultComponentNamespace) } - defaultComponentNamespace = client.Namespace } - var componentType string - var componentName string - var componentNamespace string - var catalogDevfileList catalog.DevfileComponentTypeList - isDevfileRegistryPresent := true // defaulted to true since odo ships with a default registry set + } else { + // Direct mode (User enters the full command) - if co.interactive { - // Interactive mode + if util.CheckPathExists(DevfilePath) || co.devfileMetadata.devfilePath.value != "" { + // Use existing devfile directly + + if len(args) > 1 { + return errors.Errorf("Accepts between 0 and 1 arg when using existing devfile, received %d", len(args)) + } + + // If user can use existing devfile directly, the first arg is component name instead of component type + if len(args) == 1 { + componentName = args[0] + } else { + currentDirPath, err := os.Getwd() + if err != nil { + return err + } + currentDirName := filepath.Base(currentDirPath) + componentName = currentDirName + } + + co.devfileMetadata.devfileSupport = true + } else { + // Download devfile from registry + + // Component type: Get from full command's first argument (mandatory in direct mode) + componentType = args[0] + + // Component name: Get from full command's second argument (optional in direct mode), by default it is component type from first argument + if len(args) == 2 { + componentName = args[1] + } else { + componentName = args[0] + } // Get available devfile components for checking devfile compatibility catalogDevfileList, err = catalog.ListDevfileComponents(co.devfileMetadata.devfileRegistry.Name) if err != nil { return err } + if co.devfileMetadata.devfileRegistry.Name != "" && catalogDevfileList.Items == nil { + return errors.Errorf("Can't create devfile component from registry %s", co.devfileMetadata.devfileRegistry.Name) + } if len(catalogDevfileList.DevfileRegistries) == 0 { isDevfileRegistryPresent = false log.Warning("Registry is empty, please run `odo registry add ` to add a registry\n") } + } - if isDevfileRegistryPresent { - // Component type: We provide devfile component list to let user choose - componentType = ui.SelectDevfileComponentType(catalogDevfileList.Items) - - // Component name: User needs to specify the componet name, by default it is component type that user chooses - componentName = ui.EnterDevfileComponentName(componentType) - - // Component namespace: User needs to specify component namespace, by default it is the current active namespace - if cmd.Flags().Changed("project") && !pushtarget.IsPushTargetDocker() { - componentNamespace, err = cmd.Flags().GetString("project") - if err != nil { - return err - } - } else if !pushtarget.IsPushTargetDocker() { - componentNamespace = ui.EnterDevfileComponentNamespace(defaultComponentNamespace) - } + // Component namespace: Get from --project flag or --namespace flag, by default it is the current active namespace + if co.devfileMetadata.componentNamespace == "" && !pushtarget.IsPushTargetDocker() { + + // Check to see if we've passed in "project", if not, default to the standard Kubernetes namespace + componentNamespace, err = retrieveCmdNamespace(cmd) + if err != nil { + return err } } else { - // Direct mode (User enters the full command) - - if util.CheckPathExists(DevfilePath) || co.devfileMetadata.devfilePath.value != "" { - // Use existing devfile directly + componentNamespace = defaultComponentNamespace + } + } - if len(args) > 1 { - return errors.Errorf("Accepts between 0 and 1 arg when using existing devfile, received %d", len(args)) - } + // Set devfileMetadata struct + co.devfileMetadata.componentType = componentType + co.devfileMetadata.componentName = strings.ToLower(componentName) + co.devfileMetadata.componentNamespace = strings.ToLower(componentNamespace) - // If user can use existing devfile directly, the first arg is component name instead of component type - if len(args) == 1 { - componentName = args[0] - } else { - currentDirPath, err := os.Getwd() - if err != nil { - return err - } - currentDirName := filepath.Base(currentDirPath) - componentName = currentDirName - } + if util.CheckPathExists(DevfilePath) || co.devfileMetadata.devfilePath.value != "" { + // Categorize the sections + log.Info("Validation") - co.devfileMetadata.devfileSupport = true + var devfileAbsolutePath string + if util.CheckPathExists(DevfilePath) || co.devfileMetadata.devfilePath.protocol == "file" { + var devfilePath string + if util.CheckPathExists(DevfilePath) { + devfilePath = DevfilePath } else { - // Download devfile from registry - - // Component type: Get from full command's first argument (mandatory in direct mode) - componentType = args[0] + devfilePath = co.devfileMetadata.devfilePath.value + } + devfileAbsolutePath, err = filepath.Abs(devfilePath) + if err != nil { + return err + } + } else if co.devfileMetadata.devfilePath.protocol == "http(s)" { + devfileAbsolutePath = co.devfileMetadata.devfilePath.value + } + devfileSpinner := log.Spinnerf("Creating a devfile component from devfile path: %s", devfileAbsolutePath) + defer devfileSpinner.End(true) - // Component name: Get from full command's second argument (optional in direct mode), by default it is component type from first argument - if len(args) == 2 { - componentName = args[1] - } else { - componentName = args[0] - } + // Initialize envinfo + err = co.InitEnvInfoFromContext() + if err != nil { + return err + } - // Get available devfile components for checking devfile compatibility - catalogDevfileList, err = catalog.ListDevfileComponents(co.devfileMetadata.devfileRegistry.Name) - if err != nil { - return err - } - if co.devfileMetadata.devfileRegistry.Name != "" && catalogDevfileList.Items == nil { - return errors.Errorf("Can't create devfile component from registry %s", co.devfileMetadata.devfileRegistry.Name) - } + return nil + } - if len(catalogDevfileList.DevfileRegistries) == 0 { - isDevfileRegistryPresent = false - log.Warning("Registry is empty, please run `odo registry add ` to add a registry\n") - } - } + if isDevfileRegistryPresent { + // Categorize the sections + log.Info("Validation") - // Component namespace: Get from --project flag or --namespace flag, by default it is the current active namespace - if co.devfileMetadata.componentNamespace == "" && !pushtarget.IsPushTargetDocker() { + // Since we need to support both devfile and s2i, so we have to check if the component type is + // supported by devfile, if it is supported we return and will download the corresponding devfile later, + // if it is not supported we still need to run all the codes related with s2i after devfile compatibility check - // Check to see if we've passed in "project", if not, default to the standard Kubernetes namespace - componentNamespace, err = retrieveCmdNamespace(cmd) - if err != nil { - return err - } + hasComponent := false - } else { - componentNamespace = defaultComponentNamespace + for _, devfileComponent := range catalogDevfileList.Items { + if co.devfileMetadata.componentType == devfileComponent.Name { + hasComponent = true + co.devfileMetadata.devfileSupport = true + co.devfileMetadata.devfileLink = devfileComponent.Link + co.devfileMetadata.devfileRegistry = devfileComponent.Registry + break } } - // Set devfileMetadata struct - co.devfileMetadata.componentType = componentType - co.devfileMetadata.componentName = strings.ToLower(componentName) - co.devfileMetadata.componentNamespace = strings.ToLower(componentNamespace) + existSpinner := log.Spinner("Checking devfile existence") + if hasComponent { + existSpinner.End(true) + } else { + existSpinner.End(false) + } - if util.CheckPathExists(DevfilePath) || co.devfileMetadata.devfilePath.value != "" { - // Categorize the sections - log.Info("Validation") - - var devfileAbsolutePath string - if util.CheckPathExists(DevfilePath) || co.devfileMetadata.devfilePath.protocol == "file" { - var devfilePath string - if util.CheckPathExists(DevfilePath) { - devfilePath = DevfilePath - } else { - devfilePath = co.devfileMetadata.devfilePath.value - } - devfileAbsolutePath, err = filepath.Abs(devfilePath) - if err != nil { - return err - } - } else if co.devfileMetadata.devfilePath.protocol == "http(s)" { - devfileAbsolutePath = co.devfileMetadata.devfilePath.value - } - devfileSpinner := log.Spinnerf("Creating a devfile component from devfile path: %s", devfileAbsolutePath) - defer devfileSpinner.End(true) + supportSpinner := log.Spinner("Checking devfile compatibility") + if co.devfileMetadata.devfileSupport { + registrySpinner := log.Spinnerf("Creating a devfile component from registry: %s", co.devfileMetadata.devfileRegistry.Name) // Initialize envinfo err = co.InitEnvInfoFromContext() @@ -534,59 +569,18 @@ func (co *CreateOptions) Complete(name string, cmd *cobra.Command, args []string return err } + supportSpinner.End(true) + registrySpinner.End(true) return nil } + supportSpinner.End(false) - if isDevfileRegistryPresent { - // Categorize the sections - log.Info("Validation") - - // Since we need to support both devfile and s2i, so we have to check if the component type is - // supported by devfile, if it is supported we return and will download the corresponding devfile later, - // if it is not supported we still need to run all the codes related with s2i after devfile compatibility check - - hasComponent := false - - for _, devfileComponent := range catalogDevfileList.Items { - if co.devfileMetadata.componentType == devfileComponent.Name { - hasComponent = true - co.devfileMetadata.devfileSupport = true - co.devfileMetadata.devfileLink = devfileComponent.Link - co.devfileMetadata.devfileRegistry = devfileComponent.Registry - break - } - } - - existSpinner := log.Spinner("Checking devfile existence") - if hasComponent { - existSpinner.End(true) - } else { - existSpinner.End(false) - } - - supportSpinner := log.Spinner("Checking devfile compatibility") - if co.devfileMetadata.devfileSupport { - registrySpinner := log.Spinnerf("Creating a devfile component from registry: %s", co.devfileMetadata.devfileRegistry.Name) - - // Initialize envinfo - err = co.InitEnvInfoFromContext() - if err != nil { - return err - } - - supportSpinner.End(true) - registrySpinner.End(true) - return nil - } - supportSpinner.End(false) - - // Currently only devfile component supports --registry flag, so if user specifies --registry when creating devfile component, - // we should error out instead of running s2i componet code and throw warning message - if co.devfileMetadata.devfileRegistry.Name != "" { - return errors.Errorf("Devfile component type %s is not supported, please run `odo catalog list components` for a list of supported devfile component types", co.devfileMetadata.componentType) - } else { - log.Warningf("Devfile component type %s is not supported, please run `odo catalog list components` for a list of supported devfile component types", co.devfileMetadata.componentType) - } + // Currently only devfile component supports --registry flag, so if user specifies --registry when creating devfile component, + // we should error out instead of running s2i componet code and throw warning message + if co.devfileMetadata.devfileRegistry.Name != "" { + return errors.Errorf("Devfile component type %s is not supported, please run `odo catalog list components` for a list of supported devfile component types", co.devfileMetadata.componentType) + } else { + log.Warningf("Devfile component type %s is not supported, please run `odo catalog list components` for a list of supported devfile component types", co.devfileMetadata.componentType) } } @@ -793,29 +787,27 @@ func (co *CreateOptions) Complete(name string, cmd *cobra.Command, args []string // Validate validates the create parameters func (co *CreateOptions) Validate() (err error) { - if experimental.IsExperimentalModeEnabled() { - if co.devfileMetadata.devfileSupport { - // Validate if the devfile component that user wants to create already exists - spinner := log.Spinner("Validating devfile component") - defer spinner.End(false) + if co.devfileMetadata.devfileSupport { + // Validate if the devfile component that user wants to create already exists + spinner := log.Spinner("Validating devfile component") + defer spinner.End(false) + + err = util.ValidateK8sResourceName("component name", co.devfileMetadata.componentName) + if err != nil { + return err + } - err = util.ValidateK8sResourceName("component name", co.devfileMetadata.componentName) + // Only validate namespace if pushtarget isn't docker + if !pushtarget.IsPushTargetDocker() { + err := util.ValidateK8sResourceName("component namespace", co.devfileMetadata.componentNamespace) if err != nil { return err } + } - // Only validate namespace if pushtarget isn't docker - if !pushtarget.IsPushTargetDocker() { - err := util.ValidateK8sResourceName("component namespace", co.devfileMetadata.componentNamespace) - if err != nil { - return err - } - } - - spinner.End(true) + spinner.End(true) - return nil - } + return nil } log.Info("Validation") @@ -940,88 +932,86 @@ func (co *CreateOptions) downloadProject(projectPassed string) error { // Run has the logic to perform the required actions as part of command func (co *CreateOptions) Run() (err error) { - if experimental.IsExperimentalModeEnabled() { - if co.devfileMetadata.devfileSupport { - // Use existing devfile directly from --devfile flag - if co.devfileMetadata.devfilePath.value != "" { - if co.devfileMetadata.devfilePath.protocol == "http(s)" { - // User specify devfile path is http(s) URL - params := util.DownloadParams{ - Request: util.HTTPRequestParams{ - URL: co.devfileMetadata.devfilePath.value, - Token: co.devfileMetadata.token, - }, - Filepath: DevfilePath, - } - err = util.DownloadFile(params) - if err != nil { - return errors.Wrapf(err, "failed to download devfile for devfile component from %s", co.devfileMetadata.devfilePath.value) - } - } else if co.devfileMetadata.devfilePath.protocol == "file" { - // User specify devfile path is file system link - info, err := os.Stat(co.devfileMetadata.devfilePath.value) - if err != nil { - return err - } - err = util.CopyFile(co.devfileMetadata.devfilePath.value, DevfilePath, info) - if err != nil { - return errors.Wrapf(err, "failed to copy devfile from %s to %s", co.devfileMetadata.devfilePath, DevfilePath) - } - } - } - - if !util.CheckPathExists(DevfilePath) { - // Download devfile from registry + if co.devfileMetadata.devfileSupport { + // Use existing devfile directly from --devfile flag + if co.devfileMetadata.devfilePath.value != "" { + if co.devfileMetadata.devfilePath.protocol == "http(s)" { + // User specify devfile path is http(s) URL params := util.DownloadParams{ Request: util.HTTPRequestParams{ - URL: co.devfileMetadata.devfileRegistry.URL + co.devfileMetadata.devfileLink, + URL: co.devfileMetadata.devfilePath.value, + Token: co.devfileMetadata.token, }, Filepath: DevfilePath, } - if registryUtil.IsSecure(co.devfileMetadata.devfileRegistry.Name) { - token, err := keyring.Get(util.CredentialPrefix+co.devfileMetadata.devfileRegistry.Name, "default") - if err != nil { - return errors.Wrap(err, "unable to get secure registry credential from keyring") - } - params.Request.Token = token + err = util.DownloadFile(params) + if err != nil { + return errors.Wrapf(err, "failed to download devfile for devfile component from %s", co.devfileMetadata.devfilePath.value) + } + } else if co.devfileMetadata.devfilePath.protocol == "file" { + // User specify devfile path is file system link + info, err := os.Stat(co.devfileMetadata.devfilePath.value) + if err != nil { + return err } - err := util.DownloadFile(params) + err = util.CopyFile(co.devfileMetadata.devfilePath.value, DevfilePath, info) if err != nil { - return errors.Wrapf(err, "failed to download devfile for devfile component from %s", co.devfileMetadata.devfileRegistry.URL+co.devfileMetadata.devfileLink) + return errors.Wrapf(err, "failed to copy devfile from %s to %s", co.devfileMetadata.devfilePath, DevfilePath) } } + } - if util.CheckPathExists(DevfilePath) && co.devfileMetadata.starter != "" { - err = co.downloadProject(co.devfileMetadata.starter) + if !util.CheckPathExists(DevfilePath) { + // Download devfile from registry + params := util.DownloadParams{ + Request: util.HTTPRequestParams{ + URL: co.devfileMetadata.devfileRegistry.URL + co.devfileMetadata.devfileLink, + }, + Filepath: DevfilePath, + } + if registryUtil.IsSecure(co.devfileMetadata.devfileRegistry.Name) { + token, err := keyring.Get(util.CredentialPrefix+co.devfileMetadata.devfileRegistry.Name, "default") if err != nil { - return errors.Wrap(err, "failed to download project for devfile component") + return errors.Wrap(err, "unable to get secure registry credential from keyring") } + params.Request.Token = token } - - // Generate env file - err = co.EnvSpecificInfo.SetComponentSettings(envinfo.ComponentSettings{Name: co.devfileMetadata.componentName, Namespace: co.devfileMetadata.componentNamespace}) + err := util.DownloadFile(params) if err != nil { - return errors.Wrap(err, "failed to create env file for devfile component") + return errors.Wrapf(err, "failed to download devfile for devfile component from %s", co.devfileMetadata.devfileRegistry.URL+co.devfileMetadata.devfileLink) } + } - sourcePath, err := util.GetAbsPath(co.componentContext) + if util.CheckPathExists(DevfilePath) && co.devfileMetadata.starter != "" { + err = co.downloadProject(co.devfileMetadata.starter) if err != nil { - return errors.Wrap(err, "unable to get source path") + return errors.Wrap(err, "failed to download project for devfile component") } + } - ignoreFile, err := util.CheckGitIgnoreFile(sourcePath) - if err != nil { - return err - } + // Generate env file + err = co.EnvSpecificInfo.SetComponentSettings(envinfo.ComponentSettings{Name: co.devfileMetadata.componentName, Namespace: co.devfileMetadata.componentNamespace}) + if err != nil { + return errors.Wrap(err, "failed to create env file for devfile component") + } - err = util.AddFileToIgnoreFile(ignoreFile, filepath.Join(co.componentContext, envDir)) - if err != nil { - return err - } + sourcePath, err := util.GetAbsPath(co.componentContext) + if err != nil { + return errors.Wrap(err, "unable to get source path") + } - log.Italic("\nPlease use `odo push` command to create the component with source deployed") - return nil + ignoreFile, err := util.CheckGitIgnoreFile(sourcePath) + if err != nil { + return err + } + + err = util.AddFileToIgnoreFile(ignoreFile, filepath.Join(co.componentContext, envDir)) + if err != nil { + return err } + + log.Italic("\nPlease use `odo push` command to create the component with source deployed") + return nil } err = co.LocalConfigInfo.SetComponentSettings(co.componentSettings) @@ -1143,13 +1133,11 @@ func NewCmdCreate(name, fullName string) *cobra.Command { componentCreateCmd.Flags().StringSliceVarP(&co.componentPorts, "port", "p", []string{}, "Ports to be used when the component is created (ex. 8080,8100/tcp,9100/udp)") componentCreateCmd.Flags().StringSliceVar(&co.componentEnvVars, "env", []string{}, "Environmental variables for the component. For example --env VariableName=Value") - if experimental.IsExperimentalModeEnabled() { - componentCreateCmd.Flags().StringVar(&co.devfileMetadata.starter, "starter", "", "Download a project specified in the devfile") - componentCreateCmd.Flags().Lookup("starter").NoOptDefVal = defaultProjectName //Default value to pass to the flag if one is not specified. - componentCreateCmd.Flags().StringVar(&co.devfileMetadata.devfileRegistry.Name, "registry", "", "Create devfile component from specific registry") - componentCreateCmd.Flags().StringVar(&co.devfileMetadata.devfilePath.value, "devfile", "", "Path to the user specify devfile") - componentCreateCmd.Flags().StringVar(&co.devfileMetadata.token, "token", "", "Token to be used when downloading devfile from the devfile path that is specified via --devfile") - } + componentCreateCmd.Flags().StringVar(&co.devfileMetadata.starter, "starter", "", "Download a project specified in the devfile") + componentCreateCmd.Flags().Lookup("starter").NoOptDefVal = defaultProjectName //Default value to pass to the flag if one is not specified. + componentCreateCmd.Flags().StringVar(&co.devfileMetadata.devfileRegistry.Name, "registry", "", "Create devfile component from specific registry") + componentCreateCmd.Flags().StringVar(&co.devfileMetadata.devfilePath.value, "devfile", "", "Path to the user specify devfile") + componentCreateCmd.Flags().StringVar(&co.devfileMetadata.token, "token", "", "Token to be used when downloading devfile from the devfile path that is specified via --devfile") componentCreateCmd.SetUsageTemplate(odoutil.CmdUsageTemplate) diff --git a/pkg/odo/cli/component/delete.go b/pkg/odo/cli/component/delete.go index c40ad424afc..716994e1eb5 100644 --- a/pkg/odo/cli/component/delete.go +++ b/pkg/odo/cli/component/delete.go @@ -6,7 +6,6 @@ import ( "path/filepath" "github.com/openshift/odo/pkg/envinfo" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/odo/util/pushtarget" "github.com/openshift/odo/pkg/util" @@ -59,8 +58,8 @@ func NewDeleteOptions() *DeleteOptions { func (do *DeleteOptions) Complete(name string, cmd *cobra.Command, args []string) (err error) { do.devfilePath = filepath.Join(do.componentContext, DevfilePath) - // if experimental mode is enabled and devfile is present - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(do.devfilePath) { + // If Devfile is present + if util.CheckPathExists(do.devfilePath) { do.EnvSpecificInfo, err = envinfo.NewEnvSpecificInfo(do.componentContext) if err != nil { return err @@ -86,8 +85,8 @@ func (do *DeleteOptions) Complete(name string, cmd *cobra.Command, args []string // Validate validates the list parameters func (do *DeleteOptions) Validate() (err error) { - // if experimental mode is enabled and devfile is present - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(do.devfilePath) { + // If Devfile is present + if util.CheckPathExists(do.devfilePath) { return nil } @@ -113,7 +112,8 @@ func (do *DeleteOptions) Run() (err error) { klog.V(4).Infof("component delete called") klog.V(4).Infof("args: %#v", do) - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(do.devfilePath) { + // If devfile is present + if util.CheckPathExists(do.devfilePath) { return do.DevFileRun() } diff --git a/pkg/odo/cli/component/log.go b/pkg/odo/cli/component/log.go index 57ac5c8afbc..f78a7a83ebb 100644 --- a/pkg/odo/cli/component/log.go +++ b/pkg/odo/cli/component/log.go @@ -11,7 +11,6 @@ import ( appCmd "github.com/openshift/odo/pkg/odo/cli/application" projectCmd "github.com/openshift/odo/pkg/odo/cli/project" "github.com/openshift/odo/pkg/odo/util/completion" - "github.com/openshift/odo/pkg/odo/util/experimental" ktemplates "k8s.io/kubectl/pkg/util/templates" odoutil "github.com/openshift/odo/pkg/odo/util" @@ -47,8 +46,8 @@ func (lo *LogOptions) Complete(name string, cmd *cobra.Command, args []string) ( lo.devfilePath = "devfile.yaml" lo.devfilePath = filepath.Join(lo.componentContext, lo.devfilePath) - // if experimental mode is enabled and devfile is present - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(lo.devfilePath) { + // If devfile is present + if util.CheckPathExists(lo.devfilePath) { lo.ComponentOptions.Context = genericclioptions.NewDevfileContext(cmd) return nil } @@ -65,8 +64,8 @@ func (lo *LogOptions) Validate() (err error) { func (lo *LogOptions) Run() (err error) { stdout := os.Stdout - // If experimental mode is enabled, use devfile push - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(lo.devfilePath) { + // If devfile is present + if util.CheckPathExists(lo.devfilePath) { err = lo.DevfileComponentLog() } else { // Retrieve the log diff --git a/pkg/odo/cli/component/push.go b/pkg/odo/cli/component/push.go index 51e0840c286..9ac27bcf0ee 100644 --- a/pkg/odo/cli/component/push.go +++ b/pkg/odo/cli/component/push.go @@ -14,7 +14,6 @@ import ( projectCmd "github.com/openshift/odo/pkg/odo/cli/project" "github.com/openshift/odo/pkg/odo/genericclioptions" "github.com/openshift/odo/pkg/odo/util/completion" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/util" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -83,8 +82,7 @@ func (po *PushOptions) CompleteDevfilePath() { func (po *PushOptions) Complete(name string, cmd *cobra.Command, args []string) (err error) { po.CompleteDevfilePath() - // if experimental mode is enabled and devfile is present - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(po.DevfilePath) { + if util.CheckPathExists(po.DevfilePath) { po.Devfile, err = parser.ParseAndValidate(po.DevfilePath) if err != nil { @@ -172,10 +170,10 @@ func (po *PushOptions) Complete(name string, cmd *cobra.Command, args []string) // Validate validates the push parameters func (po *PushOptions) Validate() (err error) { - // If the experimental flag is set and devfile is present, then we do *not* validate + // If devfile is present, then we do *not* validate // TODO: We need to clean this section up a bit.. We should also validate Devfile here // too. - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(po.DevfilePath) { + if util.CheckPathExists(po.DevfilePath) { return nil } @@ -206,14 +204,14 @@ func (po *PushOptions) Validate() (err error) { // Run has the logic to perform the required actions as part of command func (po *PushOptions) Run() (err error) { - // If experimental mode is enabled, use devfile push - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(po.DevfilePath) { + // If Devfile exists + if util.CheckPathExists(po.DevfilePath) { // Return Devfile push return po.DevfilePush() - } else { - // Legacy odo push - return po.Push() } + + // Legacy odo push + return po.Push() } // NewCmdPush implements the push odo command @@ -224,13 +222,11 @@ func NewCmdPush(name, fullName string) *cobra.Command { pushCmdExampleText := pushCmdExample - if experimental.IsExperimentalModeEnabled() { - // The '-o json' option should only appear in help output when experimental mode is enabled. - annotations["machineoutput"] = "json" + // The '-o json' option should only appear in help output when experimental mode is enabled. + annotations["machineoutput"] = "json" - // The '-o json' example should likewise only appear in experimental only. - pushCmdExampleText += pushCmdExampleExperimentalOnly - } + // The '-o json' example should likewise only appear in experimental only. + pushCmdExampleText += pushCmdExampleExperimentalOnly var pushCmd = &cobra.Command{ Use: fmt.Sprintf("%s [component name]", name), @@ -251,15 +247,12 @@ func NewCmdPush(name, fullName string) *cobra.Command { pushCmd.Flags().BoolVar(&po.pushSource, "source", false, "Use source flag to only push latest source on to cluster") pushCmd.Flags().BoolVarP(&po.forceBuild, "force-build", "f", false, "Use force-build flag to force building the component") - // enable devfile flag if experimental mode is enabled - if experimental.IsExperimentalModeEnabled() { - pushCmd.Flags().StringVar(&po.namespace, "namespace", "", "Namespace to push the component to") - pushCmd.Flags().StringVar(&po.devfileInitCommand, "init-command", "", "Devfile Init Command to execute") - pushCmd.Flags().StringVar(&po.devfileBuildCommand, "build-command", "", "Devfile Build Command to execute") - pushCmd.Flags().StringVar(&po.devfileRunCommand, "run-command", "", "Devfile Run Command to execute") - pushCmd.Flags().BoolVar(&po.debugRun, "debug", false, "Runs the component in debug mode") - pushCmd.Flags().StringVar(&po.devfileDebugCommand, "debug-command", "", "Devfile Debug Command to execute") - } + pushCmd.Flags().StringVar(&po.namespace, "namespace", "", "Namespace to push the component to") + pushCmd.Flags().StringVar(&po.devfileInitCommand, "init-command", "", "Devfile Init Command to execute") + pushCmd.Flags().StringVar(&po.devfileBuildCommand, "build-command", "", "Devfile Build Command to execute") + pushCmd.Flags().StringVar(&po.devfileRunCommand, "run-command", "", "Devfile Run Command to execute") + pushCmd.Flags().BoolVar(&po.debugRun, "debug", false, "Runs the component in debug mode") + pushCmd.Flags().StringVar(&po.devfileDebugCommand, "debug-command", "", "Devfile Debug Command to execute") //Adding `--project` flag projectCmd.AddProjectFlag(pushCmd) diff --git a/pkg/odo/cli/component/update.go b/pkg/odo/cli/component/update.go index 7e85e5e9a74..c829ae3ddb1 100644 --- a/pkg/odo/cli/component/update.go +++ b/pkg/odo/cli/component/update.go @@ -18,7 +18,6 @@ import ( "github.com/openshift/odo/pkg/odo/genericclioptions" odoutil "github.com/openshift/odo/pkg/odo/util" "github.com/openshift/odo/pkg/odo/util/completion" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/util" ktemplates "k8s.io/kubectl/pkg/util/templates" @@ -76,7 +75,7 @@ func NewUpdateOptions() *UpdateOptions { func (uo *UpdateOptions) Complete(name string, cmd *cobra.Command, args []string) (err error) { uo.devfilePath = filepath.Join(uo.componentContext, DevfilePath) - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(uo.devfilePath) { + if util.CheckPathExists(uo.devfilePath) { // Add a disclaimer that we are in *experimental mode* log.Experimental("Experimental mode is enabled, use at your own risk") @@ -96,8 +95,8 @@ func (uo *UpdateOptions) Complete(name string, cmd *cobra.Command, args []string // Validate validates the update parameters func (uo *UpdateOptions) Validate() (err error) { - // if experimental mode is enabled and devfile is present - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(uo.devfilePath) { + // If devfile is present + if util.CheckPathExists(uo.devfilePath) { return nil } @@ -169,8 +168,8 @@ func (uo *UpdateOptions) Validate() (err error) { // Run has the logic to perform the required actions as part of command func (uo *UpdateOptions) Run() (err error) { - // if experimental mode is enabled and devfile is present - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(uo.devfilePath) { + // If devfile is present + if util.CheckPathExists(uo.devfilePath) { return errors.New(devfileErrorString) } diff --git a/pkg/odo/cli/component/watch.go b/pkg/odo/cli/component/watch.go index d11491d3b82..75f59f5a68a 100644 --- a/pkg/odo/cli/component/watch.go +++ b/pkg/odo/cli/component/watch.go @@ -14,7 +14,6 @@ import ( "github.com/openshift/odo/pkg/occlient" appCmd "github.com/openshift/odo/pkg/odo/cli/application" projectCmd "github.com/openshift/odo/pkg/odo/cli/project" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/odo/util/pushtarget" "github.com/pkg/errors" ktemplates "k8s.io/kubectl/pkg/util/templates" @@ -77,8 +76,8 @@ func NewWatchOptions() *WatchOptions { func (wo *WatchOptions) Complete(name string, cmd *cobra.Command, args []string) (err error) { wo.devfilePath = filepath.Join(wo.componentContext, DevfilePath) - // if experimental mode is enabled and devfile is present - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(wo.devfilePath) { + // If devfile is present + if util.CheckPathExists(wo.devfilePath) { wo.Context = genericclioptions.NewDevfileContext(cmd) // Set the source path to either the context or current working directory (if context not set) @@ -156,8 +155,8 @@ func (wo *WatchOptions) Validate() (err error) { klog.V(4).Infof("delay=0 means changes will be pushed as soon as they are detected which can cause performance issues") } - // if experimental mode is enabled and devfile is present, return. The rest of the validation is for non-devfile components - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(wo.devfilePath) { + // If Devfile is present + if util.CheckPathExists(wo.devfilePath) { exists, err := wo.devfileHandler.DoesComponentExist(wo.componentName) if err != nil { return err @@ -198,8 +197,8 @@ func (wo *WatchOptions) Validate() (err error) { // Run has the logic to perform the required actions as part of command func (wo *WatchOptions) Run() (err error) { - // if experimental mode is enabled and devfile is present - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(wo.devfilePath) { + // If devfile is present + if util.CheckPathExists(wo.devfilePath) { err = watch.DevfileWatchAndPush( os.Stdout, @@ -252,9 +251,7 @@ func NewCmdWatch(name, fullName string) *cobra.Command { example := fmt.Sprintf(watchExample, fullName) usage := name - if experimental.IsExperimentalModeEnabled() { - example = fmt.Sprintf(watchExampleWithDevfile, fullName) - } + example = fmt.Sprintf(watchExampleWithDevfile, fullName) var watchCmd = &cobra.Command{ Use: usage, @@ -274,12 +271,9 @@ func NewCmdWatch(name, fullName string) *cobra.Command { watchCmd.SetUsageTemplate(odoutil.CmdUsageTemplate) - // enable devfile flag if experimental mode is enabled - if experimental.IsExperimentalModeEnabled() { - watchCmd.Flags().StringVar(&wo.devfileInitCommand, "init-command", "", "Devfile Init Command to execute") - watchCmd.Flags().StringVar(&wo.devfileBuildCommand, "build-command", "", "Devfile Build Command to execute") - watchCmd.Flags().StringVar(&wo.devfileRunCommand, "run-command", "", "Devfile Run Command to execute") - } + watchCmd.Flags().StringVar(&wo.devfileInitCommand, "init-command", "", "Devfile Init Command to execute") + watchCmd.Flags().StringVar(&wo.devfileBuildCommand, "build-command", "", "Devfile Build Command to execute") + watchCmd.Flags().StringVar(&wo.devfileRunCommand, "run-command", "", "Devfile Run Command to execute") // Adding context flag genericclioptions.AddContextFlag(watchCmd, &wo.componentContext) diff --git a/pkg/odo/cli/debug/info.go b/pkg/odo/cli/debug/info.go index ec4d89f5ec2..baa2ef3b639 100644 --- a/pkg/odo/cli/debug/info.go +++ b/pkg/odo/cli/debug/info.go @@ -2,11 +2,11 @@ package debug import ( "fmt" + "github.com/openshift/odo/pkg/debug" "github.com/openshift/odo/pkg/log" "github.com/openshift/odo/pkg/machineoutput" "github.com/openshift/odo/pkg/odo/genericclioptions" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/util" "github.com/spf13/cobra" k8sgenclioptions "k8s.io/cli-runtime/pkg/genericclioptions" @@ -46,7 +46,9 @@ func NewInfoOptions() *InfoOptions { // Complete completes all the required options for port-forward cmd. func (o *InfoOptions) Complete(name string, cmd *cobra.Command, args []string) (err error) { - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(o.DevfilePath) { + + // If devfile is present + if util.CheckPathExists(o.DevfilePath) { o.Context = genericclioptions.NewDevfileContext(cmd) // a small shortcut @@ -54,15 +56,19 @@ func (o *InfoOptions) Complete(name string, cmd *cobra.Command, args []string) ( o.componentName = env.GetName() o.Namespace = env.GetNamespace() - } else { - o.Context = genericclioptions.NewContext(cmd) - cfg := o.Context.LocalConfigInfo - o.LocalConfigInfo = cfg - - o.componentName = cfg.GetName() - o.applicationName = cfg.GetApplication() - o.Namespace = cfg.GetProject() } + // S2I Only + /* + } else { + o.Context = genericclioptions.NewContext(cmd) + cfg := o.Context.LocalConfigInfo + o.LocalConfigInfo = cfg + + o.componentName = cfg.GetName() + o.applicationName = cfg.GetApplication() + o.Namespace = cfg.GetProject() + } + */ // Using Discard streams because nothing important is logged o.PortForwarder = debug.NewDefaultPortForwarder(o.componentName, o.applicationName, o.Namespace, o.Client, o.KClient, k8sgenclioptions.NewTestIOStreamsDiscard()) @@ -104,9 +110,7 @@ func NewCmdInfo(name, fullName string) *cobra.Command { }, } genericclioptions.AddContextFlag(cmd, &opts.contextDir) - if experimental.IsExperimentalModeEnabled() { - cmd.Flags().StringVar(&opts.DevfilePath, "devfile", "./devfile.yaml", "Path to a devfile.yaml") - } + cmd.Flags().StringVar(&opts.DevfilePath, "devfile", "./devfile.yaml", "Path to a devfile.yaml") return cmd } diff --git a/pkg/odo/cli/debug/portforward.go b/pkg/odo/cli/debug/portforward.go index 0fa737754b9..c9939ca115c 100644 --- a/pkg/odo/cli/debug/portforward.go +++ b/pkg/odo/cli/debug/portforward.go @@ -12,7 +12,6 @@ import ( "github.com/openshift/odo/pkg/debug" "github.com/openshift/odo/pkg/log" "github.com/openshift/odo/pkg/odo/genericclioptions" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/util" "github.com/spf13/cobra" @@ -74,9 +73,8 @@ func (o *PortForwardOptions) Complete(name string, cmd *cobra.Command, args []st var remotePort int - o.isExperimental = experimental.IsExperimentalModeEnabled() - - if o.isExperimental && util.CheckPathExists(o.DevfilePath) { + // Check if Devfile exists + if util.CheckPathExists(o.DevfilePath) { o.Context = genericclioptions.NewDevfileContext(cmd) // a small shortcut @@ -85,19 +83,22 @@ func (o *PortForwardOptions) Complete(name string, cmd *cobra.Command, args []st o.componentName = env.GetName() o.Namespace = env.GetNamespace() - - } else { - // this populates the LocalConfigInfo - o.Context = genericclioptions.NewContext(cmd) - - // a small shortcut - cfg := o.Context.LocalConfigInfo - remotePort = cfg.GetDebugPort() - - o.componentName = cfg.GetName() - o.applicationName = cfg.GetApplication() - o.Namespace = cfg.GetProject() } + // S2I Only + /* + } else { + // this populates the LocalConfigInfo + o.Context = genericclioptions.NewContext(cmd) + + // a small shortcut + cfg := o.Context.LocalConfigInfo + remotePort = cfg.GetDebugPort() + + o.componentName = cfg.GetName() + o.applicationName = cfg.GetApplication() + o.Namespace = cfg.GetProject() + } + */ // try to listen on the given local port and check if the port is free or not addressLook := "localhost:" + strconv.Itoa(o.localPort) @@ -182,9 +183,7 @@ func NewCmdPortForward(name, fullName string) *cobra.Command { }, } genericclioptions.AddContextFlag(cmd, &opts.contextDir) - if experimental.IsExperimentalModeEnabled() { - cmd.Flags().StringVar(&opts.DevfilePath, "devfile", "./devfile.yaml", "Path to a devfile.yaml") - } + cmd.Flags().StringVar(&opts.DevfilePath, "devfile", "./devfile.yaml", "Path to a devfile.yaml") cmd.Flags().IntVarP(&opts.localPort, "local-port", "l", config.DefaultDebugPort, "Set the local port") return cmd diff --git a/pkg/odo/cli/logout/logout.go b/pkg/odo/cli/logout/logout.go index ecb64e5eba8..12a8c4ee67a 100644 --- a/pkg/odo/cli/logout/logout.go +++ b/pkg/odo/cli/logout/logout.go @@ -2,11 +2,12 @@ package logout import ( "fmt" + "os" + "github.com/openshift/odo/pkg/odo/genericclioptions" odoutil "github.com/openshift/odo/pkg/odo/util" "github.com/spf13/cobra" "k8s.io/kubectl/pkg/util/templates" - "os" ) // RecommendedCommandName is the recommended command name diff --git a/pkg/odo/cli/service/create.go b/pkg/odo/cli/service/create.go index 611b8f33392..aac51a93029 100644 --- a/pkg/odo/cli/service/create.go +++ b/pkg/odo/cli/service/create.go @@ -14,7 +14,6 @@ import ( commonui "github.com/openshift/odo/pkg/odo/cli/ui" "github.com/openshift/odo/pkg/odo/genericclioptions" "github.com/openshift/odo/pkg/odo/util/completion" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/odo/util/validation" svc "github.com/openshift/odo/pkg/service" @@ -119,7 +118,7 @@ func (o *ServiceCreateOptions) Complete(name string, cmd *cobra.Command, args [] var class scv1beta1.ClusterServiceClass - if experimental.IsExperimentalModeEnabled() && o.fromFile != "" { + if o.fromFile != "" { o.interactive = false return } @@ -222,146 +221,147 @@ func (o *ServiceCreateOptions) Validate() (err error) { return nil } - // we want to find an Operator only if something's passed to the crd flag on CLI - if experimental.IsExperimentalModeEnabled() { - // if the user wants to create service from a file, we check for - // existence of file and validate if the requested operator and CR - // exist on the cluster - if o.fromFile != "" { - if _, err := os.Stat(o.fromFile); err != nil { - return errors.Wrap(err, "unable to find specified file") - } + // if the user wants to create service from a file, we check for + // existence of file and validate if the requested operator and CR + // exist on the cluster + if o.fromFile != "" { + if _, err := os.Stat(o.fromFile); err != nil { + return errors.Wrap(err, "unable to find specified file") + } - // Parse the file to find Operator and CR info - fileContents, err := ioutil.ReadFile(o.fromFile) - if err != nil { - return err - } - // var jsonCR map[string]interface{} - err = yaml.Unmarshal(fileContents, &o.CustomResourceDefinition) - if err != nil { - return err - } + // Parse the file to find Operator and CR info + fileContents, err := ioutil.ReadFile(o.fromFile) + if err != nil { + return err + } + // var jsonCR map[string]interface{} + err = yaml.Unmarshal(fileContents, &o.CustomResourceDefinition) + if err != nil { + return err + } - // Check if the operator and the CR exist on cluster - o.CustomResource = o.CustomResourceDefinition["kind"].(string) - csvs, err := o.KClient.GetClusterServiceVersionList() - if err != nil { - return err - } + // Check if the operator and the CR exist on cluster + o.CustomResource = o.CustomResourceDefinition["kind"].(string) + csvs, err := o.KClient.GetClusterServiceVersionList() + if err != nil { + return err + } - csv, err := doesCRExist(o.CustomResource, csvs) - if err != nil { - return fmt.Errorf("Could not find specified service/custom resource: %s\nPlease check the \"kind\" field in the yaml (it's case-sensitive)", o.CustomResource) - } + csv, err := doesCRExist(o.CustomResource, csvs) + if err != nil { + return fmt.Errorf("Could not find specified service/custom resource: %s\nPlease check the \"kind\" field in the yaml (it's case-sensitive)", o.CustomResource) + } - // all is well, let's populate the fields required for creating operator backed service - o.group, o.version = groupVersionALMExample(o.CustomResourceDefinition) - o.resource = resourceFromCSV(csv, o.CustomResource) - o.ServiceName, err = serviceNameFromCRD(o.CustomResourceDefinition, o.ServiceName) + // all is well, let's populate the fields required for creating operator backed service + o.group, o.version = groupVersionALMExample(o.CustomResourceDefinition) + o.resource = resourceFromCSV(csv, o.CustomResource) + o.ServiceName, err = serviceNameFromCRD(o.CustomResourceDefinition, o.ServiceName) + return err + } + if o.CustomResource != "" { + // make sure that CSV of the specified ServiceType exists + csv, err := o.KClient.GetClusterServiceVersion(o.ServiceType) + if err != nil { + // error only occurs when OperatorHub is not installed. + // k8s does't have it installed by default but OCP does return err } - if o.CustomResource != "" { - // make sure that CSV of the specified ServiceType exists - csv, err := o.KClient.GetClusterServiceVersion(o.ServiceType) - if err != nil { - // error only occurs when OperatorHub is not installed. - // k8s does't have it installed by default but OCP does - return err - } - - var almExamples []map[string]interface{} - val, ok := csv.Annotations["alm-examples"] - if ok { - err = json.Unmarshal([]byte(val), &almExamples) - if err != nil { - return errors.Wrap(err, "unable to unmarshal alm-examples") - } - } else { - // There's no alm examples in the CSV's definition - return fmt.Errorf("Could not find alm-examples in operator's definition.\nPlease provide a file containing yaml specification to start the %s service from %s operator", o.CustomResource, o.ServiceName) - } - almExample, err := getAlmExample(almExamples, o.CustomResource, o.ServiceType) + var almExamples []map[string]interface{} + val, ok := csv.Annotations["alm-examples"] + if ok { + err = json.Unmarshal([]byte(val), &almExamples) if err != nil { - return err + return errors.Wrap(err, "unable to unmarshal alm-examples") } - o.CustomResourceDefinition = almExample - o.group, o.version = groupVersionALMExample(almExample) - o.resource = resourceFromCSV(csv, o.CustomResource) - o.ServiceName, err = serviceNameFromCRD(o.CustomResourceDefinition, o.ServiceName) - return err } else { - // prevent user from executing `odo service create ` - // because the correct way is to execute `odo service - // --crd ` - csvs, err := o.KClient.GetClusterServiceVersionList() - if err != nil { - return err - } + // There's no alm examples in the CSV's definition + return fmt.Errorf("Could not find alm-examples in operator's definition.\nPlease provide a file containing yaml specification to start the %s service from %s operator", o.CustomResource, o.ServiceName) + } - for _, csv := range csvs.Items { - if csv.Name == o.ServiceType { - // this is satisfied if user has specified operator but not - // a CRD name - return errors.New("Please specify service name along with the operator name") - } + almExample, err := getAlmExample(almExamples, o.CustomResource, o.ServiceType) + if err != nil { + return err + } + o.CustomResourceDefinition = almExample + o.group, o.version = groupVersionALMExample(almExample) + o.resource = resourceFromCSV(csv, o.CustomResource) + o.ServiceName, err = serviceNameFromCRD(o.CustomResourceDefinition, o.ServiceName) + return err + } else { + // prevent user from executing `odo service create ` + // because the correct way is to execute `odo service + // --crd ` + csvs, err := o.KClient.GetClusterServiceVersionList() + if err != nil { + return err + } + + for _, csv := range csvs.Items { + if csv.Name == o.ServiceType { + // this is satisfied if user has specified operator but not + // a CRD name + return errors.New("Please specify service name along with the operator name") } } } - // make sure the service type exists - classPtr, err := o.Client.GetClusterServiceClass(o.ServiceType) - if err != nil { - return errors.Wrap(err, "unable to create service because Service Catalog is not enabled in your cluster") - } - if classPtr == nil { - return fmt.Errorf("service %v doesn't exist\nRun 'odo catalog list services' to see a list of supported services.\n", o.ServiceType) - } - // check plan - plans, err := o.Client.GetMatchingPlans(*classPtr) - if err != nil { - return err - } - if len(o.Plan) == 0 { - // when the plan has not been supplied, if there is only one available plan, we select it - if len(plans) == 1 { - for k := range plans { - o.Plan = k + return nil + + // EVERYTHING BELOW is S2I only to be implemented later. + /* + // make sure the service type exists + classPtr, err := o.Client.GetClusterServiceClass(o.ServiceType) + if err != nil { + return errors.Wrap(err, "unable to create service because Service Catalog is not enabled in your cluster") + } + if classPtr == nil { + return fmt.Errorf("service %v doesn't exist\nRun 'odo catalog list services' to see a list of supported services.\n", o.ServiceType) + } + + // check plan + plans, err := o.Client.GetMatchingPlans(*classPtr) + if err != nil { + return err + } + if len(o.Plan) == 0 { + // when the plan has not been supplied, if there is only one available plan, we select it + if len(plans) == 1 { + for k := range plans { + o.Plan = k + } + klog.V(4).Infof("Plan %s was automatically selected since it's the only one available for service %s", o.Plan, o.ServiceType) + } else { + return fmt.Errorf("no plan was supplied for service %v.\nPlease select one of: %v\n", o.ServiceType, strings.Join(ui.GetServicePlanNames(plans), ",")) } - klog.V(4).Infof("Plan %s was automatically selected since it's the only one available for service %s", o.Plan, o.ServiceType) } else { - return fmt.Errorf("no plan was supplied for service %v.\nPlease select one of: %v\n", o.ServiceType, strings.Join(ui.GetServicePlanNames(plans), ",")) - } - } else { - // when the plan has been supplied, we need to make sure it exists - if _, ok := plans[o.Plan]; !ok { - return fmt.Errorf("plan %s is invalid for service %v.\nPlease select one of: %v\n", o.Plan, o.ServiceType, strings.Join(ui.GetServicePlanNames(plans), ",")) + // when the plan has been supplied, we need to make sure it exists + if _, ok := plans[o.Plan]; !ok { + return fmt.Errorf("plan %s is invalid for service %v.\nPlease select one of: %v\n", o.Plan, o.ServiceType, strings.Join(ui.GetServicePlanNames(plans), ",")) + } } - } - //validate service name - return o.validateServiceName(o.ServiceName) + //validate service name + return o.validateServiceName(o.ServiceName) + */ } // Run contains the logic for the odo service create command func (o *ServiceCreateOptions) Run() (err error) { s := &log.Status{} - if experimental.IsExperimentalModeEnabled() { - // in case of an opertor backed service, name of the service is - // provided by the yaml specification in alm-examples. It might also - // happen that a user spins up Service Catalog based service in - // experimental mode but we're taking a bet against that for now, so - // the user won't get to see service name in the log message - if !o.DryRun { - log.Infof("Deploying service of type: %s", o.CustomResource) - s = log.Spinner("Deploying service") - defer s.End(false) - } - } else { - log.Infof("Deploying service %s of type: %s", o.ServiceName, o.ServiceType) + // in case of an opertor backed service, name of the service is + // provided by the yaml specification in alm-examples. It might also + // happen that a user spins up Service Catalog based service in + // experimental mode but we're taking a bet against that for now, so + // the user won't get to see service name in the log message + if !o.DryRun { + log.Infof("Deploying service of type: %s", o.CustomResource) + s = log.Spinner("Deploying service") + defer s.End(false) } + // S2I only + // log.Infof("Deploying service %s of type: %s", o.ServiceName, o.ServiceType) - if experimental.IsExperimentalModeEnabled() && o.CustomResource != "" { + if o.CustomResource != "" { // if experimental mode is enabled and o.CustomResource is not empty, we're expected to create an Operator backed service if o.DryRun { // if it's dry run, only print the alm-example (o.CustomResourceDefinition) and exit @@ -428,14 +428,12 @@ func NewCmdServiceCreate(name, fullName string) *cobra.Command { }, } - if experimental.IsExperimentalModeEnabled() { - serviceCreateCmd.Use += fmt.Sprintf(" [flags]\n %s --crd [service_name] [flags]", o.CmdFullName) - serviceCreateCmd.Example += fmt.Sprintf("\n\n") + fmt.Sprintf(createOperatorExample, fullName) - serviceCreateCmd.Flags().StringVar(&o.CustomResource, "crd", "", "The name of the CRD of the operator to be used to create the service") - serviceCreateCmd.Flags().BoolVar(&o.DryRun, "dry-run", false, "Print the yaml specificiation that will be used to create the service") - // remove this feature after enabling service create interactive mode for operator backed services - serviceCreateCmd.Flags().StringVar(&o.fromFile, "from-file", "", "Path to the file containing yaml specification to use to start operator backed service") - } + serviceCreateCmd.Use += fmt.Sprintf(" [flags]\n %s --crd [service_name] [flags]", o.CmdFullName) + serviceCreateCmd.Example += fmt.Sprintf("\n\n") + fmt.Sprintf(createOperatorExample, fullName) + serviceCreateCmd.Flags().StringVar(&o.CustomResource, "crd", "", "The name of the CRD of the operator to be used to create the service") + serviceCreateCmd.Flags().BoolVar(&o.DryRun, "dry-run", false, "Print the yaml specificiation that will be used to create the service") + // remove this feature after enabling service create interactive mode for operator backed services + serviceCreateCmd.Flags().StringVar(&o.fromFile, "from-file", "", "Path to the file containing yaml specification to use to start operator backed service") serviceCreateCmd.Flags().StringVar(&o.Plan, "plan", "", "The name of the plan of the service to be created") serviceCreateCmd.Flags().StringArrayVarP(&o.parameters, "parameters", "p", []string{}, "Parameters of the plan where a parameter is expressed as = 0 { return fmt.Errorf("host is not supported for URLs of Route Kind") @@ -235,20 +237,25 @@ func (o *URLCreateOptions) Validate() (err error) { if !util.CheckOutputFlag(o.OutputFlag) { return fmt.Errorf("given output format %s is not supported", o.OutputFlag) } - if !experimental.IsExperimentalModeEnabled() { - if o.now { - err = o.ValidateComponentCreate() - if err != nil { - return err + + // S2I Only + /* + if !experimental.IsExperimentalModeEnabled() { + if o.now { + err = o.ValidateComponentCreate() + if err != nil { + return err + } } } - } + */ return } // Run contains the logic for the odo url create command func (o *URLCreateOptions) Run() (err error) { - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(o.DevfilePath) { + // If devfile is present + if util.CheckPathExists(o.DevfilePath) { if pushtarget.IsPushTargetDocker() { for _, localURL := range o.EnvSpecificInfo.GetURL() { fmt.Printf("componentPort is %v, localUrl.port is %v", o.componentPort, localURL.Port) @@ -275,7 +282,9 @@ func (o *URLCreateOptions) Run() (err error) { if err != nil { return errors.Wrapf(err, "failed to persist the component settings to config file") } - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(o.DevfilePath) { + + // If devfile is present + if util.CheckPathExists(o.DevfilePath) { componentName := o.EnvSpecificInfo.GetName() if pushtarget.IsPushTargetDocker() { log.Successf("URL %s created for component: %v with exposed port: %v", o.urlName, componentName, o.exposedPort) @@ -286,7 +295,9 @@ func (o *URLCreateOptions) Run() (err error) { log.Successf("URL %s created for component: %v", o.urlName, o.Component()) } if o.now { - if experimental.IsExperimentalModeEnabled() && util.CheckPathExists(o.DevfilePath) { + + // If devfile is present + if util.CheckPathExists(o.DevfilePath) { err = o.DevfilePush() } else { err = o.Push() @@ -315,23 +326,26 @@ func NewCmdURLCreate(name, fullName string) *cobra.Command { }, } urlCreateCmd.Flags().IntVarP(&o.urlPort, "port", "", -1, "port number for the url of the component, required in case of components which expose more than one service port") - // if experimental mode is enabled, add more flags to support ingress creation or docker application based on devfile - if experimental.IsExperimentalModeEnabled() { - if pushtarget.IsPushTargetDocker() { - urlCreateCmd.Flags().IntVarP(&o.exposedPort, "exposed-port", "", -1, "an external port to the application container") - urlCreateCmd.Flags().BoolVarP(&o.forceFlag, "force", "f", false, "Don't ask for confirmation, assign an exposed port directly") - urlCreateCmd.Example = fmt.Sprintf(urlCreateExampleDocker, fullName) - } else { - urlCreateCmd.Flags().StringVar(&o.tlsSecret, "tls-secret", "", "tls secret name for the url of the component if the user bring his own tls secret") - urlCreateCmd.Flags().StringVarP(&o.host, "host", "", "", "Cluster ip for this URL") - urlCreateCmd.Flags().BoolVarP(&o.secureURL, "secure", "", false, "creates a secure https url") - urlCreateCmd.Flags().BoolVar(&o.wantIngress, "ingress", false, "Creates an ingress instead of Route on OpenShift clusters") - urlCreateCmd.Example = fmt.Sprintf(urlCreateExampleExperimental, fullName) - } + + if pushtarget.IsPushTargetDocker() { + urlCreateCmd.Flags().IntVarP(&o.exposedPort, "exposed-port", "", -1, "an external port to the application container") + urlCreateCmd.Flags().BoolVarP(&o.forceFlag, "force", "f", false, "Don't ask for confirmation, assign an exposed port directly") + urlCreateCmd.Example = fmt.Sprintf(urlCreateExampleDocker, fullName) } else { + urlCreateCmd.Flags().StringVar(&o.tlsSecret, "tls-secret", "", "tls secret name for the url of the component if the user bring his own tls secret") + urlCreateCmd.Flags().StringVarP(&o.host, "host", "", "", "Cluster ip for this URL") urlCreateCmd.Flags().BoolVarP(&o.secureURL, "secure", "", false, "creates a secure https url") - urlCreateCmd.Example = fmt.Sprintf(urlCreateExample, fullName) + urlCreateCmd.Flags().BoolVar(&o.wantIngress, "ingress", false, "Creates an ingress instead of Route on OpenShift clusters") + urlCreateCmd.Example = fmt.Sprintf(urlCreateExampleExperimental, fullName) } + + // S2I only (maybe?) + /* + } else { + urlCreateCmd.Flags().BoolVarP(&o.secureURL, "secure", "", false, "creates a secure https url") + urlCreateCmd.Example = fmt.Sprintf(urlCreateExample, fullName) + } + */ genericclioptions.AddNowFlag(urlCreateCmd, &o.now) o.AddContextFlag(urlCreateCmd) completion.RegisterCommandFlagHandler(urlCreateCmd, "context", completion.FileCompletionHandler) diff --git a/pkg/odo/cli/url/delete.go b/pkg/odo/cli/url/delete.go index ee4eb934121..e83d7743a61 100644 --- a/pkg/odo/cli/url/delete.go +++ b/pkg/odo/cli/url/delete.go @@ -8,8 +8,6 @@ import ( "github.com/openshift/odo/pkg/odo/cli/ui" "github.com/openshift/odo/pkg/odo/genericclioptions" "github.com/openshift/odo/pkg/odo/util/completion" - "github.com/openshift/odo/pkg/odo/util/experimental" - "github.com/pkg/errors" "github.com/spf13/cobra" ktemplates "k8s.io/kubectl/pkg/util/templates" ) @@ -40,35 +38,37 @@ func NewURLDeleteOptions() *URLDeleteOptions { // Complete completes URLDeleteOptions after they've been Deleted func (o *URLDeleteOptions) Complete(name string, cmd *cobra.Command, args []string) (err error) { - if experimental.IsExperimentalModeEnabled() { + o.Context = genericclioptions.NewDevfileContext(cmd) + o.urlName = args[0] + err = o.InitEnvInfoFromContext() + if err != nil { + return err + } + o.CompleteDevfilePath() - o.Context = genericclioptions.NewDevfileContext(cmd) - o.urlName = args[0] - err = o.InitEnvInfoFromContext() - if err != nil { - return err - } - o.CompleteDevfilePath() - } else { - if o.now { - o.Context = genericclioptions.NewContextCreatingAppIfNeeded(cmd) + // S2I Only + /* } else { - o.Context = genericclioptions.NewContext(cmd) - } - o.urlName = args[0] - err = o.InitConfigFromContext() - if err != nil { - return err - } - if o.now { - prjName := o.LocalConfigInfo.GetProject() - o.ResolveSrcAndConfigFlags() - err = o.ResolveProject(prjName) + if o.now { + o.Context = genericclioptions.NewContextCreatingAppIfNeeded(cmd) + } else { + o.Context = genericclioptions.NewContext(cmd) + } + o.urlName = args[0] + err = o.InitConfigFromContext() if err != nil { return err } + if o.now { + prjName := o.LocalConfigInfo.GetProject() + o.ResolveSrcAndConfigFlags() + err = o.ResolveProject(prjName) + if err != nil { + return err + } + } } - } + */ return } @@ -76,35 +76,38 @@ func (o *URLDeleteOptions) Complete(name string, cmd *cobra.Command, args []stri // Validate validates the URLDeleteOptions based on completed values func (o *URLDeleteOptions) Validate() (err error) { var exists bool - if experimental.IsExperimentalModeEnabled() { - urls := o.EnvSpecificInfo.GetURL() - componentName := o.EnvSpecificInfo.GetName() - for _, url := range urls { - if url.Name == o.urlName { - exists = true - } - } - if !exists { - return fmt.Errorf("the URL %s does not exist within the component %s", o.urlName, componentName) + urls := o.EnvSpecificInfo.GetURL() + componentName := o.EnvSpecificInfo.GetName() + for _, url := range urls { + if url.Name == o.urlName { + exists = true } - } else { - urls := o.LocalConfigInfo.GetURL() + } + if !exists { + return fmt.Errorf("the URL %s does not exist within the component %s", o.urlName, componentName) + } - for _, url := range urls { - if url.Name == o.urlName { - exists = true + // S2I Only + /* + } else { + urls := o.LocalConfigInfo.GetURL() + + for _, url := range urls { + if url.Name == o.urlName { + exists = true + } } - } - if o.now { - err = o.ValidateComponentCreate() - if err != nil { - return err + if o.now { + err = o.ValidateComponentCreate() + if err != nil { + return err + } + } + if !exists { + return fmt.Errorf("the URL %s does not exist within the component %s", o.urlName, o.Component()) } } - if !exists { - return fmt.Errorf("the URL %s does not exist within the component %s", o.urlName, o.Component()) - } - } + */ return } @@ -112,35 +115,37 @@ func (o *URLDeleteOptions) Validate() (err error) { // Run contains the logic for the odo url delete command func (o *URLDeleteOptions) Run() (err error) { if o.urlForceDeleteFlag || ui.Proceed(fmt.Sprintf("Are you sure you want to delete the url %v", o.urlName)) { - if experimental.IsExperimentalModeEnabled() { - err = o.EnvSpecificInfo.DeleteURL(o.urlName) + err = o.EnvSpecificInfo.DeleteURL(o.urlName) + if err != nil { + return err + } + if o.now { + err = o.DevfilePush() if err != nil { return err } - if o.now { - err = o.DevfilePush() + } else { + log.Successf("URL %s removed from the env file", o.urlName) + log.Italic("\nTo delete the URL on the cluster, please use `odo push`") + } + // S2I Only + /* + } else { + err = o.LocalConfigInfo.DeleteURL(o.urlName) if err != nil { return err } - } else { - log.Successf("URL %s removed from the env file", o.urlName) - log.Italic("\nTo delete the URL on the cluster, please use `odo push`") - } - } else { - err = o.LocalConfigInfo.DeleteURL(o.urlName) - if err != nil { - return err - } - log.Successf("URL %s removed from the config file", o.urlName) - if o.now { - err = o.Push() - if err != nil { - return errors.Wrap(err, "failed to push changes") + log.Successf("URL %s removed from the config file", o.urlName) + if o.now { + err = o.Push() + if err != nil { + return errors.Wrap(err, "failed to push changes") + } + } else { + log.Italic("\nTo delete the URL on the cluster, please use `odo push`") } - } else { - log.Italic("\nTo delete the URL on the cluster, please use `odo push`") } - } + */ } else { return fmt.Errorf("aborting deletion of URL: %v", o.urlName) } diff --git a/pkg/odo/cli/url/describe.go b/pkg/odo/cli/url/describe.go index 795ef2d32e5..12ba14bdf55 100644 --- a/pkg/odo/cli/url/describe.go +++ b/pkg/odo/cli/url/describe.go @@ -18,7 +18,6 @@ import ( "github.com/openshift/odo/pkg/odo/genericclioptions" "github.com/openshift/odo/pkg/odo/util" "github.com/openshift/odo/pkg/odo/util/completion" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/url" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -47,13 +46,14 @@ func NewURLDescribeOptions() *URLDescribeOptions { // Complete completes URLDescribeOptions after they've been Listed func (o *URLDescribeOptions) Complete(name string, cmd *cobra.Command, args []string) (err error) { - if experimental.IsExperimentalModeEnabled() { - o.Context = genericclioptions.NewDevfileContext(cmd) - o.EnvSpecificInfo, err = envinfo.NewEnvSpecificInfo(o.componentContext) - } else { + o.Context = genericclioptions.NewDevfileContext(cmd) + o.EnvSpecificInfo, err = envinfo.NewEnvSpecificInfo(o.componentContext) + + // S2I Only + /* o.Context = genericclioptions.NewContext(cmd) o.localConfigInfo, err = config.NewLocalConfigInfo(o.componentContext) - } + */ if err != nil { return errors.Wrap(err, "failed intiating local config") } @@ -68,94 +68,68 @@ func (o *URLDescribeOptions) Validate() (err error) { // Run contains the logic for the odo url describe command func (o *URLDescribeOptions) Run() (err error) { - if experimental.IsExperimentalModeEnabled() { - if pushtarget.IsPushTargetDocker() { - client, err := lclient.New() - if err != nil { - return err - } - u, err := url.GetContainerURL(client, o.EnvSpecificInfo, o.url, o.EnvSpecificInfo.GetName()) - if err != nil { - return err - } + if pushtarget.IsPushTargetDocker() { + client, err := lclient.New() + if err != nil { + return err + } + u, err := url.GetContainerURL(client, o.EnvSpecificInfo, o.url, o.EnvSpecificInfo.GetName()) + if err != nil { + return err + } - if log.IsJSON() { - machineoutput.OutputSuccess(u) - } else { - tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) - fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT") - var urlString string - if u.Status.State == url.StateTypeNotPushed { - // to be consistent with URL for ingress and routes - // if not pushed, display URl as :// - urlString = "://" - } else { - urlString = fmt.Sprintf("%s:%s", u.Spec.Host, strconv.Itoa(u.Spec.ExternalPort)) - } - // are there changes between local and cluster states? - outOfSync := false - fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", urlString, "\t", u.Spec.Port) - if u.Status.State != url.StateTypePushed { - outOfSync = true - } - tabWriterURL.Flush() - if outOfSync { - log.Info("There are local changes. Please run 'odo push'.") - } - } + if log.IsJSON() { + machineoutput.OutputSuccess(u) } else { - componentName := o.EnvSpecificInfo.GetName() - oclient, err := occlient.New() - if err != nil { - return err - } - oclient.Namespace = o.KClient.Namespace - routeSupported, err := oclient.IsRouteSupported() - if err != nil { - return err + tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) + fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT") + var urlString string + if u.Status.State == url.StateTypeNotPushed { + // to be consistent with URL for ingress and routes + // if not pushed, display URl as :// + urlString = "://" + } else { + urlString = fmt.Sprintf("%s:%s", u.Spec.Host, strconv.Itoa(u.Spec.ExternalPort)) } - u, err := url.GetIngressOrRoute(oclient, o.KClient, o.EnvSpecificInfo, o.url, componentName, routeSupported) - if err != nil { - return err + // are there changes between local and cluster states? + outOfSync := false + fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", urlString, "\t", u.Spec.Port) + if u.Status.State != url.StateTypePushed { + outOfSync = true } - if log.IsJSON() { - machineoutput.OutputSuccess(u) - } else { - tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) - fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT", "\t", "SECURE", "\t", "KIND") - - // are there changes between local and cluster states? - outOfSync := false - if u.Spec.Kind == envinfo.ROUTE { - fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(u.Spec.Protocol, u.Spec.Host, "", experimental.IsExperimentalModeEnabled()), "\t", u.Spec.Port, "\t", u.Spec.Secure, "\t", u.Spec.Kind) - } else { - fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(url.GetProtocol(routev1.Route{}, url.ConvertIngressURLToIngress(u, componentName)), "", u.Spec.Host, experimental.IsExperimentalModeEnabled()), "\t", u.Spec.Port, "\t", u.Spec.Secure, "\t", u.Spec.Kind) - } - if u.Status.State != url.StateTypePushed { - outOfSync = true - } - tabWriterURL.Flush() - if outOfSync { - log.Info("There are local changes. Please run 'odo push'.") - } + tabWriterURL.Flush() + if outOfSync { + log.Info("There are local changes. Please run 'odo push'.") } } } else { - u, err := url.Get(o.Client, o.localConfigInfo, o.url, o.Application) + componentName := o.EnvSpecificInfo.GetName() + oclient, err := occlient.New() + if err != nil { + return err + } + oclient.Namespace = o.KClient.Namespace + routeSupported, err := oclient.IsRouteSupported() + if err != nil { + return err + } + u, err := url.GetIngressOrRoute(oclient, o.KClient, o.EnvSpecificInfo, o.url, componentName, routeSupported) if err != nil { return err } - if log.IsJSON() { machineoutput.OutputSuccess(u) } else { - tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) - fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT") + fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT", "\t", "SECURE", "\t", "KIND") // are there changes between local and cluster states? outOfSync := false - fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(u.Spec.Protocol, u.Spec.Host, "", experimental.IsExperimentalModeEnabled()), "\t", u.Spec.Port) + if u.Spec.Kind == envinfo.ROUTE { + fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(u.Spec.Protocol, u.Spec.Host, ""), "\t", u.Spec.Port, "\t", u.Spec.Secure, "\t", u.Spec.Kind) + } else { + fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(url.GetProtocol(routev1.Route{}, url.ConvertIngressURLToIngress(u, componentName)), "", u.Spec.Host), "\t", u.Spec.Port, "\t", u.Spec.Secure, "\t", u.Spec.Kind) + } if u.Status.State != url.StateTypePushed { outOfSync = true } @@ -166,6 +140,34 @@ func (o *URLDescribeOptions) Run() (err error) { } } + // S2I Only + /* + } else { + u, err := url.Get(o.Client, o.localConfigInfo, o.url, o.Application) + if err != nil { + return err + } + + if log.IsJSON() { + machineoutput.OutputSuccess(u) + } else { + + tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) + fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT") + + // are there changes between local and cluster states? + outOfSync := false + fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(u.Spec.Protocol, u.Spec.Host, "", experimental.IsExperimentalModeEnabled()), "\t", u.Spec.Port) + if u.Status.State != url.StateTypePushed { + outOfSync = true + } + tabWriterURL.Flush() + if outOfSync { + log.Info("There are local changes. Please run 'odo push'.") + } + } + */ + return } diff --git a/pkg/odo/cli/url/list.go b/pkg/odo/cli/url/list.go index 9c1f682c946..668e346d361 100644 --- a/pkg/odo/cli/url/list.go +++ b/pkg/odo/cli/url/list.go @@ -12,9 +12,6 @@ import ( "github.com/openshift/odo/pkg/odo/util/pushtarget" - "github.com/openshift/odo/pkg/odo/util/experimental" - - "github.com/openshift/odo/pkg/config" "github.com/openshift/odo/pkg/lclient" "github.com/openshift/odo/pkg/log" "github.com/openshift/odo/pkg/machineoutput" @@ -50,13 +47,13 @@ func NewURLListOptions() *URLListOptions { // Complete completes URLListOptions after they've been Listed func (o *URLListOptions) Complete(name string, cmd *cobra.Command, args []string) (err error) { - if experimental.IsExperimentalModeEnabled() { - o.Context = genericclioptions.NewDevfileContext(cmd) - o.EnvSpecificInfo, err = envinfo.NewEnvSpecificInfo(o.componentContext) - } else { + o.Context = genericclioptions.NewDevfileContext(cmd) + o.EnvSpecificInfo, err = envinfo.NewEnvSpecificInfo(o.componentContext) + // S2I Only + /* o.Context = genericclioptions.NewContext(cmd) o.LocalConfigInfo, err = config.NewLocalConfigInfo(o.componentContext) - } + */ if err != nil { return errors.Wrap(err, "failed intiating local config") } @@ -70,95 +67,60 @@ func (o *URLListOptions) Validate() (err error) { // Run contains the logic for the odo url list command func (o *URLListOptions) Run() (err error) { - if experimental.IsExperimentalModeEnabled() { - if pushtarget.IsPushTargetDocker() { - componentName := o.EnvSpecificInfo.GetName() - client, err := lclient.New() - if err != nil { - return err - } - urls, err := url.ListDockerURL(client, componentName, o.EnvSpecificInfo) - if err != nil { - return err - } - if log.IsJSON() { - machineoutput.OutputSuccess(urls) - } else { - if len(urls.Items) == 0 { - return fmt.Errorf("no URLs found for component %v. Refer `odo url create -h` to add one", componentName) - } - - log.Infof("Found the following URLs for component %v", componentName) - tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) - fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT") - - // are there changes between local and container states? - outOfSync := false - for _, u := range urls.Items { - var urlString string - if u.Status.State == url.StateTypeNotPushed { - // to be consistent with URL for ingress and routes - // if not pushed, display URl as :// - urlString = "://" - } else { - urlString = fmt.Sprintf("%s:%s", u.Spec.Host, strconv.Itoa(u.Spec.ExternalPort)) - } - fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", urlString, "\t", u.Spec.Port) - if u.Status.State != url.StateTypePushed { - outOfSync = true - } - } - tabWriterURL.Flush() - if outOfSync { - log.Info("There are local changes. Please run 'odo push'.") - } - } + if pushtarget.IsPushTargetDocker() { + componentName := o.EnvSpecificInfo.GetName() + client, err := lclient.New() + if err != nil { + return err + } + urls, err := url.ListDockerURL(client, componentName, o.EnvSpecificInfo) + if err != nil { + return err + } + if log.IsJSON() { + machineoutput.OutputSuccess(urls) } else { - componentName := o.EnvSpecificInfo.GetName() - oclient, err := occlient.New() - if err != nil { - return err - } - oclient.Namespace = o.KClient.Namespace - routeSupported, err := oclient.IsRouteSupported() - if err != nil { - return err - } - urls, err := url.ListIngressAndRoute(oclient, o.KClient, o.EnvSpecificInfo, componentName, routeSupported) - if err != nil { - return err + if len(urls.Items) == 0 { + return fmt.Errorf("no URLs found for component %v. Refer `odo url create -h` to add one", componentName) } - if log.IsJSON() { - machineoutput.OutputSuccess(urls) - } else { - if len(urls.Items) == 0 { - return fmt.Errorf("no URLs found for component %v. Refer `odo url create -h` to add one", componentName) - } - log.Infof("Found the following URLs for component %v", componentName) - tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) - fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT", "\t", "SECURE", "\t", "KIND") + log.Infof("Found the following URLs for component %v", componentName) + tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) + fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT") - // are there changes between local and cluster states? - outOfSync := false - for _, u := range urls.Items { - if u.Spec.Kind == envinfo.ROUTE { - fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(u.Spec.Protocol, u.Spec.Host, "", experimental.IsExperimentalModeEnabled()), "\t", u.Spec.Port, "\t", u.Spec.Secure, "\t", u.Spec.Kind) - } else { - fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(url.GetProtocol(routev1.Route{}, url.ConvertIngressURLToIngress(u, o.EnvSpecificInfo.GetName())), "", u.Spec.Host, experimental.IsExperimentalModeEnabled()), "\t", u.Spec.Port, "\t", u.Spec.Secure, "\t", u.Spec.Kind) - } - if u.Status.State != url.StateTypePushed { - outOfSync = true - } + // are there changes between local and container states? + outOfSync := false + for _, u := range urls.Items { + var urlString string + if u.Status.State == url.StateTypeNotPushed { + // to be consistent with URL for ingress and routes + // if not pushed, display URl as :// + urlString = "://" + } else { + urlString = fmt.Sprintf("%s:%s", u.Spec.Host, strconv.Itoa(u.Spec.ExternalPort)) } - tabWriterURL.Flush() - if outOfSync { - log.Info("There are local changes. Please run 'odo push'.") + fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", urlString, "\t", u.Spec.Port) + if u.Status.State != url.StateTypePushed { + outOfSync = true } } + tabWriterURL.Flush() + if outOfSync { + log.Info("There are local changes. Please run 'odo push'.") + } } } else { - urls, err := url.List(o.Client, o.LocalConfigInfo, o.Component(), o.Application) + componentName := o.EnvSpecificInfo.GetName() + oclient, err := occlient.New() + if err != nil { + return err + } + oclient.Namespace = o.KClient.Namespace + routeSupported, err := oclient.IsRouteSupported() + if err != nil { + return err + } + urls, err := url.ListIngressAndRoute(oclient, o.KClient, o.EnvSpecificInfo, componentName, routeSupported) if err != nil { return err } @@ -166,17 +128,21 @@ func (o *URLListOptions) Run() (err error) { machineoutput.OutputSuccess(urls) } else { if len(urls.Items) == 0 { - return fmt.Errorf("no URLs found for component %v in application %v", o.Component(), o.Application) + return fmt.Errorf("no URLs found for component %v. Refer `odo url create -h` to add one", componentName) } - log.Infof("Found the following URLs for component %v in application %v:", o.Component(), o.Application) + log.Infof("Found the following URLs for component %v", componentName) tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) - fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT", "\t", "SECURE") + fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT", "\t", "SECURE", "\t", "KIND") // are there changes between local and cluster states? outOfSync := false for _, u := range urls.Items { - fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(u.Spec.Protocol, u.Spec.Host, "", experimental.IsExperimentalModeEnabled()), "\t", u.Spec.Port, "\t", u.Spec.Secure) + if u.Spec.Kind == envinfo.ROUTE { + fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(u.Spec.Protocol, u.Spec.Host, ""), "\t", u.Spec.Port, "\t", u.Spec.Secure, "\t", u.Spec.Kind) + } else { + fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(url.GetProtocol(routev1.Route{}, url.ConvertIngressURLToIngress(u, o.EnvSpecificInfo.GetName())), "", u.Spec.Host), "\t", u.Spec.Port, "\t", u.Spec.Secure, "\t", u.Spec.Kind) + } if u.Status.State != url.StateTypePushed { outOfSync = true } @@ -187,7 +153,39 @@ func (o *URLListOptions) Run() (err error) { } } } + // S2I Only + /* + } else { + urls, err := url.List(o.Client, o.LocalConfigInfo, o.Component(), o.Application) + if err != nil { + return err + } + if log.IsJSON() { + machineoutput.OutputSuccess(urls) + } else { + if len(urls.Items) == 0 { + return fmt.Errorf("no URLs found for component %v in application %v", o.Component(), o.Application) + } + log.Infof("Found the following URLs for component %v in application %v:", o.Component(), o.Application) + tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) + fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT", "\t", "SECURE") + + // are there changes between local and cluster states? + outOfSync := false + for _, u := range urls.Items { + fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(u.Spec.Protocol, u.Spec.Host, "", experimental.IsExperimentalModeEnabled()), "\t", u.Spec.Port, "\t", u.Spec.Secure) + if u.Status.State != url.StateTypePushed { + outOfSync = true + } + } + tabWriterURL.Flush() + if outOfSync { + log.Info("There are local changes. Please run 'odo push'.") + } + } + } + */ return } diff --git a/pkg/odo/util/cmdutils.go b/pkg/odo/util/cmdutils.go index 75ca1ef0566..2d4f67b55e1 100644 --- a/pkg/odo/util/cmdutils.go +++ b/pkg/odo/util/cmdutils.go @@ -11,7 +11,6 @@ import ( "github.com/openshift/odo/pkg/log" "github.com/openshift/odo/pkg/machineoutput" "github.com/openshift/odo/pkg/occlient" - "github.com/openshift/odo/pkg/odo/util/experimental" "github.com/openshift/odo/pkg/storage" urlPkg "github.com/openshift/odo/pkg/url" @@ -137,25 +136,23 @@ func PrintComponentInfo(client *occlient.Client, currentComponentName string, co if componentDesc.Spec.URL != nil { var output string - if !experimental.IsExperimentalModeEnabled() { - // if the component is not pushed - if componentDesc.Status.State == component.StateTypeNotPushed { - // Gather the output - for i, componentURL := range componentDesc.Spec.URL { - output += fmt.Sprintf(" · URL named %s will be exposed via %v\n", componentURL, componentDesc.Spec.Ports[i]) - } - } else { - // Retrieve the URLs - urls, err := urlPkg.ListPushed(client, currentComponentName, applicationName) - LogErrorAndExit(err, "") - - // Gather the output - for _, componentURL := range componentDesc.Spec.URL { - url := urls.Get(componentURL) - output += fmt.Sprintf(" · %v exposed via %v\n", urlPkg.GetURLString(url.Spec.Protocol, url.Spec.Host, "", experimental.IsExperimentalModeEnabled()), url.Spec.Port) - } + // if the component is not pushed + if componentDesc.Status.State == component.StateTypeNotPushed { + // Gather the output + for i, componentURL := range componentDesc.Spec.URL { + output += fmt.Sprintf(" · URL named %s will be exposed via %v\n", componentURL, componentDesc.Spec.Ports[i]) + } + } else { + // Retrieve the URLs + urls, err := urlPkg.ListPushed(client, currentComponentName, applicationName) + LogErrorAndExit(err, "") + // Gather the output + for _, componentURL := range componentDesc.Spec.URL { + url := urls.Get(componentURL) + output += fmt.Sprintf(" · %v exposed via %v\n", urlPkg.GetURLString(url.Spec.Protocol, url.Spec.Host, ""), url.Spec.Port) } + } // Cut off the last newline and output if len(output) > 0 { diff --git a/pkg/url/url.go b/pkg/url/url.go index fee72e1ce86..c5b5a058f9a 100644 --- a/pkg/url/url.go +++ b/pkg/url/url.go @@ -242,7 +242,7 @@ type CreateParameters struct { // Create creates a URL and returns url string and error if any // portNumber is the target port number for the route and is -1 in case no port number is specified in which case it is automatically detected for components which expose only one service port) -func Create(client *occlient.Client, kClient *kclient.Client, parameters CreateParameters, isRouteSupported bool, isExperimental bool) (string, error) { +func Create(client *occlient.Client, kClient *kclient.Client, parameters CreateParameters, isRouteSupported bool) (string, error) { if parameters.urlKind != envinfo.INGRESS && parameters.urlKind != envinfo.ROUTE { return "", fmt.Errorf("urlKind %s is not supported for URL creation", parameters.urlKind) @@ -256,7 +256,7 @@ func Create(client *occlient.Client, kClient *kclient.Client, parameters CreateP serviceName := "" - if isExperimental && parameters.urlKind == envinfo.INGRESS && kClient != nil { + if parameters.urlKind == envinfo.INGRESS && kClient != nil { if parameters.host == "" { return "", errors.Errorf("the host cannot be empty") } @@ -318,14 +318,14 @@ func Create(client *occlient.Client, kClient *kclient.Client, parameters CreateP if err != nil { return "", errors.Wrap(err, "unable to create ingress") } - return GetURLString(GetProtocol(routev1.Route{}, *ingress), "", ingressDomain, isExperimental), nil + return GetURLString(GetProtocol(routev1.Route{}, *ingress), "", ingressDomain), nil } else { if !isRouteSupported { return "", errors.Errorf("routes are not available on non OpenShift clusters") } var ownerReference metav1.OwnerReference - if !isExperimental || kClient == nil { + if kClient == nil { var err error parameters.urlName, err = util.NamespaceOpenShiftObject(parameters.urlName, parameters.applicationName) if err != nil { @@ -360,7 +360,7 @@ func Create(client *occlient.Client, kClient *kclient.Client, parameters CreateP if err != nil { return "", errors.Wrap(err, "unable to create route") } - return GetURLString(GetProtocol(*route, iextensionsv1.Ingress{}), route.Spec.Host, "", isExperimental), nil + return GetURLString(GetProtocol(*route, iextensionsv1.Ingress{}), route.Spec.Host, ""), nil } } @@ -684,11 +684,11 @@ func ConvertEnvinfoURL(envinfoURL envinfo.EnvInfoURL, serviceName string) URL { } // GetURLString returns a string representation of given url -func GetURLString(protocol, URL string, ingressDomain string, isExperimentalMode bool) string { - if isExperimentalMode && URL == "" { - return protocol + "://" + ingressDomain - } - return protocol + "://" + URL +func GetURLString(protocol, URL string, ingressDomain string) string { + return protocol + "://" + ingressDomain + + // S2I only + //return protocol + "://" + URL } // Exists checks if the url exists in the component or not @@ -992,7 +992,7 @@ func Push(client *occlient.Client, kClient *kclient.Client, parameters PushParam secretName: urlInfo.Spec.TLSSecret, urlKind: urlInfo.Spec.Kind, } - host, err := Create(client, kClient, createParameters, parameters.IsRouteSupported, parameters.IsExperimentalModeEnabled) + host, err := Create(client, kClient, createParameters, parameters.IsRouteSupported) if err != nil { return err } diff --git a/pkg/url/url_test.go b/pkg/url/url_test.go index 59cfc2f7b47..6f69d7b7f83 100644 --- a/pkg/url/url_test.go +++ b/pkg/url/url_test.go @@ -35,16 +35,15 @@ import ( func TestCreate(t *testing.T) { type args struct { - componentName string - applicationName string - urlName string - portNumber int - secure bool - host string - urlKind envinfo.URLKind - isRouteSupported bool - isExperimentalModeEnabled bool - tlsSecret string + componentName string + applicationName string + urlName string + portNumber int + secure bool + host string + urlKind envinfo.URLKind + isRouteSupported bool + tlsSecret string } tests := []struct { name string @@ -170,13 +169,12 @@ func TestCreate(t *testing.T) { { name: "Case 4: Create a ingress, with same name as component,instead of route on openshift cluster", args: args{ - componentName: "nodejs", - urlName: "nodejs", - portNumber: 8080, - host: "com", - isRouteSupported: true, - isExperimentalModeEnabled: true, - urlKind: envinfo.INGRESS, + componentName: "nodejs", + urlName: "nodejs", + portNumber: 8080, + host: "com", + isRouteSupported: true, + urlKind: envinfo.INGRESS, }, returnedIngress: fake.GetSingleIngress("nodejs", "nodejs"), want: "http://nodejs.com", @@ -185,13 +183,12 @@ func TestCreate(t *testing.T) { { name: "Case 5: Create a ingress, with different name as component,instead of route on openshift cluster", args: args{ - componentName: "nodejs", - urlName: "example", - portNumber: 8080, - host: "com", - isRouteSupported: true, - isExperimentalModeEnabled: true, - urlKind: envinfo.INGRESS, + componentName: "nodejs", + urlName: "example", + portNumber: 8080, + host: "com", + isRouteSupported: true, + urlKind: envinfo.INGRESS, }, returnedRoute: &routev1.Route{ ObjectMeta: metav1.ObjectMeta{ @@ -222,14 +219,13 @@ func TestCreate(t *testing.T) { { name: "Case 6: Create a secure ingress, instead of route on openshift cluster, default tls exists", args: args{ - componentName: "nodejs", - urlName: "example", - portNumber: 8080, - host: "com", - isRouteSupported: true, - isExperimentalModeEnabled: true, - secure: true, - urlKind: envinfo.INGRESS, + componentName: "nodejs", + urlName: "example", + portNumber: 8080, + host: "com", + isRouteSupported: true, + secure: true, + urlKind: envinfo.INGRESS, }, returnedIngress: fake.GetSingleIngress("example", "nodejs"), defaultTLSExists: true, @@ -239,14 +235,13 @@ func TestCreate(t *testing.T) { { name: "Case 7: Create a secure ingress, instead of route on openshift cluster and default tls doesn't exist", args: args{ - componentName: "nodejs", - urlName: "example", - portNumber: 8080, - host: "com", - isRouteSupported: true, - isExperimentalModeEnabled: true, - secure: true, - urlKind: envinfo.INGRESS, + componentName: "nodejs", + urlName: "example", + portNumber: 8080, + host: "com", + isRouteSupported: true, + secure: true, + urlKind: envinfo.INGRESS, }, returnedIngress: fake.GetSingleIngress("example", "nodejs"), defaultTLSExists: false, @@ -256,15 +251,14 @@ func TestCreate(t *testing.T) { { name: "Case 8: Fail when while creating ingress when user given tls secret doesn't exists", args: args{ - componentName: "nodejs", - urlName: "example", - portNumber: 8080, - host: "com", - isRouteSupported: true, - isExperimentalModeEnabled: true, - secure: true, - tlsSecret: "user-secret", - urlKind: envinfo.INGRESS, + componentName: "nodejs", + urlName: "example", + portNumber: 8080, + host: "com", + isRouteSupported: true, + secure: true, + tlsSecret: "user-secret", + urlKind: envinfo.INGRESS, }, returnedIngress: fake.GetSingleIngress("example", "nodejs"), defaultTLSExists: false, @@ -275,15 +269,14 @@ func TestCreate(t *testing.T) { { name: "Case 9: Create a secure ingress, instead of route on openshift cluster, user tls secret does exists", args: args{ - componentName: "nodejs", - urlName: "example", - portNumber: 8080, - host: "com", - isRouteSupported: true, - isExperimentalModeEnabled: true, - secure: true, - tlsSecret: "user-secret", - urlKind: envinfo.INGRESS, + componentName: "nodejs", + urlName: "example", + portNumber: 8080, + host: "com", + isRouteSupported: true, + secure: true, + tlsSecret: "user-secret", + urlKind: envinfo.INGRESS, }, returnedIngress: fake.GetSingleIngress("example", "nodejs"), defaultTLSExists: false, @@ -295,15 +288,14 @@ func TestCreate(t *testing.T) { { name: "Case 10: invalid url kind", args: args{ - componentName: "nodejs", - urlName: "example", - portNumber: 8080, - host: "com", - isRouteSupported: true, - isExperimentalModeEnabled: true, - secure: true, - tlsSecret: "user-secret", - urlKind: "blah", + componentName: "nodejs", + urlName: "example", + portNumber: 8080, + host: "com", + isRouteSupported: true, + secure: true, + tlsSecret: "user-secret", + urlKind: "blah", }, returnedIngress: fake.GetSingleIngress("example", "nodejs"), defaultTLSExists: false, @@ -314,12 +306,11 @@ func TestCreate(t *testing.T) { { name: "Case 11: route is not supported on the cluster", args: args{ - componentName: "nodejs", - applicationName: "app", - urlName: "example", - isRouteSupported: false, - isExperimentalModeEnabled: true, - urlKind: envinfo.ROUTE, + componentName: "nodejs", + applicationName: "app", + urlName: "example", + isRouteSupported: false, + urlKind: envinfo.ROUTE, }, returnedIngress: fake.GetSingleIngress("example", "nodejs"), defaultTLSExists: false, @@ -330,13 +321,12 @@ func TestCreate(t *testing.T) { { name: "Case 11: secretName used without secure flag", args: args{ - componentName: "nodejs", - applicationName: "app", - urlName: "example", - isRouteSupported: false, - isExperimentalModeEnabled: true, - tlsSecret: "secret", - urlKind: envinfo.ROUTE, + componentName: "nodejs", + applicationName: "app", + urlName: "example", + isRouteSupported: false, + tlsSecret: "secret", + urlKind: envinfo.ROUTE, }, returnedIngress: fake.GetSingleIngress("example", "nodejs"), defaultTLSExists: false, @@ -412,7 +402,7 @@ func TestCreate(t *testing.T) { urlKind: tt.args.urlKind, } - got, err := Create(client, fakeKClient, urlCreateParameters, tt.args.isRouteSupported, tt.args.isExperimentalModeEnabled) + got, err := Create(client, fakeKClient, urlCreateParameters, tt.args.isRouteSupported) if err == nil && !tt.wantErr { if tt.args.urlKind == envinfo.INGRESS { @@ -741,8 +731,7 @@ func TestGetValidPortNumber(t *testing.T) { func TestPush(t *testing.T) { type args struct { - isRouteSupported bool - isExperimentalModeEnabled bool + isRouteSupported bool } tests := []struct { name string @@ -766,47 +755,50 @@ func TestPush(t *testing.T) { applicationName: "app", returnedRoutes: &routev1.RouteList{}, }, - { - name: "2 urls on local config and 0 on openshift cluster", - componentName: "nodejs", - applicationName: "app", - args: args{isRouteSupported: true}, - existingConfigURLs: []config.ConfigURL{ - { - Name: "example", - Port: 8080, - Secure: false, - }, - { - Name: "example-1", - Port: 9090, - Secure: false, - }, - }, - returnedRoutes: &routev1.RouteList{}, - createdURLs: []URL{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "example-app", - }, - Spec: URLSpec{ + // THIS TESTS S2I FUNCTIONALITY. Disabled since we are no longer doing s2i by default + /* + { + name: "2 urls on local config and 0 on openshift cluster", + componentName: "nodejs", + applicationName: "app", + args: args{isRouteSupported: true}, + existingConfigURLs: []config.ConfigURL{ + { + Name: "example", Port: 8080, Secure: false, - Kind: envinfo.ROUTE, }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "example-1-app", - }, - Spec: URLSpec{ + { + Name: "example-1", Port: 9090, Secure: false, - Kind: envinfo.ROUTE, + }, + }, + returnedRoutes: &routev1.RouteList{}, + createdURLs: []URL{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "example-app", + }, + Spec: URLSpec{ + Port: 8080, + Secure: false, + Kind: envinfo.ROUTE, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "example-1-app", + }, + Spec: URLSpec{ + Port: 9090, + Secure: false, + Kind: envinfo.ROUTE, + }, }, }, }, - }, + */ { name: "0 url on local config and 2 on openshift cluster", componentName: "wildfly", @@ -818,51 +810,54 @@ func TestPush(t *testing.T) { getMachineReadableFormat(testingutil.GetSingleRoute("example-1-app", 9100, "nodejs", "app")), }, }, - { - name: "2 url on local config and 2 on openshift cluster, but they are different", - componentName: "nodejs", - applicationName: "app", - args: args{isRouteSupported: true}, - existingConfigURLs: []config.ConfigURL{ - { - Name: "example-local-0", - Port: 8080, - Secure: false, - }, - { - Name: "example-local-1", - Port: 9090, - Secure: false, - }, - }, - returnedRoutes: testingutil.GetRouteListWithMultiple("nodejs", "app"), - deletedURLs: []URL{ - getMachineReadableFormat(testingutil.GetSingleRoute("example-app", 8080, "nodejs", "app")), - getMachineReadableFormat(testingutil.GetSingleRoute("example-1-app", 9100, "nodejs", "app")), - }, - createdURLs: []URL{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "example-local-0-app", - }, - Spec: URLSpec{ + // THIS TESTS S2I FUNCTIONALITY. Disabled since we are no longer doing s2i by default + /* + { + name: "2 url on local config and 2 on openshift cluster, but they are different", + componentName: "nodejs", + applicationName: "app", + args: args{isRouteSupported: true}, + existingConfigURLs: []config.ConfigURL{ + { + Name: "example-local-0", Port: 8080, Secure: false, - Kind: envinfo.ROUTE, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "example-local-1-app", }, - Spec: URLSpec{ + { + Name: "example-local-1", Port: 9090, Secure: false, - Kind: envinfo.ROUTE, + }, + }, + returnedRoutes: testingutil.GetRouteListWithMultiple("nodejs", "app"), + deletedURLs: []URL{ + getMachineReadableFormat(testingutil.GetSingleRoute("example-app", 8080, "nodejs", "app")), + getMachineReadableFormat(testingutil.GetSingleRoute("example-1-app", 9100, "nodejs", "app")), + }, + createdURLs: []URL{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "example-local-0-app", + }, + Spec: URLSpec{ + Port: 8080, + Secure: false, + Kind: envinfo.ROUTE, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "example-local-1-app", + }, + Spec: URLSpec{ + Port: 9090, + Secure: false, + Kind: envinfo.ROUTE, + }, }, }, }, - }, + */ { name: "2 url on local config and openshift cluster are in sync", componentName: "nodejs", @@ -888,7 +883,7 @@ func TestPush(t *testing.T) { { name: "0 urls on env file and cluster", componentName: "nodejs", - args: args{isRouteSupported: true, isExperimentalModeEnabled: true}, + args: args{isRouteSupported: true}, existingEnvInfoURLs: []envinfo.EnvInfoURL{}, returnedRoutes: &routev1.RouteList{}, returnedIngress: &extensionsv1.IngressList{}, @@ -896,7 +891,7 @@ func TestPush(t *testing.T) { { name: "2 urls on env file and 0 on openshift cluster", componentName: "nodejs", - args: args{isRouteSupported: true, isExperimentalModeEnabled: true}, + args: args{isRouteSupported: true}, existingEnvInfoURLs: []envinfo.EnvInfoURL{ { Name: "example", @@ -943,7 +938,7 @@ func TestPush(t *testing.T) { { name: "0 urls on env file and 2 on openshift cluster", componentName: "nodejs", - args: args{isRouteSupported: true, isExperimentalModeEnabled: true}, + args: args{isRouteSupported: true}, existingEnvInfoURLs: []envinfo.EnvInfoURL{}, returnedRoutes: &routev1.RouteList{}, returnedIngress: fake.GetIngressListWithMultiple("nodejs"), @@ -963,7 +958,7 @@ func TestPush(t *testing.T) { { name: "2 urls on env file and 2 on openshift cluster, but they are different", componentName: "wildfly", - args: args{isRouteSupported: true, isExperimentalModeEnabled: true}, + args: args{isRouteSupported: true}, existingEnvInfoURLs: []envinfo.EnvInfoURL{ { Name: "example-local-0", @@ -1022,7 +1017,7 @@ func TestPush(t *testing.T) { { name: "2 urls on env file and openshift cluster are in sync", componentName: "wildfly", - args: args{isRouteSupported: true, isExperimentalModeEnabled: true}, + args: args{isRouteSupported: true}, existingEnvInfoURLs: []envinfo.EnvInfoURL{ { Name: "example-0", @@ -1047,7 +1042,7 @@ func TestPush(t *testing.T) { { name: "2 (1 ingress,1 route) urls on env file and 2 on openshift cluster (1 ingress,1 route), but they are different", componentName: "nodejs", - args: args{isRouteSupported: true, isExperimentalModeEnabled: true}, + args: args{isRouteSupported: true}, existingEnvInfoURLs: []envinfo.EnvInfoURL{ { Name: "example-local-0", @@ -1104,7 +1099,7 @@ func TestPush(t *testing.T) { { name: "create a ingress on a kubernetes cluster", componentName: "nodejs", - args: args{isRouteSupported: false, isExperimentalModeEnabled: true}, + args: args{isRouteSupported: false}, existingEnvInfoURLs: []envinfo.EnvInfoURL{ { Name: "example", @@ -1136,7 +1131,7 @@ func TestPush(t *testing.T) { { name: "url with same name exists on env and cluster but with different specs", componentName: "nodejs", - args: args{isRouteSupported: true, isExperimentalModeEnabled: true}, + args: args{isRouteSupported: true}, existingEnvInfoURLs: []envinfo.EnvInfoURL{ { Name: "example-local-0", @@ -1172,50 +1167,52 @@ func TestPush(t *testing.T) { }, wantErr: false, }, - { - name: "url with same name exists on config and cluster but with different specs", - componentName: "nodejs", - applicationName: "app", - args: args{isRouteSupported: true, isExperimentalModeEnabled: false}, - existingConfigURLs: []config.ConfigURL{ - { - Name: "example-local-0", - Port: 8080, - Secure: false, - }, - }, - returnedRoutes: &routev1.RouteList{ - Items: []routev1.Route{ - testingutil.GetSingleRoute("example-local-0", 9090, "nodejs", "app"), - }, - }, - returnedIngress: &extensionsv1.IngressList{}, - createdURLs: []URL{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "example-local-0-app", - }, - Spec: URLSpec{ + // S2I related test, disabling + /* + { + name: "url with same name exists on config and cluster but with different specs", + componentName: "nodejs", + applicationName: "app", + args: args{isRouteSupported: true}, + existingConfigURLs: []config.ConfigURL{ + { + Name: "example-local-0", Port: 8080, Secure: false, - Kind: envinfo.ROUTE, }, }, - }, - deletedURLs: []URL{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "example-local-0-app", + returnedRoutes: &routev1.RouteList{ + Items: []routev1.Route{ + testingutil.GetSingleRoute("example-local-0", 9090, "nodejs", "app"), + }, + }, + returnedIngress: &extensionsv1.IngressList{}, + createdURLs: []URL{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "example-local-0-app", + }, + Spec: URLSpec{ + Port: 8080, + Secure: false, + Kind: envinfo.ROUTE, + }, + }, + }, + deletedURLs: []URL{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "example-local-0-app", + }, }, }, + wantErr: false, }, - wantErr: false, - }, - + */ { name: "create a secure route url", componentName: "nodejs", - args: args{isRouteSupported: true, isExperimentalModeEnabled: true}, + args: args{isRouteSupported: true}, existingEnvInfoURLs: []envinfo.EnvInfoURL{ { Name: "example", @@ -1242,7 +1239,7 @@ func TestPush(t *testing.T) { { name: "create a secure ingress url with empty user given tls secret", componentName: "nodejs", - args: args{isRouteSupported: true, isExperimentalModeEnabled: true}, + args: args{isRouteSupported: true}, existingEnvInfoURLs: []envinfo.EnvInfoURL{ { Name: "example", @@ -1271,7 +1268,7 @@ func TestPush(t *testing.T) { { name: "create a secure ingress url with user given tls secret", componentName: "nodejs", - args: args{isRouteSupported: true, isExperimentalModeEnabled: true}, + args: args{isRouteSupported: true}, existingEnvInfoURLs: []envinfo.EnvInfoURL{ { Name: "example", @@ -1338,12 +1335,11 @@ func TestPush(t *testing.T) { }) if err := Push(fakeClient, fakeKClient, PushParameters{ - ComponentName: tt.componentName, - ApplicationName: tt.applicationName, - ConfigURLs: tt.existingConfigURLs, - EnvURLS: tt.existingEnvInfoURLs, - IsRouteSupported: tt.args.isRouteSupported, - IsExperimentalModeEnabled: tt.args.isExperimentalModeEnabled, + ComponentName: tt.componentName, + ApplicationName: tt.applicationName, + ConfigURLs: tt.existingConfigURLs, + EnvURLS: tt.existingEnvInfoURLs, + IsRouteSupported: tt.args.isRouteSupported, }); (err != nil) != tt.wantErr { t.Errorf("Push() error = %v, wantErr %v", err, tt.wantErr) } else {