Skip to content

Commit b6d8bbd

Browse files
committed
Simplify the configuration loading
Moves the options to flags. Also moves the env variables to the main command, so there are no sideeffects when running the commands. Signed-off-by: Petr Kotas <pkotas@redhat.com>
1 parent f842c77 commit b6d8bbd

File tree

7 files changed

+312
-110
lines changed

7 files changed

+312
-110
lines changed

cadctl/cmd/investigate/investigate.go

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ package investigate
1919
import (
2020
"fmt"
2121
"os"
22-
"path/filepath"
2322
"strings"
2423

2524
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
25+
config "github.com/openshift/configuration-anomaly-detection/cadctl/config"
2626
investigations "github.com/openshift/configuration-anomaly-detection/pkg/investigations"
2727
"github.com/openshift/configuration-anomaly-detection/pkg/investigations/ccam"
2828
investigation "github.com/openshift/configuration-anomaly-detection/pkg/investigations/investigation"
@@ -31,6 +31,7 @@ import (
3131
"github.com/openshift/configuration-anomaly-detection/pkg/metrics"
3232
ocm "github.com/openshift/configuration-anomaly-detection/pkg/ocm"
3333
"github.com/openshift/configuration-anomaly-detection/pkg/pagerduty"
34+
"go.uber.org/zap"
3435

3536
"github.com/spf13/cobra"
3637
)
@@ -40,19 +41,40 @@ var InvestigateCmd = &cobra.Command{
4041
Use: "investigate",
4142
SilenceUsage: true,
4243
Short: "Filter for and investigate supported alerts",
43-
RunE: run,
44+
PreRunE: func(cmd *cobra.Command, args []string) error {
45+
var err error
46+
47+
if config.Config.ConfigFile != "" {
48+
// loads the configuration unless config file is present
49+
// config should be used only when developing
50+
if _, err = config.Config.GetCadOcmClientID(cmd); err != nil {
51+
return fmt.Errorf("failed to get cadOcmClientID: %w", err)
52+
}
53+
if _, err = config.Config.GetCadOcmClientSecret(cmd); err != nil {
54+
return fmt.Errorf("failed to get cadOcmClientSecret: %w", err)
55+
}
56+
if _, err = config.Config.GetCadOcmURL(cmd); err != nil {
57+
return fmt.Errorf("failed to get cadOcmURL: %w", err)
58+
}
59+
}
60+
61+
if _, err = config.Config.GetExperimental(cmd); err != nil {
62+
return fmt.Errorf("failed to get experimental flag: %w", err)
63+
}
64+
65+
return nil
66+
},
67+
RunE: run,
4468
}
4569

46-
var (
47-
logLevelFlag = ""
48-
payloadPath = "./payload.json"
49-
)
70+
var payloadPath = "./payload.json"
5071

5172
const pagerdutyTitlePrefix = "[CAD Investigated]"
5273

5374
func init() {
75+
logging.RawLogger = logging.InitLogger(config.Config.LogLevel, "")
76+
5477
InvestigateCmd.Flags().StringVarP(&payloadPath, "payload-path", "p", payloadPath, "the path to the payload")
55-
InvestigateCmd.Flags().StringVarP(&logging.LogLevelString, "log-level", "l", "", "the log level [debug,info,warn,error,fatal], default = info")
5678

5779
err := InvestigateCmd.MarkFlagRequired("payload-path")
5880
if err != nil {
@@ -62,10 +84,6 @@ func init() {
6284

6385
func run(cmd *cobra.Command, _ []string) error {
6486
// early init of logger for logs before clusterID is known
65-
if cmd.Flags().Changed("log-level") {
66-
flagValue, _ := cmd.Flags().GetString("log-level")
67-
logging.RawLogger = logging.InitLogger(flagValue, "")
68-
}
6987
payload, err := os.ReadFile(payloadPath)
7088
if err != nil {
7189
return fmt.Errorf("failed to read webhook payload: %w", err)
@@ -87,8 +105,7 @@ func run(cmd *cobra.Command, _ []string) error {
87105
}
88106
}()
89107

90-
_, cadExperimentalEnabled := os.LookupEnv("CAD_EXPERIMENTAL_ENABLED")
91-
alertInvestigation := investigations.GetInvestigation(pdClient.GetTitle(), cadExperimentalEnabled)
108+
alertInvestigation := investigations.GetInvestigation(pdClient.GetTitle(), config.Config.Experimental)
92109

93110
// Escalate all unsupported alerts
94111
if alertInvestigation == nil {
@@ -109,8 +126,17 @@ func run(cmd *cobra.Command, _ []string) error {
109126
return err
110127
}
111128

112-
ocmClient, err := GetOCMClient()
113-
if err != nil {
129+
var ocmClient *ocm.SdkClient
130+
var ocmErr error
131+
// Initialize the OCM client
132+
// If the config file is set, use it to initialize the OCM client
133+
// use config file only when developing
134+
if config.Config.ConfigFile != "" {
135+
ocmClient, ocmErr = ocm.NewFromConfig(config.Config.ConfigFile)
136+
} else {
137+
ocmClient, ocmErr = ocm.NewFromClientKeyPair(config.Config.CadOcmURL, config.Config.CadOcmClientID, config.Config.CadOcmClientSecret)
138+
}
139+
if ocmErr != nil {
114140
return fmt.Errorf("could not initialize ocm client: %w", err)
115141
}
116142

@@ -122,13 +148,8 @@ func run(cmd *cobra.Command, _ []string) error {
122148
// For installing clusters, externalID can be empty.
123149
internalClusterID := cluster.ID()
124150

125-
// re-initialize logger for the internal-cluster-id context
126-
// if log-level flag is set, take priority over env + default
127-
if cmd.Flags().Changed("log-level") {
128-
logging.RawLogger = logging.InitLogger(logLevelFlag, internalClusterID)
129-
} else {
130-
logging.RawLogger = logging.InitLogger(logging.LogLevelString, internalClusterID)
131-
}
151+
// add the internal-cluster-id context to the logger
152+
logging.RawLogger = logging.RawLogger.With(zap.String("cluster_id", internalClusterID))
132153

133154
requiresInvestigation, err := clusterRequiresInvestigation(cluster, pdClient, ocmClient)
134155
if err != nil || !requiresInvestigation {
@@ -184,22 +205,6 @@ func handleCADFailure(err error, resources *investigation.Resources, pdClient *p
184205
}
185206
}
186207

187-
// GetOCMClient will retrieve the OcmClient from the 'ocm' package
188-
func GetOCMClient() (*ocm.SdkClient, error) {
189-
cadOcmFilePath := os.Getenv("CAD_OCM_FILE_PATH")
190-
191-
_, err := os.Stat(cadOcmFilePath)
192-
if os.IsNotExist(err) {
193-
configDir, err := os.UserConfigDir()
194-
if err != nil {
195-
return nil, err
196-
}
197-
cadOcmFilePath = filepath.Join(configDir, "/ocm/ocm.json")
198-
}
199-
200-
return ocm.New(cadOcmFilePath)
201-
}
202-
203208
// Checks pre-requisites for a cluster investigation:
204209
// - the cluster's state is supported by CAD for an investigation (= not uninstalling)
205210
// - the cloud provider is supported by CAD (cluster is AWS)

cadctl/cmd/root.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,20 @@ limitations under the License.
1717
package cmd
1818

1919
import (
20+
21+
// "github.com/openshift-online/ocm-cli/pkg/config"
2022
investigate "github.com/openshift/configuration-anomaly-detection/cadctl/cmd/investigate"
23+
config "github.com/openshift/configuration-anomaly-detection/cadctl/config"
2124
"github.com/openshift/configuration-anomaly-detection/pkg/logging"
2225
"github.com/openshift/configuration-anomaly-detection/pkg/metrics"
2326
"github.com/spf13/cobra"
2427
)
2528

2629
// rootCmd represents the base command when called without any subcommands
2730
var rootCmd = &cobra.Command{
28-
Use: "cadctl",
29-
Short: "A util of configuration-anomaly-detection (CAD) checks",
31+
Use: "cadctl",
32+
Short: "A util of configuration-anomaly-detection (CAD) checks",
33+
PersistentPreRunE: loadCommon,
3034
}
3135

3236
// Execute adds all child commands to the root command and sets flags appropriately.
@@ -41,4 +45,22 @@ func Execute() {
4145

4246
func init() {
4347
rootCmd.AddCommand(investigate.InvestigateCmd)
48+
rootCmd.PersistentFlags().StringP("ocmconfig", "c", "", "Path to the OCM config file to use for CLI requests. When not set the OCM_CONFIG environment variable will be used. If that is not set, the default OCM config locations will be file will be used.")
49+
}
50+
51+
func loadCommon(cmd *cobra.Command, args []string) error {
52+
var err error
53+
54+
_, err = config.Config.GetLogLevel(cmd)
55+
if err != nil {
56+
logging.Fatal(err)
57+
return err
58+
}
59+
_, err = config.Config.GetConfigFile(cmd)
60+
if err != nil {
61+
logging.Fatal(err)
62+
return err
63+
}
64+
65+
return nil
4466
}

cadctl/config/config.go

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
Copyright © 2022 Red Hat, Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package config
18+
19+
import (
20+
"fmt"
21+
"os"
22+
23+
"github.com/spf13/cobra"
24+
25+
"github.com/openshift/configuration-anomaly-detection/pkg/ocm"
26+
)
27+
28+
type config struct {
29+
ConfigFile string
30+
LogLevel string
31+
CadOcmClientID string
32+
CadOcmClientSecret string
33+
CadOcmURL string
34+
Experimental bool
35+
}
36+
37+
var Config config
38+
39+
// GetConfigFile retrieves the OCM config file path from the command line flags or environment variables.
40+
// It checks the following in order:
41+
// 1. Command line flag --ocmconfig
42+
// 2. Environment variable OCM_CONFIG
43+
// 3. Default OCM config locations
44+
// If the file is not found at any of these locations, the config path remains empty.
45+
// Missing config is a valid state, as the user may not have a config file.
46+
func (c *config) GetConfigFile(cmd *cobra.Command) (string, error) {
47+
ocmConfigPath, err := cmd.Flags().GetString("ocmconfig")
48+
if err != nil {
49+
return "", fmt.Errorf("failed to get ocmconfig flag: %w", err)
50+
}
51+
52+
if ocmConfigPath != "" {
53+
if _, err := os.Stat(ocmConfigPath); err != nil {
54+
return "", fmt.Errorf("ocmconfig file not found at %s: %w", ocmConfigPath, err)
55+
}
56+
57+
c.ConfigFile = ocmConfigPath
58+
return ocmConfigPath, nil
59+
}
60+
61+
ocmConfigPath, exists := os.LookupEnv("OCM_CONFIG")
62+
if exists {
63+
if _, err := os.Stat(ocmConfigPath); err != nil {
64+
return "", fmt.Errorf("ocmconfig file not found at %s: %w", ocmConfigPath, err)
65+
}
66+
67+
c.ConfigFile = ocmConfigPath
68+
return ocmConfigPath, nil
69+
}
70+
71+
ocmConfigPath, err = ocm.Location()
72+
if err != nil {
73+
// Location() checks for file existence
74+
return "", fmt.Errorf("failed to get ocmconfig file location: %w", err)
75+
}
76+
77+
c.ConfigFile = ocmConfigPath
78+
return ocmConfigPath, nil
79+
}
80+
81+
func (c *config) GetLogLevel(cmd *cobra.Command) (string, error) {
82+
logLevel, err := cmd.Flags().GetString("log-level")
83+
if err != nil {
84+
return "", fmt.Errorf("failed to get log-level flag: %w", err)
85+
}
86+
if logLevel != "" {
87+
c.LogLevel = logLevel
88+
return logLevel, nil
89+
}
90+
91+
if envLogLevel, exists := os.LookupEnv("LOG_LEVEL"); exists {
92+
c.LogLevel = envLogLevel
93+
return logLevel, nil
94+
}
95+
96+
c.LogLevel = "info"
97+
return logLevel, nil
98+
}
99+
100+
// GetExperimental retrieves the experimental flag passed as a command line argument.
101+
// If not set, it checks the CAD_EXPERIMENTAL_ENABLED environment variable.
102+
// Defaults to false if neither is set.
103+
func (c *config) GetExperimental(cmd *cobra.Command) (bool, error) {
104+
experimentalFlag, err := cmd.Flags().GetBool("experimental")
105+
if err != nil {
106+
return false, fmt.Errorf("failed to get experimental flag: %w", err)
107+
}
108+
if experimentalFlag {
109+
c.Experimental = true
110+
return experimentalFlag, nil
111+
}
112+
113+
experimental, exist := os.LookupEnv("CAD_EXPERIMENTAL_ENABLED")
114+
if exist && experimental == "true" {
115+
c.Experimental = true
116+
return experimentalFlag, nil
117+
}
118+
119+
c.Experimental = false
120+
return experimentalFlag, nil
121+
}
122+
123+
// GetCadOcmClientID retrieves the OCM cliend ID passed as
124+
// an CAD_OCM_CLIENT_ID environment variable.
125+
func (c *config) GetCadOcmClientID(cmd *cobra.Command) (string, error) {
126+
cadOcmClientID, exist := os.LookupEnv("CAD_OCM_CLIENT_ID")
127+
if !exist {
128+
return "", fmt.Errorf("client-id flag or CAD_OCM_CLIENT_ID environment variable must be set")
129+
}
130+
131+
c.CadOcmClientID = cadOcmClientID
132+
return cadOcmClientID, nil
133+
}
134+
135+
// GetCadOcmClientSecret retrieves the OCM client secret passed as
136+
// an environment CAD_OCM_CLIENT_SECRET variable.
137+
func (c *config) GetCadOcmClientSecret(cmd *cobra.Command) (string, error) {
138+
cadOcmClientSecret, exist := os.LookupEnv("CAD_OCM_CLIENT_SECRET")
139+
if !exist {
140+
return "", fmt.Errorf("client-secret flag or CAD_OCM_CLIENT_SECRET environment variable must be set")
141+
}
142+
143+
c.CadOcmClientSecret = cadOcmClientSecret
144+
return cadOcmClientSecret, nil
145+
}
146+
147+
// GetCadOcmURL retrieves the OCM URL passed as an environment
148+
// CAD_OCM_URL variable.
149+
func (c *config) GetCadOcmURL(cmd *cobra.Command) (string, error) {
150+
cadOcmURL, exist := os.LookupEnv("CAD_OCM_URL")
151+
if !exist {
152+
return "", fmt.Errorf("ocm-url flag or CAD_OCM_URL environment variable must be set")
153+
}
154+
155+
c.CadOcmURL = cadOcmURL
156+
return cadOcmURL, nil
157+
}

interceptor/main.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const (
2222
idleTimeout = 60 * time.Second
2323
)
2424

25-
var logger = logging.InitLogger(logging.LogLevelString, "")
25+
var logger = logging.RawLogger
2626

2727
func main() {
2828
// set up signals so we handle the first shutdown signal gracefully
@@ -71,6 +71,18 @@ func main() {
7171
logger.Infof("Server exiting")
7272
}
7373

74+
func init() {
75+
// read log level from environment variable
76+
logLevel := os.Getenv("LOG_LEVEL")
77+
if logLevel != "" || logLevel == "info" {
78+
// no change needed
79+
return
80+
}
81+
82+
// set up logging
83+
logging.RawLogger = logging.InitLogger(logLevel, "")
84+
}
85+
7486
func readinessHandler(w http.ResponseWriter, r *http.Request) {
7587
w.WriteHeader(http.StatusOK)
7688
}

0 commit comments

Comments
 (0)