github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/cmd/create/create_variable.go (about) 1 package create 2 3 import ( 4 "fmt" 5 "path/filepath" 6 7 "github.com/olli-ai/jx/v2/pkg/cmd/create/options" 8 9 "github.com/olli-ai/jx/v2/pkg/cmd/helper" 10 11 "github.com/jenkins-x/jx-logging/pkg/log" 12 "github.com/olli-ai/jx/v2/pkg/cmd/opts" 13 "github.com/olli-ai/jx/v2/pkg/cmd/templates" 14 "github.com/olli-ai/jx/v2/pkg/config" 15 "github.com/olli-ai/jx/v2/pkg/jenkinsfile" 16 "github.com/olli-ai/jx/v2/pkg/jenkinsfile/gitresolver" 17 "github.com/olli-ai/jx/v2/pkg/kube" 18 "github.com/olli-ai/jx/v2/pkg/util" 19 "github.com/pkg/errors" 20 "github.com/spf13/cobra" 21 ) 22 23 var ( 24 createVariableLong = templates.LongDesc(` 25 Creates an environment variable in the Jenkins X Pipeline 26 `) 27 28 createVariableExample = templates.Examples(` 29 # Create a new environment variable with a name and value 30 jx create var -n CHEESE -v Edam 31 32 # Create a new environment variable with a name and ask the user for the value 33 jx create var -n CHEESE 34 35 # Overrides an environment variable from the build pack 36 jx create var 37 `) 38 ) 39 40 // CreateVariableOptions the options for the create spring command 41 type CreateVariableOptions struct { 42 options.CreateOptions 43 44 Dir string 45 Name string 46 Value string 47 } 48 49 // NewCmdCreateVariable creates a command object for the "create" command 50 func NewCmdCreateVariable(commonOpts *opts.CommonOptions) *cobra.Command { 51 options := &CreateVariableOptions{ 52 CreateOptions: options.CreateOptions{ 53 CommonOptions: commonOpts, 54 }, 55 } 56 57 cmd := &cobra.Command{ 58 Use: "variable", 59 Short: "Creates an environment variable in the Jenkins X Pipeline", 60 Aliases: []string{"var", "envvar"}, 61 Long: createVariableLong, 62 Example: createVariableExample, 63 Run: func(cmd *cobra.Command, args []string) { 64 options.Cmd = cmd 65 options.Args = args 66 err := options.Run() 67 helper.CheckErr(err) 68 }, 69 } 70 71 cmd.Flags().StringVarP(&options.Name, "name", "n", "", "The name of the environment variable to set") 72 cmd.Flags().StringVarP(&options.Value, "value", "v", "", "The value of the environment variable to set") 73 cmd.Flags().StringVarP(&options.Dir, "dir", "d", "", "The root project directory. Defaults to the current dir") 74 return cmd 75 } 76 77 // Run implements the command 78 func (o *CreateVariableOptions) Run() error { 79 dir := o.Dir 80 var err error 81 if dir == "" { 82 dir, _, err := o.Git().FindGitConfigDir(o.Dir) 83 if err != nil { 84 return err 85 } 86 if dir == "" { 87 dir = "." 88 } 89 } 90 projectConfig, fileName, err := config.LoadProjectConfig(dir) 91 if err != nil { 92 return err 93 } 94 enrichedProjectConfig, _, err := config.LoadProjectConfig(dir) 95 if err != nil { 96 return err 97 } 98 99 name := o.Name 100 value := o.Value 101 if o.BatchMode { 102 if name == "" { 103 return util.MissingOption("name") 104 } 105 if value == "" { 106 return util.MissingOption("value") 107 } 108 } 109 110 defaultValues, err := o.loadEnvVars(enrichedProjectConfig) 111 if err != nil { 112 return err 113 } 114 keys := util.SortedMapKeys(defaultValues) 115 116 if name == "" { 117 message := "environment variable name: " 118 help := "the name of the environment variable which is usually upper case without spaces or dashes" 119 if len(keys) == 0 { 120 name, err = util.PickValue(message, "", true, help, o.GetIOFileHandles()) 121 } else { 122 name, err = util.PickName(keys, message, help, o.GetIOFileHandles()) 123 } 124 if err != nil { 125 return err 126 } 127 if name == "" { 128 return util.MissingOption("name") 129 } 130 } 131 if value == "" { 132 message := "environment variable value: " 133 value, err = util.PickValue(message, defaultValues[name], true, "", o.GetIOFileHandles()) 134 if err != nil { 135 return err 136 } 137 if name == "" { 138 return util.MissingOption("name") 139 } 140 } 141 142 if projectConfig.PipelineConfig == nil { 143 projectConfig.PipelineConfig = &jenkinsfile.PipelineConfig{} 144 } 145 projectConfig.PipelineConfig.Env = kube.SetEnvVar(projectConfig.PipelineConfig.Env, name, value) 146 147 err = projectConfig.SaveConfig(fileName) 148 if err != nil { 149 return err 150 } 151 log.Logger().Infof("Updated Jenkins X Pipeline file: %s", util.ColorInfo(fileName)) 152 return nil 153 154 } 155 156 func (o *CreateVariableOptions) loadEnvVars(projectConfig *config.ProjectConfig) (map[string]string, error) { 157 answer := map[string]string{} 158 159 teamSettings, err := o.TeamSettings() 160 if err != nil { 161 return answer, err 162 } 163 164 packsDir, err := gitresolver.InitBuildPack(o.Git(), teamSettings.BuildPackURL, teamSettings.BuildPackRef) 165 if err != nil { 166 return answer, err 167 } 168 169 resolver, err := gitresolver.CreateResolver(packsDir, o.Git()) 170 if err != nil { 171 return answer, err 172 } 173 174 name := projectConfig.BuildPack 175 if name == "" { 176 name, err = o.DiscoverBuildPack(o.Dir, projectConfig, name) 177 if err != nil { 178 return answer, err 179 } 180 } 181 if projectConfig.PipelineConfig == nil { 182 projectConfig.PipelineConfig = &jenkinsfile.PipelineConfig{} 183 } 184 pipelineConfig := projectConfig.PipelineConfig 185 if name != "none" { 186 packDir := filepath.Join(packsDir, name) 187 pipelineFile := filepath.Join(packDir, jenkinsfile.PipelineConfigFileName) 188 exists, err := util.FileExists(pipelineFile) 189 if err != nil { 190 return answer, errors.Wrapf(err, "failed to find build pack pipeline YAML: %s", pipelineFile) 191 } 192 if !exists { 193 return answer, fmt.Errorf("no build pack for %s exists at directory %s", name, packDir) 194 } 195 buildPackPipelineConfig, err := jenkinsfile.LoadPipelineConfig(pipelineFile, resolver, true, false) 196 if err != nil { 197 return answer, errors.Wrapf(err, "failed to load build pack pipeline YAML: %s", pipelineFile) 198 } 199 err = pipelineConfig.ExtendPipeline(buildPackPipelineConfig, false) 200 if err != nil { 201 return answer, errors.Wrapf(err, "failed to override PipelineConfig using configuration in file %s", pipelineFile) 202 } 203 } 204 205 kubeClient, ns, err := o.KubeClientAndDevNamespace() 206 if err != nil { 207 return answer, err 208 } 209 210 answer = pipelineConfig.GetAllEnvVars() 211 212 podTemplates, err := kube.LoadPodTemplates(kubeClient, ns) 213 if err != nil { 214 return answer, err 215 } 216 containerName := pipelineConfig.Agent.GetImage() 217 if containerName != "" && podTemplates != nil && podTemplates[containerName] != nil { 218 podTemplate := podTemplates[containerName] 219 if len(podTemplate.Spec.Containers) > 0 { 220 container := podTemplate.Spec.Containers[0] 221 for _, env := range container.Env { 222 if env.Value != "" || answer[env.Name] == "" { 223 answer[env.Name] = env.Value 224 } 225 } 226 } 227 } 228 return answer, nil 229 }