@@ -70,22 +70,26 @@ type parsedToken struct {
7070 tokenType string
7171}
7272
73+ // Environment variable prefix for vipers
74+ const envPrefix = "CHAINLOOP"
75+
7376func NewRootCmd (l zerolog.Logger ) * cobra.Command {
7477 rootCmd := & cobra.Command {
7578 Use : appName ,
7679 Short : "Chainloop Command Line Interface" ,
7780 SilenceErrors : true ,
7881 SilenceUsage : true ,
7982 PersistentPreRunE : func (cmd * cobra.Command , args []string ) error {
80- logger .Debug ().Str ("path" , viper .ConfigFileUsed ()).Msg ("using config file" )
81-
8283 var err error
8384 logger , err = initLogger (l )
8485 if err != nil {
8586 return err
8687 }
8788
88- if flagInsecure {
89+ logger .Debug ().Str ("path" , viper .ConfigFileUsed ()).Msg ("using config file" )
90+
91+ insecure := viper .GetBool (confOptions .insecure .viperKey )
92+ if insecure {
8993 logger .Warn ().Msg ("API contacted in insecure mode" )
9094 }
9195
@@ -95,14 +99,15 @@ func NewRootCmd(l zerolog.Logger) *cobra.Command {
9599 }
96100
97101 var opts = []grpcconn.Option {
98- grpcconn .WithInsecure (flagInsecure ),
102+ grpcconn .WithInsecure (insecure ),
99103 }
100104
101105 if caFilePath := viper .GetString (confOptions .controlplaneCA .viperKey ); caFilePath != "" {
102106 opts = append (opts , grpcconn .WithCAFile (caFilePath ))
103107 }
104108
105- conn , err := grpcconn .New (viper .GetString (confOptions .controlplaneAPI .viperKey ), apiToken , opts ... )
109+ controlplaneURL := viper .GetString (confOptions .controlplaneAPI .viperKey )
110+ conn , err := grpcconn .New (controlplaneURL , apiToken , opts ... )
106111 if err != nil {
107112 return err
108113 }
@@ -158,25 +163,28 @@ func NewRootCmd(l zerolog.Logger) *cobra.Command {
158163
159164 rootCmd .PersistentFlags ().StringVarP (& flagCfgFile , "config" , "c" , "" , "Path to an existing config file (default is $HOME/.config/chainloop/config.toml)" )
160165
161- rootCmd .PersistentFlags ().String (confOptions .controlplaneAPI .flagName , defaultCPAPI , "URL for the Control Plane API" )
162- err := viper .BindPFlag (confOptions .controlplaneAPI .viperKey , rootCmd .PersistentFlags ().Lookup (confOptions .controlplaneAPI .flagName ))
163- cobra .CheckErr (err )
166+ rootCmd .PersistentFlags ().String (confOptions .controlplaneAPI .flagName , defaultCPAPI , fmt . Sprintf ( "URL for the Control Plane API ($%s)" , calculateEnvVarName ( confOptions . controlplaneAPI . viperKey )) )
167+ cobra . CheckErr ( viper .BindPFlag (confOptions .controlplaneAPI .viperKey , rootCmd .PersistentFlags ().Lookup (confOptions .controlplaneAPI .flagName ) ))
168+ cobra .CheckErr (viper . BindEnv ( confOptions . controlplaneAPI . viperKey , calculateEnvVarName ( confOptions . controlplaneAPI . viperKey )) )
164169
165170 // Custom CAs for the control plane
166- rootCmd .PersistentFlags ().String (confOptions .controlplaneCA .flagName , "" , "CUSTOM CA file for the Control Plane API (optional)" )
167- err = viper .BindPFlag (confOptions .controlplaneCA .viperKey , rootCmd .PersistentFlags ().Lookup (confOptions .controlplaneCA .flagName ))
168- cobra .CheckErr (err )
171+ rootCmd .PersistentFlags ().String (confOptions .controlplaneCA .flagName , "" , fmt . Sprintf ( "CUSTOM CA file for the Control Plane API (optional) ($%s)" , calculateEnvVarName ( confOptions . controlplaneCA . viperKey )) )
172+ cobra . CheckErr ( viper .BindPFlag (confOptions .controlplaneCA .viperKey , rootCmd .PersistentFlags ().Lookup (confOptions .controlplaneCA .flagName ) ))
173+ cobra .CheckErr (viper . BindEnv ( confOptions . controlplaneCA . viperKey , calculateEnvVarName ( confOptions . controlplaneCA . viperKey )) )
169174
170- rootCmd .PersistentFlags ().String (confOptions .CASAPI .flagName , defaultCASAPI , "URL for the Artifacts Content Addressable Storage (CAS)" )
171- err = viper .BindPFlag (confOptions .CASAPI .viperKey , rootCmd .PersistentFlags ().Lookup (confOptions .CASAPI .flagName ))
172- cobra .CheckErr (err )
175+ rootCmd .PersistentFlags ().String (confOptions .CASAPI .flagName , defaultCASAPI , fmt . Sprintf ( "URL for the Artifacts Content Addressable Storage API ($%s)" , calculateEnvVarName ( confOptions . CASAPI . viperKey )) )
176+ cobra . CheckErr ( viper .BindPFlag (confOptions .CASAPI .viperKey , rootCmd .PersistentFlags ().Lookup (confOptions .CASAPI .flagName ) ))
177+ cobra .CheckErr (viper . BindEnv ( confOptions . CASAPI . viperKey , calculateEnvVarName ( confOptions . CASAPI . viperKey )) )
173178
174179 // Custom CAs for the CAS
175- rootCmd .PersistentFlags ().String (confOptions .CASCA .flagName , "" , "CUSTOM CA file for the Artifacts CAS API (optional)" )
176- err = viper .BindPFlag (confOptions .CASCA .viperKey , rootCmd .PersistentFlags ().Lookup (confOptions .CASCA .flagName ))
177- cobra .CheckErr (err )
180+ rootCmd .PersistentFlags ().String (confOptions .CASCA .flagName , "" , fmt .Sprintf ("CUSTOM CA file for the Artifacts CAS API (optional) ($%s)" , calculateEnvVarName (confOptions .CASCA .viperKey )))
181+ cobra .CheckErr (viper .BindPFlag (confOptions .CASCA .viperKey , rootCmd .PersistentFlags ().Lookup (confOptions .CASCA .flagName )))
182+ cobra .CheckErr (viper .BindEnv (confOptions .CASCA .viperKey , calculateEnvVarName (confOptions .CASCA .viperKey )))
183+
184+ rootCmd .PersistentFlags ().BoolVarP (& flagInsecure , "insecure" , "i" , false , fmt .Sprintf ("Skip TLS transport during connection to the control plane ($%s)" , calculateEnvVarName (confOptions .insecure .viperKey )))
185+ cobra .CheckErr (viper .BindPFlag (confOptions .insecure .viperKey , rootCmd .PersistentFlags ().Lookup ("insecure" )))
186+ cobra .CheckErr (viper .BindEnv (confOptions .insecure .viperKey , calculateEnvVarName (confOptions .insecure .viperKey )))
178187
179- rootCmd .PersistentFlags ().BoolVarP (& flagInsecure , "insecure" , "i" , false , "Skip TLS transport during connection to the control plane" )
180188 rootCmd .PersistentFlags ().BoolVar (& flagDebug , "debug" , false , "Enable debug/verbose logging mode" )
181189 rootCmd .PersistentFlags ().StringVarP (& flagOutputFormat , "output" , "o" , "table" , "Output format, valid options are json and table" )
182190
@@ -192,6 +200,18 @@ func NewRootCmd(l zerolog.Logger) *cobra.Command {
192200 return rootCmd
193201}
194202
203+ // this could have been done using automatic + prefix but we want to have control and know the values
204+ //
205+ // viper.AutomaticEnv()
206+ // viper.SetEnvPrefix(envPrefix)
207+ // viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))
208+ func calculateEnvVarName (key string ) string {
209+ // replace - with _ and . with _
210+ s := strings .ReplaceAll (key , "-" , "_" )
211+ s = strings .ReplaceAll (s , "." , "_" )
212+ return fmt .Sprintf ("%s_%s" , envPrefix , strings .ToUpper (s ))
213+ }
214+
195215func init () {
196216 cobra .OnInitialize (initConfigFile )
197217 // Using the cobra.OnFinalize because the hooks don't work on error
0 commit comments