Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`) |
Comment on lines +88 to +96

`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
Expand Down
16 changes: 9 additions & 7 deletions cmd/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Comment on lines +73 to +74

CLI flags take precedence over their environment variables.

Default commands:
%s
Expand Down
29 changes: 29 additions & 0 deletions cmk.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"flag"
"fmt"
"os"
"strconv"
"strings"

"github.com/apache/cloudstack-cloudmonkey/cli"
Expand Down Expand Up @@ -53,6 +54,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)
}
Comment thread
vishesh92 marked this conversation as resolved.
if !*debug {
Comment on lines 55 to +79
if value, err := strconv.ParseBool(strings.TrimSpace(os.Getenv(config.DebugEnvVar))); err == nil && value {
*debug = true
}
}
Comment thread
vishesh92 marked this conversation as resolved.
Comment on lines +79 to +83

cfg := config.NewConfig(configFilePath)

if *showVersion {
Expand Down
21 changes: 20 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down Expand Up @@ -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)
}
}
Expand Down
Loading