This is an automated email from the ASF dual-hosted git repository. vishesh92 pushed a commit to branch add-env-vars-support in repository https://gitbox.apache.org/repos/asf/cloudstack-cloudmonkey.git
commit c05eaa57abac8eb9068b34025801a83d62aa2b26 Author: vishesh92 <[email protected]> AuthorDate: Tue Sep 1 13:29:20 2026 +0530 Add support env vars to pass in addition to args --- README.md | 21 +++++++++++++++++++++ cmd/command.go | 16 +++++++++------- cmk.go | 28 ++++++++++++++++++++++++++++ config/config.go | 20 +++++++++++++++++++- 4 files changed, 77 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 66f4dc6..4c3edc9 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,27 @@ If cloudmonkey is being upgraded from a version lower than v6.0.0, it must be no that the cloudmonkey configuration path is changed from `~/.cloudmonkey/config` to `~/.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 +### Environment Variables + +`cmk` supports environment variables that mirror its CLI flags. CLI flags take +precedence over environment variables, which take precedence over values in the +config file. + +| Environment variable | Flag | Description | +|----------------------|------|-------------| +| `CMK_CONFIG` | `-c` | Config file path | +| `CMK_PROFILE` | `-p` | Server profile | +| `CMK_URL` | `-u` | CloudStack's API endpoint URL | +| `CMK_API_KEY` | `-k` | CloudStack user's API key | +| `CMK_SECRET_KEY` | `-s` | CloudStack user's secret key | +| `CMK_OUTPUT` | `-o` | API response output format | +| `CMK_DEBUG` | `-d` | Enable debug mode when set to `true` or `1` | + +`CMK_CONFIG` must point to an existing config file, and `CMK_PROFILE` must name +an existing profile in the config; otherwise `cmk` exits with an error. A profile +selected via `CMK_PROFILE` applies only to that invocation and is not persisted +to the config file. + ### License Licensed to the Apache Software Foundation (ASF) under one diff --git a/cmd/command.go b/cmd/command.go index 1928755..b0ffaef 100644 --- a/cmd/command.go +++ b/cmd/command.go @@ -65,13 +65,15 @@ CloudMonkey (cmk) 🐵 is a command line interface for Apache CloudStack. Allowed flags: -h Show this help message or API doc when specified after an API -v Print version - -o API response output format: json, text, table, column, csv - -p Server profile - -d Enable debug mode - -c Different config file path - -u CloudStack's API endpoint URL - -s CloudStack user's secret Key - -k CloudStack user's API Key + -o API response output format: json, text, table, column, csv (env: CMK_OUTPUT) + -p Server profile (env: CMK_PROFILE) + -d Enable debug mode (env: CMK_DEBUG) + -c Different config file path (env: CMK_CONFIG) + -u CloudStack's API endpoint URL (env: CMK_URL) + -s CloudStack user's secret Key (env: CMK_SECRET_KEY) + -k CloudStack user's API Key (env: CMK_API_KEY) + +CLI flags take precedence over their environment variables. Default commands: %s diff --git a/cmk.go b/cmk.go index 9ba8073..03b97b0 100644 --- a/cmk.go +++ b/cmk.go @@ -53,6 +53,34 @@ func main() { flag.Parse() args := flag.Args() + // Fall back to environment variables for flags not passed on the + // command line; CLI flags take precedence over environment variables. + if *configFilePath == "" { + *configFilePath = os.Getenv(config.ConfigFileEnvVar) + } + if *profile == "" { + *profile = os.Getenv(config.ProfileEnvVar) + } + if *acsURL == config.DefaultACSAPIEndpoint { + if value := os.Getenv(config.URLEnvVar); value != "" { + *acsURL = value + } + } + if *apiKey == "" { + *apiKey = os.Getenv(config.APIKeyEnvVar) + } + if *secretKey == "" { + *secretKey = os.Getenv(config.SecretKeyEnvVar) + } + if *outputFormat == "" { + *outputFormat = os.Getenv(config.OutputEnvVar) + } + if !*debug { + if value := os.Getenv(config.DebugEnvVar); value == "true" || value == "1" { + *debug = true + } + } + cfg := config.NewConfig(configFilePath) if *showVersion { diff --git a/config/config.go b/config/config.go index 1fb06d8..8fd216f 100644 --- a/config/config.go +++ b/config/config.go @@ -56,6 +56,24 @@ var nonEmptyConfigKeys = map[string]bool{ // DefaultACSAPIEndpoint is the default API endpoint for CloudStack. const DefaultACSAPIEndpoint = "http://localhost:8080/client/api" +// Environment variables that mirror CLI flags; flags take precedence. +const ( + // ConfigFileEnvVar sets the config file path when -c is not passed + ConfigFileEnvVar = "CMK_CONFIG" + // ProfileEnvVar sets the server profile when -p is not passed + ProfileEnvVar = "CMK_PROFILE" + // URLEnvVar sets CloudStack's API endpoint URL when -u is not passed + URLEnvVar = "CMK_URL" + // APIKeyEnvVar sets CloudStack user's API key when -k is not passed + APIKeyEnvVar = "CMK_API_KEY" + // SecretKeyEnvVar sets CloudStack user's secret key when -s is not passed + SecretKeyEnvVar = "CMK_SECRET_KEY" + // OutputEnvVar sets the API response output format when -o is not passed + OutputEnvVar = "CMK_OUTPUT" + // DebugEnvVar enables debug mode when set to true or 1 and -d is not passed + DebugEnvVar = "CMK_DEBUG" +) + // ServerProfile describes a management server type ServerProfile struct { URL string `ini:"url"` @@ -435,7 +453,7 @@ func NewConfig(configFilePath *string) *Config { if *configFilePath != "" { defaultConf.ConfigFile, _ = filepath.Abs(*configFilePath) if _, err := os.Stat(defaultConf.ConfigFile); os.IsNotExist(err) { - fmt.Println("Config file doesn't exist.") + fmt.Printf("Config file '%s' doesn't exist.\n", defaultConf.ConfigFile) os.Exit(1) } }
