-
Notifications
You must be signed in to change notification settings - Fork 128
/
root.go
167 lines (145 loc) · 4.72 KB
/
root.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package cmd
import (
"fmt"
"net/url"
"os"
"strings"
"sync"
"github.com/fatih/color"
"github.com/hbagdi/deck/utils"
homedir "github.com/mitchellh/go-homedir"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var (
cfgFile string
config utils.KongClientConfig
verbose int
noColor bool
)
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "deck",
Short: "Administer your Kong declaratively",
Long: `decK helps you manage Kong clusters with a declarative
configuration file.
It can be used to export, import or sync entities to Kong.`,
SilenceUsage: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if _, err := url.ParseRequestURI(config.Address); err != nil {
return errors.WithStack(errors.Wrap(err, "invalid URL"))
}
if noColor {
color.NoColor = true
}
return nil
},
}
// Execute adds all child commands to the root command and sets
// sflags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
var wg sync.WaitGroup
var err error
const threads = 2
wg.Add(threads)
go func() {
sendAnalytics()
wg.Done()
}()
go func() {
err = rootCmd.Execute()
wg.Done()
}()
wg.Wait()
if err != nil {
os.Exit(1)
}
}
//nolint:errcheck
func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "",
"config file (default is $HOME/.deck.yaml)")
rootCmd.PersistentFlags().String("kong-addr", "http://localhost:8001",
"HTTP Address of Kong's Admin API.\n"+
"This value can also be set using DECK_KONG_ADDR\n"+
" environment variable.")
viper.BindPFlag("kong-addr",
rootCmd.PersistentFlags().Lookup("kong-addr"))
rootCmd.PersistentFlags().StringSlice("headers", []string{},
"HTTP Headers(key:value) to inject in all requests to Kong's Admin API.\n"+
"This flag can be specified multiple times to inject multiple headers.")
viper.BindPFlag("headers",
rootCmd.PersistentFlags().Lookup("headers"))
rootCmd.PersistentFlags().Bool("tls-skip-verify", false,
"Disable verification of Kong's Admin TLS certificate.\n"+
"This value can also be set using DECK_TLS_SKIP_VERIFY "+
"environment variable.")
viper.BindPFlag("tls-skip-verify",
rootCmd.PersistentFlags().Lookup("tls-skip-verify"))
rootCmd.PersistentFlags().String("tls-server-name", "",
"Name to use to verify the hostname in "+
"Kong's Admin TLS certificate.\n"+
"This value can also be set using DECK_TLS_SERVER_NAME"+
" environment variable.")
viper.BindPFlag("tls-server-name",
rootCmd.PersistentFlags().Lookup("tls-server-name"))
rootCmd.PersistentFlags().String("ca-cert", "",
"Custom CA certificate to use to verify "+
"Kong's Admin TLS certificate.\n"+
"This value can also be set using DECK_CA_CERT"+
" environment variable.")
viper.BindPFlag("ca-cert",
rootCmd.PersistentFlags().Lookup("ca-cert"))
rootCmd.PersistentFlags().Int("verbose", 0,
"Enable verbose verbose logging levels\n"+
"Setting this value to 2 outputs all HTTP requests/responses\n"+
"between decK and Kong.")
viper.BindPFlag("verbose",
rootCmd.PersistentFlags().Lookup("verbose"))
rootCmd.PersistentFlags().Bool("no-color", false,
"disable colorized output")
viper.BindPFlag("no-color",
rootCmd.PersistentFlags().Lookup("no-color"))
rootCmd.PersistentFlags().Bool("skip-workspace-crud", false,
"Skip API calls related to Workspaces (Kong Enterprise only)")
viper.BindPFlag("skip-workspace-crud",
rootCmd.PersistentFlags().Lookup("skip-workspace-crud"))
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Search config in home directory with name ".deck"(without extension).
viper.AddConfigPath(home)
viper.SetConfigName(".deck")
}
viper.SetEnvPrefix("deck")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
fmt.Println(err)
}
}
config.Address = viper.GetString("kong-addr")
config.TLSServerName = viper.GetString("tls-server-name")
config.TLSSkipVerify = viper.GetBool("tls-skip-verify")
config.TLSCACert = viper.GetString("ca-cert")
config.Headers = viper.GetStringSlice("headers")
verbose = viper.GetInt("verbose")
noColor = viper.GetBool("no-color")
config.SkipWorkspaceCrud = viper.GetBool("skip-workspace-crud")
config.Debug = verbose >= 1
}