From 270929e7ffe171b5361ea4531dd95fd406a310fe Mon Sep 17 00:00:00 2001 From: Gerd Oberlechner Date: Wed, 20 Nov 2024 22:21:24 +0100 Subject: [PATCH] env vars Signed-off-by: Gerd Oberlechner --- templatize.sh | 2 +- .../cmd/pipeline/inspect/options.go | 10 ++- tooling/templatize/pkg/pipeline/inspect.go | 61 ++++++++++++------- tooling/templatize/pkg/pipeline/shell.go | 30 ++++++--- tooling/templatize/pkg/utils/env.go | 26 ++++++++ 5 files changed, 97 insertions(+), 32 deletions(-) create mode 100644 tooling/templatize/pkg/utils/env.go diff --git a/templatize.sh b/templatize.sh index 92ef70ad8..4b47439ed 100755 --- a/templatize.sh +++ b/templatize.sh @@ -138,7 +138,7 @@ elif [ -n "$PIPELINE" ] && [ -n "$PIPELINE_STEP" ]; then --pipeline-file=${PIPELINE} \ --step=${PIPELINE_STEP} \ --aspect vars \ - --format Makefile + --format makefile else $TEMPLATIZE inspect \ --config-file=${CONFIG_FILE} \ diff --git a/tooling/templatize/cmd/pipeline/inspect/options.go b/tooling/templatize/cmd/pipeline/inspect/options.go index 209f1eb6a..5ec480249 100644 --- a/tooling/templatize/cmd/pipeline/inspect/options.go +++ b/tooling/templatize/cmd/pipeline/inspect/options.go @@ -3,6 +3,7 @@ package inspect import ( "context" "fmt" + "os" "github.com/spf13/cobra" @@ -61,7 +62,12 @@ func (o *RawInspectOptions) Validate() (*ValidatedInspectOptions, error) { if err != nil { return nil, err } - // todo validate aspect + + inspectScopes := pipeline.NewStepInspectScopes() + if _, ok := inspectScopes[o.Aspect]; !ok { + return nil, fmt.Errorf("unknown inspect scope %q", o.Aspect) + } + return &ValidatedInspectOptions{ validatedInspectOptions: &validatedInspectOptions{ RawInspectOptions: o, @@ -106,5 +112,5 @@ func (o *InspectOptions) RunInspect(ctx context.Context) error { Step: o.PipelineOptions.Step, Aspect: o.Aspect, Format: o.Format, - }) + }, os.Stdout) } diff --git a/tooling/templatize/pkg/pipeline/inspect.go b/tooling/templatize/pkg/pipeline/inspect.go index 5ed262a74..a6fa999c5 100644 --- a/tooling/templatize/pkg/pipeline/inspect.go +++ b/tooling/templatize/pkg/pipeline/inspect.go @@ -3,20 +3,17 @@ package pipeline import ( "context" "fmt" - "strings" + "io" "github.com/Azure/ARO-HCP/tooling/templatize/pkg/config" ) -type StepInspectScope func(*step, *PipelineInspectOptions) error +type StepInspectScope func(*step, *PipelineInspectOptions, io.Writer) error -var stepInspectScopes = map[string]StepInspectScope{ - "vars": inspectVars, -} - -func init() { - // Initialize the map with function pointers - stepInspectScopes["vars"] = inspectVars +func NewStepInspectScopes() map[string]StepInspectScope { + return map[string]StepInspectScope{ + "vars": inspectVars, + } } type PipelineInspectOptions struct { @@ -27,12 +24,13 @@ type PipelineInspectOptions struct { Vars config.Variables } -func (p *Pipeline) Inspect(ctx context.Context, options *PipelineInspectOptions) error { +func (p *Pipeline) Inspect(ctx context.Context, options *PipelineInspectOptions, writer io.Writer) error { + stepInspectScopes := NewStepInspectScopes() for _, rg := range p.ResourceGroups { for _, step := range rg.Steps { if step.Name == options.Step { if inspectFunc, ok := stepInspectScopes[options.Aspect]; ok { - err := inspectFunc(step, options) + err := inspectFunc(step, options, writer) if err != nil { return err } @@ -46,19 +44,38 @@ func (p *Pipeline) Inspect(ctx context.Context, options *PipelineInspectOptions) return fmt.Errorf("step %q not found", options.Step) } -func inspectVars(s *step, options *PipelineInspectOptions) error { +func inspectVars(s *step, options *PipelineInspectOptions, writer io.Writer) error { + var envVars map[string]string + var err error switch s.Action { case "Shell": - envVars, err := s.getEnvVars(options.Vars, false) - if err != nil { - return err - } - for _, e := range envVars { - parts := strings.SplitN(e, "=", 2) - fmt.Printf("%s ?= %s\n", parts[0], parts[1]) - } - return nil + envVars, err = s.getEnvVars(options.Vars, false) default: - return fmt.Errorf("dumping step variables not implemented for action type %q", s.Action) + return fmt.Errorf("inspecting step variables not implemented for action type %s", s.Action) + } + if err != nil { + return err + } + + switch options.Format { + case "makefile": + printMakefileVars(envVars, writer) + case "shell": + printShellVars(envVars, writer) + default: + return fmt.Errorf("unknown output format %q", options.Format) + } + return nil +} + +func printMakefileVars(vars map[string]string, writer io.Writer) { + for k, v := range vars { + fmt.Fprintf(writer, "%s ?= %s\n", k, v) + } +} + +func printShellVars(vars map[string]string, writer io.Writer) { + for k, v := range vars { + fmt.Fprintf(writer, "export %s=\"%s\"\n", k, v) } } diff --git a/tooling/templatize/pkg/pipeline/shell.go b/tooling/templatize/pkg/pipeline/shell.go index a473ff17f..39dcc985c 100644 --- a/tooling/templatize/pkg/pipeline/shell.go +++ b/tooling/templatize/pkg/pipeline/shell.go @@ -7,6 +7,7 @@ import ( "os/exec" "github.com/Azure/ARO-HCP/tooling/templatize/pkg/config" + "github.com/Azure/ARO-HCP/tooling/templatize/pkg/utils" ) func (s *step) runShellStep(ctx context.Context, executionTarget *ExecutionTarget, options *PipelineRunOptions) error { @@ -27,7 +28,7 @@ func (s *step) runShellStep(ctx context.Context, executionTarget *ExecutionTarge fmt.Printf("Warning: failed to delete kubeconfig file %s: %v\n", kubeconfigFile, err) } }() - envVars = append(envVars, fmt.Sprintf("KUBECONFIG=%s", kubeconfigFile)) + envVars["KUBECONFIG"] = kubeconfigFile } // TODO handle dry-run @@ -35,7 +36,7 @@ func (s *step) runShellStep(ctx context.Context, executionTarget *ExecutionTarge // execute the command fmt.Printf("Executing shell command: %s - %s\n", s.Command[0], s.Command[1:]) cmd := exec.CommandContext(ctx, s.Command[0], s.Command[1:]...) - cmd.Env = append(cmd.Env, envVars...) + cmd.Env = append(cmd.Env, utils.MapToEnvVarArray(envVars)...) output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("failed to execute shell command: %s %w", string(output), err) @@ -47,18 +48,33 @@ func (s *step) runShellStep(ctx context.Context, executionTarget *ExecutionTarge return nil } -func (s *step) getEnvVars(vars config.Variables, includeOSEnvVars bool) ([]string, error) { - envVars := make([]string, 0) +func (s *step) getEnvVars(vars config.Variables, includeOSEnvVars bool) (map[string]string, error) { + envVars := make(map[string]string) + envVars["RUNS_IN_TEMPLATIZE"] = "1" if includeOSEnvVars { - envVars = append(envVars, os.Environ()...) + for k, v := range utils.GetOSEnvVarsAsMap() { + envVars[k] = v + } } - envVars = append(envVars, "RUNS_IN_TEMPLATIZE=1") for _, e := range s.Env { value, found := vars.GetByPath(e.ConfigRef) if !found { return nil, fmt.Errorf("failed to lookup config reference %s for %s", e.ConfigRef, e.Name) } - envVars = append(envVars, fmt.Sprintf("%s=%s", e.Name, value)) + envVars[e.Name] = anyToString(value) } return envVars, nil } + +func anyToString(value any) string { + switch v := value.(type) { + case string: + return v + case int: + return fmt.Sprintf("%d", v) + case bool: + return fmt.Sprintf("%t", v) + default: + return fmt.Sprintf("%v", v) + } +} diff --git a/tooling/templatize/pkg/utils/env.go b/tooling/templatize/pkg/utils/env.go new file mode 100644 index 000000000..84c51b537 --- /dev/null +++ b/tooling/templatize/pkg/utils/env.go @@ -0,0 +1,26 @@ +package utils + +import ( + "fmt" + "os" + "strings" +) + +func GetOSEnvVarsAsMap() map[string]string { + envVars := make(map[string]string) + for _, env := range os.Environ() { + parts := strings.SplitN(env, "=", 2) + if len(parts) == 2 { + envVars[parts[0]] = parts[1] + } + } + return envVars +} + +func MapToEnvVarArray(envVars map[string]string) []string { + envVarArray := make([]string, 0, len(envVars)) + for k, v := range envVars { + envVarArray = append(envVarArray, fmt.Sprintf("%s=%s", k, v)) + } + return envVarArray +}