github.com/kubeshop/testkube@v1.17.23/cmd/kubectl-testkube/commands/testsuites/create.go (about) 1 package testsuites 2 3 import ( 4 "fmt" 5 "os" 6 "strconv" 7 8 "github.com/robfig/cron" 9 "github.com/spf13/cobra" 10 11 "github.com/kubeshop/testkube/cmd/kubectl-testkube/commands/common" 12 apiClient "github.com/kubeshop/testkube/pkg/api/v1/client" 13 "github.com/kubeshop/testkube/pkg/api/v1/testkube" 14 "github.com/kubeshop/testkube/pkg/crd" 15 "github.com/kubeshop/testkube/pkg/ui" 16 ) 17 18 func NewCreateTestSuitesCmd() *cobra.Command { 19 20 var ( 21 name string 22 file string 23 labels map[string]string 24 variables []string 25 secretVariables []string 26 schedule string 27 executionName string 28 httpProxy, httpsProxy string 29 secretVariableReferences map[string]string 30 timeout int32 31 jobTemplate string 32 cronJobTemplate string 33 scraperTemplate string 34 pvcTemplate string 35 jobTemplateReference string 36 cronJobTemplateReference string 37 scraperTemplateReference string 38 pvcTemplateReference string 39 update bool 40 ) 41 42 cmd := &cobra.Command{ 43 Use: "testsuite", 44 Aliases: []string{"testsuites", "ts"}, 45 Short: "Create new TestSuite", 46 Long: `Create new TestSuite Custom Resource`, 47 Run: func(cmd *cobra.Command, args []string) { 48 crdOnly, err := strconv.ParseBool(cmd.Flag("crd-only").Value.String()) 49 ui.ExitOnError("parsing flag value", err) 50 51 options, err := NewTestSuiteUpsertOptionsFromFlags(cmd) 52 ui.ExitOnError("getting test suite options", err) 53 54 if options.Name == "" { 55 ui.Failf("pass valid test suite name (in '--name' flag)") 56 } 57 58 if !crdOnly { 59 client, namespace, err := common.GetClient(cmd) 60 ui.ExitOnError("getting client", err) 61 62 testSuite, _ := client.GetTestSuite(options.Name) 63 64 if options.Name == testSuite.Name { 65 if cmd.Flag("update").Changed { 66 if !update { 67 ui.Failf("TestSuite with name '%s' already exists in namespace %s, ", testSuite.Name, namespace) 68 } 69 } else { 70 var ok bool 71 if stat, _ := os.Stdin.Stat(); (stat.Mode() & os.ModeCharDevice) != 0 { 72 ok = ui.Confirm(fmt.Sprintf("TestSuite with name '%s' already exists in namespace %s, ", testSuite.Name, namespace) + 73 "do you want to overwrite it?") 74 } 75 76 if !ok { 77 ui.Failf("TestSuite creation was aborted") 78 } 79 } 80 81 options, err := NewTestSuiteUpdateOptionsFromFlags(cmd) 82 ui.ExitOnError("getting test suite options", err) 83 84 testSuite, err = client.UpdateTestSuite(options) 85 ui.ExitOnError("updating TestSuite "+testSuite.Name+" in namespace "+namespace, err) 86 87 ui.SuccessAndExit("TestSuite updated", testSuite.Name) 88 } 89 90 _, err = client.CreateTestSuite(apiClient.UpsertTestSuiteOptions(options)) 91 ui.ExitOnError("creating test suite "+options.Name+" in namespace "+options.Namespace, err) 92 93 ui.Success("Test suite created", options.Name) 94 } else { 95 (*testkube.TestSuiteUpsertRequest)(&options).QuoteTestSuiteTextFields() 96 data, err := crd.ExecuteTemplate(crd.TemplateTestSuite, options) 97 ui.ExitOnError("executing crd template", err) 98 99 ui.Info(data) 100 } 101 }, 102 } 103 104 cmd.Flags().StringVarP(&file, "file", "f", "", "JSON test suite file - will be read from stdin if not specified, look at testkube.TestUpsertRequest") 105 cmd.Flags().StringVar(&name, "name", "", "Set/Override test suite name") 106 cmd.Flags().StringToStringVarP(&labels, "label", "l", nil, "label key value pair: --label key1=value1") 107 cmd.Flags().StringArrayVarP(&variables, "variable", "v", nil, "param key value pair: --variable key1=value1") 108 cmd.Flags().StringArrayVarP(&secretVariables, "secret-variable", "s", nil, "secret variable key value pair: --secret-variable key1=value1") 109 cmd.Flags().StringVarP(&schedule, "schedule", "", "", "test suite schedule in a cron job form: * * * * *") 110 cmd.Flags().StringVarP(&executionName, "execution-name", "", "", "execution name, if empty will be autogenerated") 111 cmd.Flags().StringVar(&httpProxy, "http-proxy", "", "http proxy for executor containers") 112 cmd.Flags().StringVar(&httpsProxy, "https-proxy", "", "https proxy for executor containers") 113 cmd.Flags().StringToStringVarP(&secretVariableReferences, "secret-variable-reference", "", nil, "secret variable references in a form name1=secret_name1=secret_key1") 114 cmd.Flags().Int32Var(&timeout, "timeout", 0, "duration in seconds for test suite to timeout. 0 disables timeout.") 115 cmd.Flags().StringVar(&jobTemplate, "job-template", "", "job template file path for extensions to job template") 116 cmd.Flags().StringVar(&cronJobTemplate, "cronjob-template", "", "cron job template file path for extensions to cron job template") 117 cmd.Flags().StringVar(&scraperTemplate, "scraper-template", "", "scraper template file path for extensions to scraper template") 118 cmd.Flags().StringVar(&pvcTemplate, "pvc-template", "", "pvc template file path for extensions to pvc template") 119 cmd.Flags().StringVar(&jobTemplateReference, "job-template-reference", "", "reference to job template to use for the test") 120 cmd.Flags().StringVar(&cronJobTemplateReference, "cronjob-template-reference", "", "reference to cron job template to use for the test") 121 cmd.Flags().StringVar(&scraperTemplateReference, "scraper-template-reference", "", "reference to scraper template to use for the test") 122 cmd.Flags().StringVar(&pvcTemplateReference, "pvc-template-reference", "", "reference to pvc template to use for the test") 123 cmd.Flags().BoolVar(&update, "update", false, "update, if test suite already exists") 124 125 return cmd 126 } 127 128 func validateSchedule(schedule string) error { 129 if schedule == "" { 130 return nil 131 } 132 133 specParser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow) 134 if _, err := specParser.Parse(schedule); err != nil { 135 return err 136 } 137 138 return nil 139 }