diff --git a/internal/exec/helmfile.go b/internal/exec/helmfile.go index 4b2c8d303..dd422a380 100644 --- a/internal/exec/helmfile.go +++ b/internal/exec/helmfile.go @@ -63,6 +63,11 @@ func ExecuteHelmfile(info schema.ConfigAndStacksInfo) error { return errors.New("stack must be specified") } + if !info.ComponentIsEnabled { + u.LogInfo(cliConfig, fmt.Sprintf("component '%s' is not enabled and skipped", info.ComponentFromArg)) + return nil + } + err = checkHelmfileConfig(cliConfig) if err != nil { return err diff --git a/internal/exec/stack_utils.go b/internal/exec/stack_utils.go index eeba73308..573be3573 100644 --- a/internal/exec/stack_utils.go +++ b/internal/exec/stack_utils.go @@ -54,13 +54,14 @@ func BuildTerraformWorkspace(cliConfig schema.CliConfiguration, configAndStacksI return strings.Replace(workspace, "/", "-", -1), nil } -// ProcessComponentMetadata processes component metadata and returns a base component (if any) and whether the component is real or abstract +// ProcessComponentMetadata processes component metadata and returns a base component (if any) and whether the component is real or abstract and whether the component is disabled or not func ProcessComponentMetadata( component string, componentSection map[string]any, -) (map[string]any, string, bool) { +) (map[string]any, string, bool, bool) { baseComponentName := "" componentIsAbstract := false + componentIsEnabled := true var componentMetadata map[string]any // Find base component in the `component` attribute @@ -75,6 +76,11 @@ func ProcessComponentMetadata( componentIsAbstract = true } } + if enabledValue, exists := componentMetadata["enabled"]; exists { + if enabled, ok := enabledValue.(bool); ok && !enabled { + componentIsEnabled = false + } + } // Find base component in the `metadata.component` attribute // `metadata.component` overrides `component` if componentMetadataComponent, componentMetadataComponentExists := componentMetadata[cfg.ComponentSectionName].(string); componentMetadataComponentExists { @@ -87,7 +93,7 @@ func ProcessComponentMetadata( baseComponentName = "" } - return componentMetadata, baseComponentName, componentIsAbstract + return componentMetadata, baseComponentName, componentIsAbstract, componentIsEnabled } // BuildDependentStackNameFromDependsOnLegacy builds the dependent stack name from "settings.spacelift.depends_on" config diff --git a/internal/exec/terraform.go b/internal/exec/terraform.go index 7b3153fd4..cffe26734 100644 --- a/internal/exec/terraform.go +++ b/internal/exec/terraform.go @@ -70,6 +70,11 @@ func ExecuteTerraform(info schema.ConfigAndStacksInfo) error { return errors.New("stack must be specified") } + if !info.ComponentIsEnabled { + u.LogInfo(cliConfig, fmt.Sprintf("component '%s' is not enabled and skipped", info.ComponentFromArg)) + return nil + } + err = checkTerraformConfig(cliConfig) if err != nil { return err diff --git a/internal/exec/utils.go b/internal/exec/utils.go index 8eea02068..b2ac1342f 100644 --- a/internal/exec/utils.go +++ b/internal/exec/utils.go @@ -129,7 +129,8 @@ func ProcessComponentConfig( } // Process component metadata and find a base component (if any) and whether the component is real or abstract - componentMetadata, baseComponentName, componentIsAbstract := ProcessComponentMetadata(component, componentSection) + componentMetadata, baseComponentName, componentIsAbstract, componentIsEnabled := ProcessComponentMetadata(component, componentSection) + configAndStacksInfo.ComponentIsEnabled = componentIsEnabled // Remove the ENV vars that are set to `null` in the `env` section. // Setting an ENV var to `null` in stack config has the effect of unsetting it @@ -391,7 +392,7 @@ func ProcessStacks( } } - if foundStackCount == 0 { + if foundStackCount == 0 && configAndStacksInfo.ComponentIsEnabled { cliConfigYaml := "" if cliConfig.Logs.Level == u.LogLevelTrace { @@ -573,8 +574,9 @@ func ProcessStacks( configAndStacksInfo.ComponentEnvList = u.ConvertEnvVars(configAndStacksInfo.ComponentEnvSection) // Process component metadata - _, baseComponentName, _ := ProcessComponentMetadata(configAndStacksInfo.ComponentFromArg, configAndStacksInfo.ComponentSection) + _, baseComponentName, _, componentIsEnabled := ProcessComponentMetadata(configAndStacksInfo.ComponentFromArg, configAndStacksInfo.ComponentSection) configAndStacksInfo.BaseComponentPath = baseComponentName + configAndStacksInfo.ComponentIsEnabled = componentIsEnabled // Process component path and name configAndStacksInfo.ComponentFolderPrefix = "" diff --git a/pkg/schema/schema.go b/pkg/schema/schema.go index 89e90b061..41b677970 100644 --- a/pkg/schema/schema.go +++ b/pkg/schema/schema.go @@ -196,6 +196,7 @@ type ConfigAndStacksInfo struct { ComponentImportsSection []string NeedHelp bool ComponentIsAbstract bool + ComponentIsEnabled bool ComponentMetadataSection AtmosSectionMapType TerraformWorkspace string JsonSchemaDir string diff --git a/pkg/spacelift/spacelift_stack_processor.go b/pkg/spacelift/spacelift_stack_processor.go index 0401298a2..353b0166b 100644 --- a/pkg/spacelift/spacelift_stack_processor.go +++ b/pkg/spacelift/spacelift_stack_processor.go @@ -172,9 +172,9 @@ func TransformStackConfigToSpaceliftStacks( } // Process component metadata and find a base component (if any) and whether the component is real or abstract - componentMetadata, baseComponentName, componentIsAbstract := e.ProcessComponentMetadata(component, componentMap) + componentMetadata, baseComponentName, componentIsAbstract, componentIsEnabled := e.ProcessComponentMetadata(component, componentMap) - if componentIsAbstract { + if componentIsAbstract || !componentIsEnabled { continue } diff --git a/website/docs/core-concepts/stacks/define-components.mdx b/website/docs/core-concepts/stacks/define-components.mdx index e7406c9eb..9ec3c0389 100644 --- a/website/docs/core-concepts/stacks/define-components.mdx +++ b/website/docs/core-concepts/stacks/define-components.mdx @@ -212,3 +212,25 @@ There are two types of components: