Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
hashmap-kz committed Jan 2, 2025
2 parents 0281a6e + 0238af7 commit eaafcb8
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 10 deletions.
62 changes: 52 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,58 @@ kubectl envsubst apply -f manifests/ \

## **Flags**:

```
--envsubst-allowed-vars=HOME,USER,PKEY_PATH,DB_PASS,IMAGE_NAME,IMAGE_TAG
Accepts a comma-separated list of variable names allowed for substitution.
Variables not included in this list will not be substituted.
--envsubst-allowed-prefixes=APP_,CI_
Accepts a comma-separated list of prefixes.
Only variables with names starting with one of these prefixes will be substituted; others will be ignored.
```
### **1. Using Command-Line Flags**

#### `--envsubst-allowed-vars`

- **Description**: Specifies a comma-separated list of variable names that are explicitly allowed for substitution.
- **Usage**:
```bash
--envsubst-allowed-vars=HOME,USER,PKEY_PATH,DB_PASS,IMAGE_NAME,IMAGE_TAG
```
- **Behavior**:
- Variables not included in this list will not be substituted.
- Useful for ensuring only specific variables are processed, preventing accidental substitutions.

#### `--envsubst-allowed-prefixes`

- **Description**: Specifies a comma-separated list of prefixes to filter variables by name.
- **Usage**:
```bash
--envsubst-allowed-prefixes=APP_,CI_
```
- **Behavior**:
- Only variables with names starting with one of the specified prefixes will be substituted.
- Variables without matching prefixes will be ignored.

---

### **2. Using Environment Variables**

#### `ENVSUBST_ALLOWED_VARS`

- **Description**: Alternative way to define a list of allowed variables for substitution.
- **Usage**:
```bash
export ENVSUBST_ALLOWED_VARS='HOST,USER,PKEY_PATH'
```

#### `ENVSUBST_ALLOWED_PREFIXES`

- **Description**: Alternative way to define a list of allowed prefixes for variable substitution.
- **Usage**:
```bash
export ENVSUBST_ALLOWED_PREFIXES='CI_,APP_'
```

---

### **NOTE: CLI Takes Precedence Over Environment Variables**

- **Priority**: If both CLI flags and environment variables are set:
- **CLI flags** (`--envsubst-allowed-vars`, `--envsubst-allowed-prefixes`) will **override** their respective
environment variable values.
- This ensures explicit command-line options have the highest priority.

---

Expand Down
27 changes: 27 additions & 0 deletions pkg/cmd/rawargs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import (
"strings"
)

const (
envsubstAllowedVarsEnv = "ENVSUBST_ALLOWED_VARS"
envsubstAllowedPrefixesEnv = "ENVSUBST_ALLOWED_PREFIXES"
)

type CmdArgsRawRecognized struct {
Filenames []string
EnvsubstAllowedVars []string
Expand Down Expand Up @@ -119,5 +124,27 @@ func parseArgs() (CmdArgsRawRecognized, error) {
}
}

// trying to get allowed-vars config from envs
if len(result.EnvsubstAllowedVars) == 0 {
if value, exists := os.LookupEnv(envsubstAllowedVarsEnv); exists {
split := strings.Split(value, ",")
if allEmpty(split) {
return result, fmt.Errorf("missing value for env: %s", envsubstAllowedVarsEnv)
}
result.EnvsubstAllowedVars = split
}
}

// trying to get allowed-prefixes from envs
if len(result.EnvsubstAllowedPrefix) == 0 {
if value, exists := os.LookupEnv(envsubstAllowedPrefixesEnv); exists {
split := strings.Split(value, ",")
if allEmpty(split) {
return result, fmt.Errorf("missing value for env: %s", envsubstAllowedPrefixesEnv)
}
result.EnvsubstAllowedPrefix = split
}
}

return result, nil
}
100 changes: 100 additions & 0 deletions pkg/cmd/rawargs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"os"
"reflect"
"strings"
"testing"
)

Expand Down Expand Up @@ -196,3 +197,102 @@ func TestParseArgs(t *testing.T) {
})
}
}

func TestParseArgs_EnvFallback(t *testing.T) {
os.Setenv("ENVSUBST_ALLOWED_VARS", "HOME,USER")
os.Setenv("ENVSUBST_ALLOWED_PREFIXES", "APP_,CI_")
defer os.Unsetenv("ENVSUBST_ALLOWED_VARS")
defer os.Unsetenv("ENVSUBST_ALLOWED_PREFIXES")

os.Args = []string{"cmd"}
result, err := parseArgs()

if err != nil {
t.Fatalf("Unexpected error: %v", err)
}

expectedVars := []string{"HOME", "USER"}
expectedPrefixes := []string{"APP_", "CI_"}
if len(result.EnvsubstAllowedVars) != len(expectedVars) {
t.Errorf("Expected allowed vars %v, got %v", expectedVars, result.EnvsubstAllowedVars)
}
for i, varName := range expectedVars {
if result.EnvsubstAllowedVars[i] != varName {
t.Errorf("Expected allowed var %s, got %s", varName, result.EnvsubstAllowedVars[i])
}
}
if len(result.EnvsubstAllowedPrefix) != len(expectedPrefixes) {
t.Errorf("Expected allowed prefixes %v, got %v", expectedPrefixes, result.EnvsubstAllowedPrefix)
}
for i, prefix := range expectedPrefixes {
if result.EnvsubstAllowedPrefix[i] != prefix {
t.Errorf("Expected allowed prefix %s, got %s", prefix, result.EnvsubstAllowedPrefix[i])
}
}
}

func TestParseArgs_CmdAndEnvFlags(t *testing.T) {
// Set environment variables
os.Setenv("ENVSUBST_ALLOWED_VARS", "HOME,USER")
os.Setenv("ENVSUBST_ALLOWED_PREFIXES", "APP_,CI_")
defer os.Unsetenv("ENVSUBST_ALLOWED_VARS")
defer os.Unsetenv("ENVSUBST_ALLOWED_PREFIXES")

// Set command-line arguments
os.Args = []string{
"cmd",
"--envsubst-allowed-vars=CMD_VAR1,CMD_VAR2",
"--envsubst-allowed-prefixes=CMD_",
}

result, err := parseArgs()

if err != nil {
t.Fatalf("Unexpected error: %v", err)
}

// Verify that command-line flags take precedence over environment variables
expectedVars := []string{"CMD_VAR1", "CMD_VAR2"}
expectedPrefixes := []string{"CMD_"}

if len(result.EnvsubstAllowedVars) != len(expectedVars) {
t.Errorf("Expected allowed vars %v, got %v", expectedVars, result.EnvsubstAllowedVars)
}
for i, varName := range expectedVars {
if result.EnvsubstAllowedVars[i] != varName {
t.Errorf("Expected allowed var %s, got %s", varName, result.EnvsubstAllowedVars[i])
}
}

if len(result.EnvsubstAllowedPrefix) != len(expectedPrefixes) {
t.Errorf("Expected allowed prefixes %v, got %v", expectedPrefixes, result.EnvsubstAllowedPrefix)
}
for i, prefix := range expectedPrefixes {
if result.EnvsubstAllowedPrefix[i] != prefix {
t.Errorf("Expected allowed prefix %s, got %s", prefix, result.EnvsubstAllowedPrefix[i])
}
}
}

func TestParseArgs_EmptyEnvVars(t *testing.T) {
// Set empty environment variables
os.Setenv("ENVSUBST_ALLOWED_VARS", "")
os.Setenv("ENVSUBST_ALLOWED_PREFIXES", "")
defer os.Unsetenv("ENVSUBST_ALLOWED_VARS")
defer os.Unsetenv("ENVSUBST_ALLOWED_PREFIXES")

os.Args = []string{"cmd"}
_, err := parseArgs()

// Expect an error due to empty environment variables
if err == nil {
t.Fatal("Expected an error for empty environment variables, but got none")
}

expectedErrorVars := "missing value for env: ENVSUBST_ALLOWED_VARS"
expectedErrorPrefixes := "missing value for env: ENVSUBST_ALLOWED_PREFIXES"

if !strings.Contains(err.Error(), expectedErrorVars) && !strings.Contains(err.Error(), expectedErrorPrefixes) {
t.Errorf("Expected error to mention missing values for ENVSUBST_ALLOWED_VARS or ENVSUBST_ALLOWED_PREFIXES, got '%s'", err.Error())
}
}
File renamed without changes.
15 changes: 15 additions & 0 deletions testdata/subst/basic-example/apply-env-args.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail

# include env-vars
. vars.sh

# prepare namespace and context
kubectl create ns "${APP_NAMESPACE}" --dry-run=client -oyaml | kubectl apply -f -
kubectl config set-context --current --namespace="${APP_NAMESPACE}"

# configure CLI
export ENVSUBST_ALLOWED_PREFIXES='CI_,APP_,INFRA_'

# expand and apply manifests
kubectl envsubst apply -f manifests/

0 comments on commit eaafcb8

Please sign in to comment.