This is an automated email from the ASF dual-hosted git repository.
borisstoyanov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack-cloudmonkey.git
The following commit(s) were added to refs/heads/main by this push:
new 9f4cecf Add support to pass env vars to in addition to args to
configure cmk (#220)
9f4cecf is described below
commit 9f4cecf73204a04d67f8624a426f8c7f81f6564a
Author: Vishesh <[email protected]>
AuthorDate: Tue Sep 8 13:48:16 2026 +0530
Add support to pass env vars to in addition to args to configure cmk (#220)
---
README.md | 21 +++++++++++++++++++++
cmd/command.go | 16 +++++++++-------
cmk.go | 30 ++++++++++++++++++++++++++++--
config/config.go | 21 ++++++++++++++++++++-
4 files changed, 78 insertions(+), 10 deletions(-)
diff --git a/README.md b/README.md
index 66f4dc6..7f101b6 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 a boolean true value
(e.g. `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..d9842c1 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..2869d89 100644
--- a/cmk.go
+++ b/cmk.go
@@ -21,6 +21,7 @@ import (
"flag"
"fmt"
"os"
+ "strconv"
"strings"
"github.com/apache/cloudstack-cloudmonkey/cli"
@@ -48,11 +49,36 @@ func main() {
profile := flag.String("p", "", "server profile")
configFilePath := flag.String("c", "", "config file path")
acsURL := flag.String("u", config.DefaultACSAPIEndpoint, "cloudStack's
API endpoint URL")
- apiKey := flag.String("k", "", "cloudStack user's API Key")
- secretKey := flag.String("s", "", "cloudStack user's secret Key")
+ apiKey := flag.String("k", "", "cloudStack user's API key")
+ secretKey := flag.String("s", "", "cloudStack user's secret key")
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.
+ passedFlags := make(map[string]bool)
+ flag.Visit(func(f *flag.Flag) {
+ passedFlags[f.Name] = true
+ })
+ fallbackToEnvVar := func(flagName string, flagValue *string, envVar
string) {
+ if !passedFlags[flagName] {
+ if value := os.Getenv(envVar); value != "" {
+ *flagValue = value
+ }
+ }
+ }
+ fallbackToEnvVar("c", configFilePath, config.ConfigFileEnvVar)
+ fallbackToEnvVar("p", profile, config.ProfileEnvVar)
+ fallbackToEnvVar("u", acsURL, config.URLEnvVar)
+ fallbackToEnvVar("k", apiKey, config.APIKeyEnvVar)
+ fallbackToEnvVar("s", secretKey, config.SecretKeyEnvVar)
+ fallbackToEnvVar("o", outputFormat, config.OutputEnvVar)
+ if !passedFlags["d"] {
+ if value, err :=
strconv.ParseBool(strings.TrimSpace(os.Getenv(config.DebugEnvVar))); err == nil
{
+ *debug = value
+ }
+ }
+
cfg := config.NewConfig(configFilePath)
if *showVersion {
diff --git a/config/config.go b/config/config.go
index 1fb06d8..02b50f0 100644
--- a/config/config.go
+++ b/config/config.go
@@ -56,6 +56,25 @@ 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 a boolean true value
+ // (e.g. 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 +454,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)
}
}