Skip to content

Commit

Permalink
Cleaning up cli docs
Browse files Browse the repository at this point in the history
Signed-off-by: Mohammed Zeeshan Ahmed <mohammed.zee1000@gmail.com>
  • Loading branch information
mohammedzee1000 committed Jul 19, 2021
1 parent ae0b990 commit a3c592e
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 128 deletions.
25 changes: 7 additions & 18 deletions pkg/odo/cli/service/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,26 @@ const (
"{{if .ServiceName}} {{.ServiceName}}{{end}}" +
" --app {{.Application}}" +
" --project {{.Project}}" +
"{{if .Plan}} --plan {{.Plan}}{{end}}" +
"{{range $key, $value := .ParametersMap}} -p {{$key}}={{$value}}{{end}}"
)

var (
createExample = ktemplates.Examples(`
# Create new postgresql service from service catalog using dev plan and name my-postgresql-db.
%[1]s dh-postgresql-apb my-postgresql-db --plan dev -p postgresql_user=luke -p postgresql_password=secret`)

createOperatorExample = ktemplates.Examples(`
# Create new EtcdCluster service from etcdoperator.v0.9.4 operator.
%[1]s etcdoperator.v0.9.4/EtcdCluster`)

createShortDesc = `Create a new service from Operator Hub or Service Catalog and deploy it on OpenShift.`
createShortDesc = `Create a new service from Operator Hub and deploy it on Kubernetes or OpenShift.`

createLongDesc = ktemplates.LongDesc(`
Create a new service from Operator Hub or Service Catalog and deploy it on OpenShift.
Create a new service from Operator Hub and deploy it on Kubernetes or OpenShift.
Service creation can be performed from a valid component directory (one containing a devfile.yaml) only.
To create the service from outside a component directory, specify path to a valid component directory using "--context" flag.
When creating a service using Operator Hub, provide a service name along with Operator name.
When creating a service, provide a service name along with Operator name.
When creating a service using Service Catalog, a --plan must be passed along with the service type. Parameters to configure the service are passed as key=value pairs.
Parameters to configure the service are passed as key=value pairs.
For a full list of service types, use: 'odo catalog list services'`)
)
Expand All @@ -55,8 +50,6 @@ For a full list of service types, use: 'odo catalog list services'`)
type CreateOptions struct {
// parameters hold the user-provided values for service class parameters via flags (populated by cobra)
parameters []string
// Plan is the selected service plan
Plan string
// ServiceType corresponds to the service class name
ServiceType string
// ServiceName is how the service will be named and known by odo
Expand Down Expand Up @@ -171,28 +164,24 @@ func NewCmdServiceCreate(name, fullName string) *cobra.Command {
o := NewCreateOptions()
o.CmdFullName = fullName
serviceCreateCmd := &cobra.Command{
Use: name + " <service_type> --plan <plan_name> [service_name]",
Use: fmt.Sprintf(" [flags]\n %s <operator_type>/<crd_name> [service_name] [flags]", o.CmdFullName),
Short: createShortDesc,
Long: createLongDesc,
Example: fmt.Sprintf(createExample, fullName),
Example: fmt.Sprintf(createOperatorExample, fullName),
Args: cobra.RangeArgs(0, 2),
Run: func(cmd *cobra.Command, args []string) {
genericclioptions.GenericRun(o, cmd, args)
},
}

serviceCreateCmd.Use += fmt.Sprintf(" [flags]\n %s <operator_type>/<crd_name> [service_name] [flags]", o.CmdFullName)
serviceCreateCmd.Example += "\n\n" + fmt.Sprintf(createOperatorExample, fullName)
serviceCreateCmd.Flags().BoolVar(&o.DryRun, "dry-run", false, "Print the yaml specificiation that will be used to create the operator backed service")
serviceCreateCmd.Flags().BoolVar(&o.DryRun, "dry-run", false, "Print the yaml specification that will be used to create the operator backed 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 <key>=<value")
serviceCreateCmd.Flags().BoolVarP(&o.wait, "wait", "w", false, "Wait until the service is ready")
genericclioptions.AddContextFlag(serviceCreateCmd, &o.componentContext)
completion.RegisterCommandHandler(serviceCreateCmd, completion.ServiceClassCompletionHandler)
completion.RegisterCommandFlagHandler(serviceCreateCmd, "plan", completion.ServicePlanCompletionHandler)
completion.RegisterCommandFlagHandler(serviceCreateCmd, "parameters", completion.ServiceParameterCompletionHandler)
return serviceCreateCmd
}
9 changes: 3 additions & 6 deletions pkg/odo/cli/service/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,8 @@ func TestOutputNonInteractiveEquivalent(t *testing.T) {
outputCLI: true,
ServiceType: "foo",
ServiceName: "myservice",
Plan: "dev",
},
expected: RecommendedCommandName + " foo myservice --app app --project testproject --plan dev",
expected: RecommendedCommandName + " foo myservice --app app --project testproject",
},
{
name: "service class and plan",
Expand All @@ -71,9 +70,8 @@ func TestOutputNonInteractiveEquivalent(t *testing.T) {
CmdFullName: RecommendedCommandName,
outputCLI: true,
ServiceType: "foo",
Plan: "dev",
},
expected: RecommendedCommandName + " foo --app app --project testproject --plan dev",
expected: RecommendedCommandName + " foo --app app --project testproject",
},
{
name: "service class and empty params",
Expand Down Expand Up @@ -105,10 +103,9 @@ func TestOutputNonInteractiveEquivalent(t *testing.T) {
outputCLI: true,
ServiceType: "foo",
ServiceName: "name",
Plan: "plan",
ParametersMap: map[string]string{"param1": "value1", "param2": "value2"},
},
expected: RecommendedCommandName + " foo name --app app --project testproject --plan plan -p param1=value1 -p param2=value2",
expected: RecommendedCommandName + " foo name --app app --project testproject -p param1=value1 -p param2=value2",
},
}

Expand Down
33 changes: 0 additions & 33 deletions pkg/odo/util/completion/completionhandlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,39 +58,6 @@ var ServiceClassCompletionHandler = func(cmd *cobra.Command, args parsedArgs, co
return
}

// ServicePlanCompletionHandler provides completion for the the plan of a selected service
var ServicePlanCompletionHandler = func(cmd *cobra.Command, args parsedArgs, context *genericclioptions.Context) (completions []string) {
completions = make([]string, 0)
// if we have less than two arguments, it means the user didn't specify the name of the service
// meaning that there is no point in providing suggestions
if len(args.original.Completed) < 2 {
complete.Log("Couldn't extract the service name")
return completions
}

inputServiceName := args.original.Completed[1]

complete.Log(fmt.Sprintf("Using input: serviceName = %s", inputServiceName))

clusterServiceClass, err := context.Client.GetKubeClient().GetClusterServiceClass(inputServiceName)
if err != nil {
complete.Log("Error retrieving details of service")
return completions
}

servicePlans, err := context.Client.GetKubeClient().ListClusterServicePlansByServiceName(clusterServiceClass.Name)
if err != nil {
complete.Log("Error retrieving details of plans of service")
return completions
}

for _, servicePlan := range servicePlans {
completions = append(completions, servicePlan.Spec.ExternalName)
}

return completions
}

// ServiceParameterCompletionHandler provides completion for the parameter names of a selected service and plan
var ServiceParameterCompletionHandler = func(cmd *cobra.Command, args parsedArgs, context *genericclioptions.Context) (completions []string) {
completions = make([]string, 0)
Expand Down
71 changes: 0 additions & 71 deletions pkg/odo/util/completion/completionhandlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,77 +21,6 @@ import (
ktesting "k8s.io/client-go/testing"
)

func TestServicePlanCompletionHandler(t *testing.T) {
serviceClassList := &scv1beta1.ClusterServiceClassList{
Items: []scv1beta1.ClusterServiceClass{testingutil.FakeClusterServiceClass("class name", "dummy")},
}
tests := []struct {
name string
returnedServiceClass *scv1beta1.ClusterServiceClassList
returnedServicePlan []scv1beta1.ClusterServicePlan
output []string
parsedArgs parsedArgs
}{
{
name: "Case 0: no service name supplied",
parsedArgs: parsedArgs{
original: complete.Args{
Completed: []string{"create"},
},
},
output: []string{},
},
{
name: "Case 1: single plan exists",
returnedServiceClass: serviceClassList,
returnedServicePlan: []scv1beta1.ClusterServicePlan{testingutil.FakeClusterServicePlan("default", 1)},
parsedArgs: parsedArgs{
original: complete.Args{
Completed: []string{"create", "class name"},
},
},
output: []string{"default"},
},
{
name: "Case 2: multiple plans exist",
returnedServiceClass: serviceClassList,
returnedServicePlan: []scv1beta1.ClusterServicePlan{
testingutil.FakeClusterServicePlan("plan1", 1),
testingutil.FakeClusterServicePlan("plan2", 2),
},
parsedArgs: parsedArgs{
original: complete.Args{
Completed: []string{"create", "class name"},
},
},
output: []string{"plan1", "plan2"},
},
}

for _, tt := range tests {
client, fakeClientSet := occlient.FakeNew()
context := genericclioptions.NewFakeContext("project", "app", "component", client, nil)

fakeClientSet.ServiceCatalogClientSet.PrependReactor("list", "clusterserviceclasses", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, tt.returnedServiceClass, nil
})

fakeClientSet.ServiceCatalogClientSet.PrependReactor("list", "clusterserviceplans", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &scv1beta1.ClusterServicePlanList{Items: tt.returnedServicePlan}, nil
})

completions := ServicePlanCompletionHandler(nil, tt.parsedArgs, context)

// Sort the output and expected output in order to avoid false negatives (since ordering of the results is not important)
sort.Strings(completions)
sort.Strings(tt.output)

if !reflect.DeepEqual(tt.output, completions) {
t.Errorf("expected output: %#v,got: %#v", tt.output, completions)
}
}
}

func TestServiceParameterCompletionHandler(t *testing.T) {
serviceClassList := &scv1beta1.ClusterServiceClassList{
Items: []scv1beta1.ClusterServiceClass{testingutil.FakeClusterServiceClass("class name", "dummy")},
Expand Down

0 comments on commit a3c592e

Please sign in to comment.