github.com/diggerhq/digger/libs@v0.0.0-20240604170430-9d61cdf01cc5/digger_config/yaml.go (about) 1 package digger_config 2 3 import ( 4 "errors" 5 6 "gopkg.in/yaml.v3" 7 ) 8 9 type DiggerConfigYaml struct { 10 ApplyAfterMerge *bool `yaml:"apply_after_merge"` 11 AllowDraftPRs *bool `yaml:"allow_draft_prs"` 12 DependencyConfiguration *DependencyConfigurationYaml `yaml:"dependency_configuration"` 13 Projects []*ProjectYaml `yaml:"projects"` 14 AutoMerge *bool `yaml:"auto_merge"` 15 CommentRenderMode *string `yaml:"comment_render_mode"` 16 Workflows map[string]*WorkflowYaml `yaml:"workflows"` 17 Telemetry *bool `yaml:"telemetry,omitempty"` 18 GenerateProjectsConfig *GenerateProjectsConfigYaml `yaml:"generate_projects"` 19 TraverseToNestedProjects *bool `yaml:"traverse_to_nested_projects"` 20 MentionDriftedProjectsInPR *bool `yaml:"mention_drifted_projects_in_pr"` 21 } 22 23 type DependencyConfigurationYaml struct { 24 Mode string `yaml:"mode"` 25 } 26 27 type ProjectYaml struct { 28 Name string `yaml:"name"` 29 Dir string `yaml:"dir"` 30 Workspace string `yaml:"workspace"` 31 Terragrunt bool `yaml:"terragrunt"` 32 OpenTofu bool `yaml:"opentofu"` 33 Workflow string `yaml:"workflow"` 34 WorkflowFile *string `yaml:"workflow_file""` 35 IncludePatterns []string `yaml:"include_patterns,omitempty"` 36 ExcludePatterns []string `yaml:"exclude_patterns,omitempty"` 37 DependencyProjects []string `yaml:"depends_on,omitempty"` 38 DriftDetection *bool `yaml:"drift_detection,omitempty"` 39 AwsRoleToAssume *AssumeRoleForProjectConfig `yaml:"aws_role_to_assume,omitempty"` 40 } 41 42 type WorkflowYaml struct { 43 EnvVars *TerraformEnvConfigYaml `yaml:"env_vars"` 44 Plan *StageYaml `yaml:"plan,omitempty"` 45 Apply *StageYaml `yaml:"apply,omitempty"` 46 Configuration *WorkflowConfigurationYaml `yaml:"workflow_configuration"` 47 } 48 49 type WorkflowConfigurationYaml struct { 50 OnPullRequestPushed []string `yaml:"on_pull_request_pushed"` 51 OnPullRequestClosed []string `yaml:"on_pull_request_closed"` 52 // pull request converted to draft 53 OnPullRequestConvertedToDraft []string `yaml:"on_pull_request_to_draft"` 54 OnCommitToDefault []string `yaml:"on_commit_to_default"` 55 } 56 57 func (s *StageYaml) ToCoreStage() Stage { 58 var steps []Step 59 for _, step := range s.Steps { 60 steps = append(steps, step.ToCoreStep()) 61 } 62 return Stage{Steps: steps} 63 } 64 65 type StageYaml struct { 66 Steps []StepYaml `yaml:"steps"` 67 } 68 69 type StepYaml struct { 70 Action string 71 Value string 72 ExtraArgs []string `yaml:"extra_args,omitempty"` 73 Shell string 74 } 75 76 type TerraformEnvConfigYaml struct { 77 State []EnvVarYaml `yaml:"state"` 78 Commands []EnvVarYaml `yaml:"commands"` 79 } 80 81 type EnvVarYaml struct { 82 Name string `yaml:"name"` 83 ValueFrom string `yaml:"value_from"` 84 Value string `yaml:"value"` 85 } 86 87 type BlockYaml struct { 88 Include string `yaml:"include"` 89 Exclude string `yaml:"exclude"` 90 Workflow string `yaml:"workflow"` 91 AwsRoleToAssume *AssumeRoleForProjectConfig `yaml:"aws_role_to_assume,omitempty"` 92 } 93 94 type AssumeRoleForProjectConfig struct { 95 AwsRoleRegion string `yaml:"aws_role_region"` 96 State string `yaml:"state"` 97 Command string `yaml:"command"` 98 } 99 100 type GenerateProjectsConfigYaml struct { 101 Include string `yaml:"include"` 102 Exclude string `yaml:"exclude"` 103 Terragrunt bool `yaml:"terragrunt"` 104 Blocks []BlockYaml `yaml:"blocks"` 105 TerragruntParsingConfig *TerragruntParsingConfig `yaml:"terragrunt_parsing,omitempty"` 106 AwsRoleToAssume *AssumeRoleForProjectConfig `yaml:"aws_role_to_assume,omitempty"` 107 } 108 109 type TerragruntParsingConfig struct { 110 GitRoot *string `yaml:"gitRoot,omitempty"` 111 AutoPlan bool `yaml:"autoPlan"` 112 AutoMerge bool `yaml:"autoMerge"` 113 IgnoreParentTerragrunt *bool `yaml:"ignoreParentTerragrunt,omitempty"` 114 CreateParentProject bool `yaml:"createParentProject"` 115 IgnoreDependencyBlocks bool `yaml:"ignoreDependencyBlocks"` 116 Parallel *bool `yaml:"parallel,omitempty"` 117 CreateWorkspace bool `yaml:"createWorkspace"` 118 CreateProjectName bool `yaml:"createProjectName"` 119 DefaultTerraformVersion string `yaml:"defaultTerraformVersion"` 120 DefaultWorkflow string `yaml:"defaultWorkflow"` 121 FilterPath string `yaml:"filterPath"` 122 OutputPath string `yaml:"outputPath"` 123 PreserveWorkflows *bool `yaml:"preserveWorkflows,omitempty"` 124 PreserveProjects bool `yaml:"preserveProjects"` 125 CascadeDependencies *bool `yaml:"cascadeDependencies,omitempty"` 126 DefaultApplyRequirements []string `yaml:"defaultApplyRequirements"` 127 //NumExecutors int64 `yaml:"numExecutors"` 128 ProjectHclFiles []string `yaml:"projectHclFiles"` 129 CreateHclProjectChilds bool `yaml:"createHclProjectChilds"` 130 CreateHclProjectExternalChilds *bool `yaml:"createHclProjectExternalChilds,omitempty"` 131 UseProjectMarkers bool `yaml:"useProjectMarkers"` 132 ExecutionOrderGroups *bool `yaml:"executionOrderGroups"` 133 } 134 135 func (p *ProjectYaml) UnmarshalYAML(unmarshal func(interface{}) error) error { 136 type rawProject ProjectYaml 137 raw := rawProject{ 138 Workspace: "default", 139 Terragrunt: false, 140 Workflow: "default", 141 } 142 if err := unmarshal(&raw); err != nil { 143 return err 144 } 145 *p = ProjectYaml(raw) 146 return nil 147 } 148 149 func (w *WorkflowYaml) UnmarshalYAML(unmarshal func(interface{}) error) error { 150 type rawWorkflow WorkflowYaml 151 raw := rawWorkflow{ 152 Configuration: &WorkflowConfigurationYaml{ 153 OnCommitToDefault: []string{"digger unlock"}, 154 OnPullRequestPushed: []string{"digger plan"}, 155 OnPullRequestClosed: []string{"digger unlock"}, 156 }, 157 Plan: &StageYaml{ 158 Steps: []StepYaml{ 159 { 160 Action: "init", ExtraArgs: []string{}, 161 }, 162 { 163 Action: "plan", ExtraArgs: []string{}, 164 }, 165 }, 166 }, 167 Apply: &StageYaml{ 168 Steps: []StepYaml{ 169 { 170 Action: "init", ExtraArgs: []string{}, 171 }, 172 { 173 Action: "apply", ExtraArgs: []string{}, 174 }, 175 }, 176 }, 177 EnvVars: &TerraformEnvConfigYaml{ 178 State: []EnvVarYaml{}, 179 Commands: []EnvVarYaml{}, 180 }, 181 } 182 if err := unmarshal(&raw); err != nil { 183 return err 184 } 185 if err := validateWorkflowConfigurationYaml(raw.Configuration); err != nil { 186 return err 187 } 188 *w = WorkflowYaml(raw) 189 return nil 190 } 191 192 func validateWorkflowConfigurationYaml(config *WorkflowConfigurationYaml) error { 193 if config != nil { 194 if config.OnPullRequestPushed == nil { 195 return errors.New("workflow_configuration.on_pull_request_pushed is required") 196 } 197 if config.OnPullRequestClosed == nil { 198 return errors.New("workflow_configuration.on_pull_request_closed is required") 199 } 200 if config.OnCommitToDefault == nil { 201 return errors.New("workflow_configuration.on_commit_to_default is required") 202 } 203 } 204 return nil 205 } 206 207 func (s *StepYaml) UnmarshalYAML(value *yaml.Node) error { 208 209 if value.Kind == yaml.ScalarNode { 210 return value.Decode(&s.Action) 211 } 212 213 var stepMap map[string]interface{} 214 if err := value.Decode(&stepMap); err != nil { 215 return err 216 } 217 218 if _, ok := stepMap["run"]; ok { 219 s.Action = "run" 220 s.Value = stepMap["run"].(string) 221 if _, ok := stepMap["shell"]; ok { 222 s.Shell = stepMap["shell"].(string) 223 } 224 return nil 225 } 226 227 s.extract(stepMap, "init") 228 s.extract(stepMap, "plan") 229 s.extract(stepMap, "apply") 230 231 return nil 232 } 233 234 func (s *StepYaml) ToCoreStep() Step { 235 return Step{ 236 Action: s.Action, 237 Value: s.Value, 238 ExtraArgs: s.ExtraArgs, 239 Shell: s.Shell, 240 } 241 } 242 243 func (s *StepYaml) extract(stepMap map[string]interface{}, action string) { 244 if _, ok := stepMap[action]; ok { 245 s.Action = action 246 var extraArgs []string 247 if v, ok := stepMap["extra_args"]; ok { 248 for _, v := range v.([]interface{}) { 249 extraArgs = append(extraArgs, v.(string)) 250 } 251 s.ExtraArgs = extraArgs 252 } else { 253 if stepMap[action] != nil { 254 if v, ok := stepMap[action].(map[string]interface{})["extra_args"]; ok { 255 for _, v := range v.([]interface{}) { 256 extraArgs = append(extraArgs, v.(string)) 257 } 258 s.ExtraArgs = extraArgs 259 } 260 } 261 } 262 } 263 }