Skip to content

Commit 306f2a4

Browse files
committed
Add support to pass env vars to in addition to args to configure cmk
1 parent df41d70 commit 306f2a4

4 files changed

Lines changed: 77 additions & 8 deletions

File tree

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,27 @@ If cloudmonkey is being upgraded from a version lower than v6.0.0, it must be no
7979
that the cloudmonkey configuration path is changed from `~/.cloudmonkey/config` to
8080
`~/.cmk/config` and a default `localcloud` profile is created. One must first set up basic configurations such as apikey/secretkey/username/password/url for the required profile(s) as required
8181

82+
### Environment Variables
83+
84+
`cmk` supports environment variables that mirror its CLI flags. CLI flags take
85+
precedence over environment variables, which take precedence over values in the
86+
config file.
87+
88+
| Environment variable | Flag | Description |
89+
|----------------------|------|-------------|
90+
| `CMK_CONFIG` | `-c` | Config file path |
91+
| `CMK_PROFILE` | `-p` | Server profile |
92+
| `CMK_URL` | `-u` | CloudStack's API endpoint URL |
93+
| `CMK_API_KEY` | `-k` | CloudStack user's API key |
94+
| `CMK_SECRET_KEY` | `-s` | CloudStack user's secret key |
95+
| `CMK_OUTPUT` | `-o` | API response output format |
96+
| `CMK_DEBUG` | `-d` | Enable debug mode when set to `true` or `1` |
97+
98+
`CMK_CONFIG` must point to an existing config file, and `CMK_PROFILE` must name
99+
an existing profile in the config; otherwise `cmk` exits with an error. A profile
100+
selected via `CMK_PROFILE` applies only to that invocation and is not persisted
101+
to the config file.
102+
82103
### License
83104

84105
Licensed to the Apache Software Foundation (ASF) under one

cmd/command.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,15 @@ CloudMonkey (cmk) 🐵 is a command line interface for Apache CloudStack.
6565
Allowed flags:
6666
-h Show this help message or API doc when specified after an API
6767
-v Print version
68-
-o API response output format: json, text, table, column, csv
69-
-p Server profile
70-
-d Enable debug mode
71-
-c Different config file path
72-
-u CloudStack's API endpoint URL
73-
-s CloudStack user's secret Key
74-
-k CloudStack user's API Key
68+
-o API response output format: json, text, table, column, csv (env: CMK_OUTPUT)
69+
-p Server profile (env: CMK_PROFILE)
70+
-d Enable debug mode (env: CMK_DEBUG)
71+
-c Different config file path (env: CMK_CONFIG)
72+
-u CloudStack's API endpoint URL (env: CMK_URL)
73+
-s CloudStack user's secret Key (env: CMK_SECRET_KEY)
74+
-k CloudStack user's API Key (env: CMK_API_KEY)
75+
76+
CLI flags take precedence over their environment variables.
7577
7678
Default commands:
7779
%s

cmk.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,34 @@ func main() {
5353
flag.Parse()
5454
args := flag.Args()
5555

56+
// Fall back to environment variables for flags not passed on the
57+
// command line; CLI flags take precedence over environment variables.
58+
if *configFilePath == "" {
59+
*configFilePath = os.Getenv(config.ConfigFileEnvVar)
60+
}
61+
if *profile == "" {
62+
*profile = os.Getenv(config.ProfileEnvVar)
63+
}
64+
if *acsURL == config.DefaultACSAPIEndpoint {
65+
if value := os.Getenv(config.URLEnvVar); value != "" {
66+
*acsURL = value
67+
}
68+
}
69+
if *apiKey == "" {
70+
*apiKey = os.Getenv(config.APIKeyEnvVar)
71+
}
72+
if *secretKey == "" {
73+
*secretKey = os.Getenv(config.SecretKeyEnvVar)
74+
}
75+
if *outputFormat == "" {
76+
*outputFormat = os.Getenv(config.OutputEnvVar)
77+
}
78+
if !*debug {
79+
if value := os.Getenv(config.DebugEnvVar); value == "true" || value == "1" {
80+
*debug = true
81+
}
82+
}
83+
5684
cfg := config.NewConfig(configFilePath)
5785

5886
if *showVersion {

config/config.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,24 @@ var nonEmptyConfigKeys = map[string]bool{
5656
// DefaultACSAPIEndpoint is the default API endpoint for CloudStack.
5757
const DefaultACSAPIEndpoint = "http://localhost:8080/client/api"
5858

59+
// Environment variables that mirror CLI flags; flags take precedence.
60+
const (
61+
// ConfigFileEnvVar sets the config file path when -c is not passed
62+
ConfigFileEnvVar = "CMK_CONFIG"
63+
// ProfileEnvVar sets the server profile when -p is not passed
64+
ProfileEnvVar = "CMK_PROFILE"
65+
// URLEnvVar sets CloudStack's API endpoint URL when -u is not passed
66+
URLEnvVar = "CMK_URL"
67+
// APIKeyEnvVar sets CloudStack user's API key when -k is not passed
68+
APIKeyEnvVar = "CMK_API_KEY"
69+
// SecretKeyEnvVar sets CloudStack user's secret key when -s is not passed
70+
SecretKeyEnvVar = "CMK_SECRET_KEY"
71+
// OutputEnvVar sets the API response output format when -o is not passed
72+
OutputEnvVar = "CMK_OUTPUT"
73+
// DebugEnvVar enables debug mode when set to true or 1 and -d is not passed
74+
DebugEnvVar = "CMK_DEBUG"
75+
)
76+
5977
// ServerProfile describes a management server
6078
type ServerProfile struct {
6179
URL string `ini:"url"`
@@ -435,7 +453,7 @@ func NewConfig(configFilePath *string) *Config {
435453
if *configFilePath != "" {
436454
defaultConf.ConfigFile, _ = filepath.Abs(*configFilePath)
437455
if _, err := os.Stat(defaultConf.ConfigFile); os.IsNotExist(err) {
438-
fmt.Println("Config file doesn't exist.")
456+
fmt.Printf("Config file '%s' doesn't exist.\n", defaultConf.ConfigFile)
439457
os.Exit(1)
440458
}
441459
}

0 commit comments

Comments
 (0)