github.com/spinnaker/spin@v1.30.0/cmd/pipeline/execute.go (about) 1 // Copyright (c) 2018, Google, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package pipeline 16 17 import ( 18 "errors" 19 "fmt" 20 "net/http" 21 "strings" 22 23 "github.com/antihax/optional" 24 "github.com/spf13/cobra" 25 26 gate "github.com/spinnaker/spin/gateapi" 27 "github.com/spinnaker/spin/util" 28 ) 29 30 type executeOptions struct { 31 *PipelineOptions 32 output string 33 application string 34 name string 35 parameterFile string 36 artifactsFile string 37 parameters []string 38 } 39 40 var ( 41 executePipelineShort = "Execute the provided pipeline" 42 executePipelineLong = "Execute the provided pipeline" 43 ) 44 45 func NewExecuteCmd(pipelineOptions *PipelineOptions) *cobra.Command { 46 options := &executeOptions{ 47 PipelineOptions: pipelineOptions, 48 } 49 cmd := &cobra.Command{ 50 Use: "execute", 51 Aliases: []string{"exec"}, 52 Short: executePipelineShort, 53 Long: executePipelineLong, 54 RunE: func(cmd *cobra.Command, args []string) error { 55 return executePipeline(cmd, options) 56 }, 57 } 58 59 cmd.PersistentFlags().StringVarP(&options.application, "application", "a", "", "Spinnaker application the pipeline lives in") 60 cmd.PersistentFlags().StringVarP(&options.name, "name", "n", "", "name of the pipeline to execute") 61 cmd.PersistentFlags().StringVarP(&options.parameterFile, "parameter-file", "f", "", "file to load pipeline parameter values from") 62 cmd.PersistentFlags().StringVarP(&options.artifactsFile, "artifacts-file", "t", "", "file to load pipeline artifacts from") 63 cmd.PersistentFlags().StringSliceVarP(&options.parameters, "parameter", "p", []string{}, "parameter in the form of key=value. can be used repeatedly.") 64 65 return cmd 66 } 67 68 func executePipeline(cmd *cobra.Command, options *executeOptions) error { 69 if options.application == "" || options.name == "" { 70 return errors.New("one of required parameters 'application' or 'name' not set") 71 } 72 73 parameters := map[string]interface{}{} 74 if options.parameterFile != "" { 75 p, err := util.ParseJsonFromFile(options.parameterFile, true) 76 if err != nil { 77 return fmt.Errorf("Could not parse supplied pipeline parameters: %v.\n", err) 78 } 79 parameters = p 80 } else if len(options.parameters) > 0 { 81 for _, p := range options.parameters { 82 // split each passed parameter on = 83 kv := strings.SplitN(p, "=", 2) 84 if len(kv) == 2 { 85 parameters[kv[0]] = kv[1] 86 } 87 } 88 } 89 90 artifactsFile := map[string]interface{}{} 91 artifactsFile, err := util.ParseJsonFromFile(options.artifactsFile, true) 92 if err != nil { 93 return fmt.Errorf("Could not parse supplied artifacts: %v.\n", err) 94 } 95 96 trigger := map[string]interface{}{"type": "manual"} 97 if len(parameters) > 0 { 98 trigger["parameters"] = parameters 99 } 100 101 if _, ok := artifactsFile["artifacts"]; ok { 102 artifacts := artifactsFile["artifacts"].([]interface{}) 103 if len(artifacts) > 0 { 104 trigger["artifacts"] = artifacts 105 } 106 } 107 108 resp, err := options.GateClient.PipelineControllerApi.InvokePipelineConfigUsingPOST1(options.GateClient.Context, 109 options.application, 110 options.name, 111 &gate.PipelineControllerApiInvokePipelineConfigUsingPOST1Opts{Trigger: optional.NewInterface(trigger)}) 112 if err != nil { 113 return fmt.Errorf("Execute pipeline failed with response: %v and error: %s\n", resp, err) 114 } 115 116 if resp.StatusCode != http.StatusAccepted { 117 return fmt.Errorf("Encountered an error executing pipeline, status code: %d\n", resp.StatusCode) 118 } 119 120 options.Ui.Success("Pipeline execution started") 121 122 return nil 123 }