Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supported the atmos.d, allowing automatic inclusion of configuration files from the atmos.d directory #808

Open
wants to merge 71 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
892cfeb
feat: add support for importing configurations from local and remote …
haitham911 Nov 24, 2024
052673b
refactor: streamline configuration initialization and enhance import …
haitham911 Nov 24, 2024
63ffce1
fix: sort full matches instead of initial matches in GetGlobMatches f…
haitham911 Nov 24, 2024
000e439
fix: add json and mapstructure tags to Import field in CliConfiguration
haitham911 Nov 24, 2024
4493540
fix: handle unexpected errors when checking for atmos.d path in InitC…
haitham911 Nov 24, 2024
d1903c4
fix: update atmos.yaml to include wildcard import for YAML files and …
haitham911 Nov 24, 2024
d9a3517
fix: remove obsolete configuration files and update atmos.yaml for cl…
haitham911 Nov 24, 2024
089a82f
fix: validate import paths to prevent directory traversal in InitCliC…
haitham911 Nov 24, 2024
c020d63
fix: enhance downloadRemoteConfig to return temporary directory and h…
haitham911 Nov 24, 2024
31c844c
fix: remove environment variable from extra-config.yaml for cleaner c…
haitham911 Nov 30, 2024
d70f66f
feat: update YAML configurations to define commands and enhance compo…
haitham911 Dec 3, 2024
512e02e
fix: replace path package with filepath for consistent path handling
haitham911 Dec 3, 2024
c22624f
Merge branch 'main' into DEV-1534
osterman Dec 4, 2024
750f4b5
feat: enhance CLI configuration loading logic to prioritize ATMOS_CLI…
haitham911 Dec 7, 2024
8eeda00
feat: reorganize configuration files and enhance YAML support for log…
haitham911 Dec 11, 2024
a8d3528
feat: rename environment variable for clarity and improve test handli…
haitham911 Dec 11, 2024
d8a00ef
feat: update remote configuration URL in atmos.yaml for improved acce…
haitham911 Dec 11, 2024
8050589
feat: restructure configuration files and remove deprecated logging s…
haitham911 Dec 11, 2024
52b170d
feat: migrate custom import configuration files to a new structure fo…
haitham911 Dec 11, 2024
f85d53e
feat: remove deprecated custom import configuration files and update …
haitham911 Dec 11, 2024
73d9255
feat: add URL validation for remote imports to enhance error handling
haitham911 Dec 12, 2024
9913b54
feat: update configuration documentation to clarify CLI config loadin…
haitham911 Dec 12, 2024
cdb9fa1
fix: correct example paths in CLI configuration documentation for cla…
haitham911 Dec 12, 2024
7090975
fix: clarify environment variable usage in CLI configuration document…
haitham911 Dec 12, 2024
3dfb2e0
Update examples/demo-atmos-cli-imports/configs.d/vendor.yaml
osterman Dec 12, 2024
cdafe20
enhance CLI configuration documentation with detailed import examples…
haitham911 Dec 13, 2024
b702884
fix: improve atmos.d path validation and add support for .atmos.d dir…
haitham911 Dec 13, 2024
8704668
fix: update command in demo configuration and improve URL validation …
haitham911 Dec 13, 2024
989cd9e
Merge branch 'main' into DEV-1534
haitham911 Dec 17, 2024
a7414bb
add env demo
haitham911 Dec 17, 2024
3a24ee6
expose env variable ATMOS_CLI_CONFIG_PATH and ATMOS_BASE_PATH before…
haitham911 Dec 18, 2024
061ba9c
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
e57aacb
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
e6a3200
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
fa5f25e
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
86e2505
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
95cdf74
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
bc2c4bc
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
8e6998a
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
87d4b0f
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
31d71c1
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
e64d2eb
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
378897c
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
e8d8507
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
6e4bc4d
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
930fde6
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
94e99d6
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
85957a4
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
b75c251
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
a742412
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
30c82d2
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
0609a78
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
1c02902
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
792ff0a
Apply suggestions from code review
osterman Dec 20, 2024
33da5d0
Apply suggestions from code review
osterman Dec 20, 2024
885bd00
Apply suggestions from code review
osterman Dec 20, 2024
b933331
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 20, 2024
50cd50e
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 30, 2024
aafdf16
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 30, 2024
3bb33fa
Update examples/demo-env/stacks/deploy/prod.yaml
osterman Dec 30, 2024
a55f6f2
Update website/docs/cli/configuration/configuration.mdx
osterman Dec 30, 2024
66c0a59
Apply suggestions from code review
osterman Dec 30, 2024
27d3acd
Apply suggestions from code review
osterman Dec 30, 2024
1d46232
revise the docs for intended behavior
osterman Dec 30, 2024
9a27195
Make it more clear
osterman Dec 30, 2024
bce6c4d
Merge branch 'main' into DEV-1534
haitham911 Jan 5, 2025
f45cf0d
fix missed from marge main branch
haitham911 Jan 5, 2025
1d33e16
change to atmosConfig
haitham911 Jan 5, 2025
f9e44cd
replace cliConfig with atmosConfig
haitham911 Jan 5, 2025
086c8c6
add mermaid for configuration
haitham911 Jan 5, 2025
bf02e59
edit mermaid doc
haitham911 Jan 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/demo-atmos.d/atmos.d/config1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
logs:
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
level: Debug
settings:
retries: 3
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
5 changes: 5 additions & 0 deletions examples/demo-atmos.d/atmos.d/sub/config2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
logs:
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
level: Warning
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
settings:
timeout: 30s
haitham911 marked this conversation as resolved.
Show resolved Hide resolved

41 changes: 41 additions & 0 deletions examples/demo-atmos.d/atmos.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Description: Configuration file for the Atmos CLI
# default import path is ./atmos.d import .yaml files from the directory and merge them
base_path: "./"
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
components:
terraform:
base_path: "components/terraform"
apply_auto_approve: false
deploy_run_init: true
init_run_reconfigure: true
auto_generate_backend_file: false

stacks:
base_path: "stacks"
included_paths:
- "deploy/**/*"
excluded_paths:
- "**/_defaults.yaml"
name_pattern: "{stage}"
haitham911 marked this conversation as resolved.
Show resolved Hide resolved

vendor:
# Single file
base_path: "./vendor.yaml"

# Directory with multiple files
#base_path: "./vendor"

# Absolute path
#base_path: "vendor.d/vendor1.yaml"

logs:
file: "/dev/stderr"
level: Info

haitham911 marked this conversation as resolved.
Show resolved Hide resolved
# Custom CLI commands

# No arguments or flags are required
commands:
- name: "test"
description: "Run all tests"
steps:
- atmos vendor pull
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
47 changes: 47 additions & 0 deletions examples/demo-atmos.d/custom-import/atmos.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Description: This is an example of a custom import configuration file.
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
# The import configuration file is used to load configurations from multiple files and directories.
# The configurations are merged together to create a single configuration object.
# The configurations are loaded in the order they are defined in the import section.
base_path: "./"
import:
- "configs.d/**/*" # Recursively load configurations from a directory
- "https://example.com/config.yaml" # Load from a remote URL
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
- "./extra-config.yaml" # Load a specific file
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
components:
terraform:
base_path: "components/terraform"
apply_auto_approve: false
deploy_run_init: true
init_run_reconfigure: true
auto_generate_backend_file: false

haitham911 marked this conversation as resolved.
Show resolved Hide resolved
stacks:
base_path: "stacks"
included_paths:
- "deploy/**/*"
excluded_paths:
- "**/_defaults.yaml"
name_pattern: "{stage}"
haitham911 marked this conversation as resolved.
Show resolved Hide resolved

vendor:
# Single file
base_path: "./vendor.yaml"

# Directory with multiple files
#base_path: "./vendor"

# Absolute path
#base_path: "vendor.d/vendor1.yaml"
haitham911 marked this conversation as resolved.
Show resolved Hide resolved

logs:
file: "/dev/stderr"
level: Info
haitham911 marked this conversation as resolved.
Show resolved Hide resolved

# Custom CLI commands

# No arguments or flags are required
commands:
- name: "test"
description: "Run all tests"
steps:
- atmos vendor pull
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 4 additions & 0 deletions examples/demo-atmos.d/custom-import/configs.d/config1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
logs:
level: Debug
settings:
retries: 3
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
logs:
level: Warning
settings:
timeout: 30s
3 changes: 3 additions & 0 deletions examples/demo-atmos.d/custom-import/extra-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
environment: production
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
logs:
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
file: /var/log/atmos.log
111 changes: 109 additions & 2 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ package config

import (
"bytes"
"context"
"encoding/json"
"fmt"
"os"
"path"
"path/filepath"
"runtime"
"strings"

"github.com/fatih/color"
"github.com/hashicorp/go-getter"
"github.com/mitchellh/go-homedir"
"github.com/pkg/errors"
"github.com/spf13/viper"
Expand Down Expand Up @@ -225,14 +228,45 @@ func InitCliConfig(configAndStacksInfo schema.ConfigAndStacksInfo, processStacks
// https://sagikazarmark.hu/blog/decoding-custom-formats-with-viper/
err = v.Unmarshal(&cliConfig)
if err != nil {
return cliConfig, err
return cliConfig,
err
}

// Process ENV vars
err = processEnvVars(&cliConfig)
if err != nil {
return cliConfig, err
}
// Check if 'import' key exists
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
if len(cliConfig.Import) == 0 {
basePath, err := filepath.Abs(cliConfig.BasePath)
if err != nil {
return cliConfig, err
}
atmosDPath := path.Join(basePath, "atmos.d")
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
// Ensure the joined path doesn't escape the intended directory
if !strings.HasPrefix(atmosDPath, basePath) {
return cliConfig, fmt.Errorf("invalid atmos.d path: attempted directory traversal")
}
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
_, err = os.Stat(atmosDPath)
if err == nil {
cliConfig.Import = []string{"atmos.d/**/*.yaml"}
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
} else if !os.IsNotExist(err) {
return cliConfig, err // Handle unexpected errors
}
}
// Process imports if any
if len(cliConfig.Import) > 0 {
err = processImports(cliConfig, v)
if err != nil {
return cliConfig, err
}

// Re-unmarshal the merged configuration into cliConfig
err = v.Unmarshal(&cliConfig)
if err != nil {
return cliConfig, err
}
}

// Process command-line args
err = processCommandLineArgs(&cliConfig, configAndStacksInfo)
Expand Down Expand Up @@ -370,3 +404,76 @@ func processConfigFile(

return true, nil
}
func processImports(cliConfig schema.CliConfiguration, v *viper.Viper) error {
for _, importPath := range cliConfig.Import {
if importPath == "" {
continue
}

var resolvedPaths []string
var err error

if strings.HasPrefix(importPath, "http://") || strings.HasPrefix(importPath, "https://") {
// Handle remote URLs
tempFile, err := downloadRemoteConfig(importPath)
if err != nil {
u.LogWarning(cliConfig, fmt.Sprintf("Warning: failed to download remote config '%s': %v", importPath, err))
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
continue
}
resolvedPaths = []string{tempFile}
} else {
impWithExt := importPath
ext := filepath.Ext(importPath)
if ext == "" {
ext = ".yaml"
impWithExt = importPath + ext
}
basePath, err := filepath.Abs(cliConfig.BasePath)
if err != nil {
return err
}
imp := path.Join(basePath, impWithExt)
// ensure the joined path doesn't escape the intended directory
if !strings.HasPrefix(imp, basePath) {
return fmt.Errorf("invalid import path: attempted directory traversal")
}
resolvedPaths, err = u.GetGlobMatches(imp)
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
u.LogWarning(cliConfig, fmt.Sprintf("Warning: failed to resolve import path '%s': %v", impWithExt, err))
continue
}
}
// print the resolved paths
u.LogTrace(cliConfig, fmt.Sprintf("Resolved import paths: %v", resolvedPaths))
for _, path := range resolvedPaths {
// Process each configuration file
_, err = processConfigFile(cliConfig, path, v)
if err != nil {
// Log the error but continue processing other files
u.LogWarning(cliConfig, fmt.Sprintf("Warning: failed to merge configuration from '%s': %v", path, err))
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
continue
}
}
}
return nil
}

func downloadRemoteConfig(url string) (string, error) {
tempDir, err := os.MkdirTemp("", "atmos-import-*")
if err != nil {
return "", err
}
tempFile := filepath.Join(tempDir, "config.yaml")
haitham911 marked this conversation as resolved.
Show resolved Hide resolved

client := &getter.Client{
Ctx: context.Background(),
Src: url,
Dst: tempFile,
Mode: getter.ClientModeFile,
}
err = client.Get()
if err != nil {
return "", fmt.Errorf("failed to download remote config: %w", err)
}
return tempFile, nil
}
haitham911 marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions pkg/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type CliConfiguration struct {
StackConfigFilesAbsolutePaths []string `yaml:"stackConfigFilesAbsolutePaths,omitempty" json:"stackConfigFilesAbsolutePaths,omitempty" mapstructure:"stackConfigFilesAbsolutePaths"`
StackType string `yaml:"stackType,omitempty" json:"StackType,omitempty" mapstructure:"stackType"`
Default bool `yaml:"default" json:"default" mapstructure:"default"`
Import []string `yaml:"import" json:"import" mapstructure:"import"`
}

type CliSettings struct {
Expand Down
3 changes: 3 additions & 0 deletions pkg/utils/glob_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"path"
"sort"
"strings"
"sync"

Expand Down Expand Up @@ -38,6 +39,8 @@ func GetGlobMatches(pattern string) ([]string, error) {
for _, match := range matches {
fullMatches = append(fullMatches, path.Join(base, match))
}
// Sort matches lexicographically
sort.Strings(fullMatches)

getGlobMatchesSyncMap.Store(pattern, strings.Join(fullMatches, ","))

Expand Down