-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Closed
Description
we build a binary with Cobra, the primary function is to collect input and send all arguments to a restful server, this server will call other functions to create a K8S cluster.
when we do it, there are a lot of arguments, and we need to enhance and change them more regularly, so, if there is a way to add flags dynamically, it will be beneficial for us.
I have written some code to implement this feature, but I am not familiar with Go lang and Corba, I'm not sure we are on the right way, if there is a more good way, please help me figure it out.
API parts, which return dynamic data.
@ns.route('/custom-api')
class CustomAPI(Resource):
def get(self):
flags_list = {
"cert": {
"type": "string",
"des": "add self-signed certs for private registries. Format: registry-name1:/path/to/cert-file1,registry-name2:/path/to/cert-file2,...",
"default": ""
},
"csf-grocery": {
"type": "bool",
"des": "set up CSF Grocery",
"default": True
}
}
return json_success(flags_list)parse API result to flag
package utils
import (
"fmt"
"os"
resty "github.com/go-resty/resty/v2"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tidwall/gjson"
)
// return data map
var customizedMap = make(map[string]interface{})
func ParseCutomizedFlags(url string, cmd *cobra.Command, args []string) map[string]interface{} {
if len(args) == 0 {
cmd.Help()
fmt.Println()
os.Exit(0)
}
fullURL := viper.GetString("datacenter-server-api") + url
var customizedData gjson.Result
client := resty.New()
resp, err := client.R().ForceContentType("application/json").EnableTrace().Get(fullURL)
if err == nil {
if gjson.Get(resp.String(), "status").String() == "OK" {
customizedData = gjson.Get(resp.String(), "data")
}
} else {
fmt.Println(err.Error())
}
if len(customizedData.Map()) > 0 {
for key_name, valueMap := range customizedData.Map() {
value_type := valueMap.Get("type").String()
if value_type == "string" {
cmd.Flags().String(string(key_name), valueMap.Map()["default"].String(), valueMap.Map()["des"].String())
} else if value_type == "bool" {
cmd.Flags().Bool(string(key_name), valueMap.Map()["default"].Bool(), valueMap.Map()["des"].String())
}
}
}
// set flag back
cmd.DisableFlagParsing = false
// parse flag manually
err = cmd.ParseFlags(args)
// if get error, print error and help info
if err != nil {
fmt.Println(err)
cmd.Help()
fmt.Println()
os.Exit(0)
}
if cmd.Flag("help").Value.String() == "true" {
cmd.Help()
fmt.Println()
os.Exit(0)
}
// put all data into map which have no changed.
if len(customizedData.Array()) > 0 {
for key_name := range customizedData.Map() {
if cmd.Flag(key_name).Value.String() != cmd.Flag(key_name).DefValue {
customizedMap[key_name] = cmd.Flag(key_name).Value
}
}
}
return customizedMap
}commands parts
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"nuke.csf.nokia.net/nuke-cli/utils"
)
var DemoClusterCreate = &cobra.Command{
Use: "demo [string to print]",
Short: "demo anything to the screen",
Long: `demo is for printing anything back to the screen. For many years people have printed back to the screen.`,
RunE: createDemoCluster,
DisableFlagParsing: true,
}
func createDemoCluster(cmd *cobra.Command, args []string) error {
// call function to get all flags data
var customizedMap = utils.ParseCutomizedFlags("/api/v1/demo/custom-api", cmd, args)
for va := range customizedMap {
fmt.Println(va)
fmt.Println(customizedMap[va])
}
return nil
}CLI result
PS D:\CLI> go run nuke.go create cluster demo --cert xxxx --csf-grocery=false
cert
xxxx
csf-grocery
false
PS D:\CLI> go run nuke.go create cluster demo --cert xxxx --csf-grocery=false --zz=0
unknown flag: --zz
Usage:
nuke create cluster demo [string to print] [flags]
Flags:
--cert string add self-signed certs for private registries. Format: registry-name1:/path/to/cert-file1,registry-name2:/path/to/cert-file2,...
--csf-grocery set up CSF Grocery (default true)
-h, --help help for demo
Global Flags:
--datacenter-server-api string data center server api (default "http://127.0.0.1:5678")
--log string nuke log level [debug, info] (default "info")
-o, --output string result output format. [json, yaml, file] (default "json")
--output-folder string when output type if file, all result files will be save to this folder. (default "./output/")
--wrap-processbar if need to wrap process bar when running a long task (default true)
PS D:\CLI> go run nuke.go create cluster demo --help
demo is for printing anything back to the screen. For many years people have printed back to the screen.
Usage:
nuke create cluster demo [string to print] [flags]
Flags:
--cert string add self-signed certs for private registries. Format: registry-name1:/path/to/cert-file1,registry-name2:/path/to/cert-file2,...
--csf-grocery set up CSF Grocery (default true)
-h, --help help for demo
Global Flags:
--datacenter-server-api string data center server api (default "http://127.0.0.1:5678")
--log string nuke log level [debug, info] (default "info")
-o, --output string result output format. [json, yaml, file] (default "json")
--output-folder string when output type if file, all result files will be save to this folder. (default "./output/")Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels