github.com/jenkins-x/jx/v2@v2.1.155/pkg/cmd/step/verify/step_verify_url.go (about) 1 package verify 2 3 import ( 4 "crypto/tls" 5 "fmt" 6 "net/http" 7 "time" 8 9 "github.com/jenkins-x/jx-logging/pkg/log" 10 "github.com/jenkins-x/jx/v2/pkg/cmd/helper" 11 "github.com/jenkins-x/jx/v2/pkg/cmd/opts" 12 "github.com/jenkins-x/jx/v2/pkg/cmd/opts/step" 13 "github.com/jenkins-x/jx/v2/pkg/cmd/templates" 14 "github.com/jenkins-x/jx/v2/pkg/util" 15 "github.com/pkg/errors" 16 "github.com/spf13/cobra" 17 ) 18 19 const ( 20 optionEndpoint = "endpoint" 21 optionCode = "code" 22 optionTimeout = "timeout" 23 optionInsecureSkipVerify = "insecureSkipVerify" 24 ) 25 26 var ( 27 stepVerifyURLLong = templates.LongDesc(` 28 This step checks the status of a URL 29 `) 30 31 stepVerifyURLExample = templates.Examples(` 32 jx step verify url --endpoint https://jenkins-x.io 33 `) 34 ) 35 36 // StepVerifyURLOptions options for step verify url command 37 type StepVerifyURLOptions struct { 38 step.StepOptions 39 40 Endpoint string 41 Code int 42 Timeout time.Duration 43 InsecureSkipVerify bool 44 } 45 46 // NewCmdStepVerifyURL creates a new verify url command 47 func NewCmdStepVerifyURL(commonOpts *opts.CommonOptions) *cobra.Command { 48 options := StepVerifyURLOptions{ 49 StepOptions: step.StepOptions{ 50 CommonOptions: commonOpts, 51 }, 52 } 53 54 cmd := &cobra.Command{ 55 Use: "url", 56 Short: "Verifies a URL returns an expected HTTP code", 57 Long: stepVerifyURLLong, 58 Example: stepVerifyURLExample, 59 Run: func(cmd *cobra.Command, args []string) { 60 options.Cmd = cmd 61 options.Args = args 62 err := options.Run() 63 helper.CheckErr(err) 64 }, 65 } 66 67 cmd.Flags().StringVarP(&options.Endpoint, optionEndpoint, "e", "", "The endpoint on which to wait for expected HTTP code") 68 cmd.Flags().IntVarP(&options.Code, optionCode, "c", http.StatusOK, "The HTTP code which should be returned by the endpoint") 69 cmd.Flags().DurationVarP(&options.Timeout, optionTimeout, "t", 10*time.Minute, "The default timeout for the endpoint to return the expected HTTP code") 70 cmd.Flags().BoolVarP(&options.InsecureSkipVerify, optionInsecureSkipVerify, "i", false, "If the URL requires an insucure request") 71 return cmd 72 } 73 74 func (o *StepVerifyURLOptions) checkFlags() error { 75 if o.Endpoint == "" { 76 return util.MissingOption(optionEndpoint) 77 } 78 79 return nil 80 } 81 82 func (o *StepVerifyURLOptions) logError(err error) error { 83 log.Logger().Infof("Retrying due to: %s", err) 84 return err 85 } 86 87 // Run waits with exponential backoff for an endpoint to return an expected HTTP status code 88 func (o *StepVerifyURLOptions) Run() error { 89 if err := o.checkFlags(); err != nil { 90 return errors.Wrap(err, "checking flags") 91 } 92 93 tr := &http.Transport{} 94 if o.InsecureSkipVerify { 95 tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} // #nosec 96 } 97 client := &http.Client{Transport: tr} 98 99 log.Logger().Infof("Waiting for %q endpoint to return %d HTTP code", o.Endpoint, o.Code) 100 101 start := time.Now() 102 103 err := util.Retry(o.Timeout, func() error { 104 resp, err := client.Get(o.Endpoint) 105 if err != nil { 106 return o.logError(err) 107 } 108 if resp.StatusCode != o.Code { 109 err := fmt.Errorf("invalid status code %d expecting %d", resp.StatusCode, o.Code) 110 return o.logError(err) 111 } 112 return nil 113 }) 114 if err != nil { 115 return errors.Wrapf(err, "waiting for %q", o.Endpoint) 116 } 117 118 elapsed := time.Since(start) 119 log.Logger().Infof("Endpoint %q returns expected status code %d in %s", o.Endpoint, o.Code, elapsed) 120 return nil 121 }