-
-
Notifications
You must be signed in to change notification settings - Fork 153
Expand file tree
/
Copy pathplanfile.go
More file actions
130 lines (111 loc) · 4.3 KB
/
planfile.go
File metadata and controls
130 lines (111 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package generate
import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/cloudposse/atmos/cmd/terraform/shared"
errUtils "github.com/cloudposse/atmos/errors"
e "github.com/cloudposse/atmos/internal/exec"
cfg "github.com/cloudposse/atmos/pkg/config"
"github.com/cloudposse/atmos/pkg/flags"
"github.com/cloudposse/atmos/pkg/schema"
)
// planfileParser handles flag parsing for planfile command.
var planfileParser *flags.StandardParser
// planfileCmd generates planfile for a terraform component.
var planfileCmd = &cobra.Command{
Use: "planfile [component]",
Short: "Generate a planfile for a Terraform component",
Long: "This command generates a `planfile` for a specified Atmos Terraform component.",
Args: cobra.MaximumNArgs(1),
FParseErrWhitelist: struct{ UnknownFlags bool }{UnknownFlags: false},
RunE: func(cmd *cobra.Command, args []string) error {
var component string
if len(args) > 0 {
component = args[0]
}
// Use Viper to respect precedence (flag > env > config > default)
v := viper.GetViper()
// Bind planfile-specific flags to Viper.
if err := planfileParser.BindFlagsToViper(cmd, v); err != nil {
return err
}
// Prompt for component if missing.
if component == "" {
prompted, err := shared.PromptForComponent(cmd)
if err = shared.HandlePromptError(err, "component"); err != nil {
return err
}
component = prompted
}
// Validate component after prompting.
if component == "" {
return errUtils.ErrMissingComponent
}
// Get flag values from Viper.
stack := v.GetString("stack")
file := v.GetString("file")
outputPath := v.GetString("output-path")
format := v.GetString("format")
processTemplates := v.GetBool("process-templates")
processFunctions := v.GetBool("process-functions")
skip := v.GetStringSlice("skip")
// Prompt for stack if missing.
if stack == "" {
prompted, err := shared.PromptForStack(cmd, component)
if err = shared.HandlePromptError(err, "stack"); err != nil {
return err
}
stack = prompted
}
// Validate stack after prompting.
if stack == "" {
return errUtils.ErrMissingStack
}
// Initialize Atmos configuration
atmosConfig, err := cfg.InitCliConfig(schema.ConfigAndStacksInfo{}, true)
if err != nil {
return err
}
opts := &e.PlanfileOptions{
Component: component,
Stack: stack,
File: file,
OutputPath: outputPath,
Format: format,
ProcessTemplates: processTemplates,
ProcessYamlFunctions: processFunctions,
Skip: skip,
}
return e.ExecuteGeneratePlanfile(opts, &atmosConfig)
},
}
func init() {
// Create parser with planfile-specific flags using functional options.
planfileParser = flags.NewStandardParser(
flags.WithStringFlag("stack", "s", "", "Atmos stack (required)"),
flags.WithStringFlag("file", "f", "", "Planfile name"),
flags.WithStringFlag("output-path", "o", "", "Output path for planfile using default naming ({stack}-{component}.planfile.{format})"),
flags.WithStringFlag("format", "", "json", "Output format: json or yaml"),
flags.WithBoolFlag("process-templates", "", true, "Enable Go template processing in Atmos stack manifests"),
flags.WithBoolFlag("process-functions", "", true, "Enable YAML functions processing in Atmos stack manifests"),
flags.WithStringSliceFlag("skip", "", []string{}, "Skip processing specific Atmos YAML functions"),
flags.WithEnvVars("stack", "ATMOS_STACK"),
flags.WithEnvVars("file", "ATMOS_FILE"),
flags.WithEnvVars("output-path", "ATMOS_OUTPUT_PATH"),
flags.WithEnvVars("format", "ATMOS_FORMAT"),
flags.WithEnvVars("process-templates", "ATMOS_PROCESS_TEMPLATES"),
flags.WithEnvVars("process-functions", "ATMOS_PROCESS_FUNCTIONS"),
flags.WithEnvVars("skip", "ATMOS_SKIP"),
)
// Register flags with the command.
planfileParser.RegisterFlags(planfileCmd)
// Mark file and output-path as mutually exclusive.
planfileCmd.MarkFlagsMutuallyExclusive("file", "output-path")
// Bind flags to Viper for environment variable support.
if err := planfileParser.BindToViper(viper.GetViper()); err != nil {
panic(err)
}
// Register shell completion for component.
planfileCmd.ValidArgsFunction = shared.ComponentsArgCompletion
GenerateCmd.AddCommand(planfileCmd)
}