Skip to content

Commit 582f9b1

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 f04b1cf commit 582f9b1

File tree

19 files changed

+447
-194
lines changed

19 files changed

+447
-194
lines changed

cadctl/cmd/investigate/investigate.go

Lines changed: 87 additions & 42 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+
"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"
@@ -40,39 +40,79 @@ var InvestigateCmd = &cobra.Command{
4040
Use: "investigate",
4141
SilenceUsage: true,
4242
Short: "Filter for and investigate supported alerts",
43-
RunE: run,
43+
PreRunE: func(cmd *cobra.Command, _ []string) error {
44+
var err error
45+
var c config.Config
46+
47+
c, err = config.BuildConfig(cmd)
48+
if err != nil {
49+
return fmt.Errorf("failed to build config: %w", err)
50+
}
51+
52+
// Initialize the logger here because it depends on user input
53+
logging.RawLogger = logging.InitLogger(c.LogLevel)
54+
logging.RawLogger = logging.WithPipelineName(logging.RawLogger, c.PipelineName)
55+
56+
// configure the RunE command using a wrapper to
57+
// append the configuration into the command
58+
cmd.RunE = func(cmd *cobra.Command, args []string) error {
59+
if err := run(c, cmd, args); err != nil {
60+
logging.Error(err)
61+
}
62+
return err
63+
}
64+
65+
return nil
66+
},
67+
RunE: func(_ *cobra.Command, _ []string) error {
68+
// DO NOT REMOVE
69+
// this ensures RunE work as expected
70+
// RunE is set in the PreRunE function
71+
// this works because the RunE is always called after PreRunE
72+
return nil
73+
},
4474
}
4575

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

5178
const pagerdutyTitlePrefix = "[CAD Investigated]"
5279

5380
func init() {
5481
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")
5682

5783
err := InvestigateCmd.MarkFlagRequired("payload-path")
5884
if err != nil {
5985
logging.Warn("Could not mark flag 'payload-path' as required")
6086
}
6187
}
6288

63-
func run(cmd *cobra.Command, _ []string) error {
64-
// 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, "")
89+
func run(c config.Config, _ *cobra.Command, _ []string) error {
90+
var err error
91+
92+
if c.PrometheusPushGateway == "" {
93+
logging.Warn("metrics disabled, set env 'CAD_PROMETHEUS_PUSHGATEWAY' to push metrics")
94+
}
95+
96+
err = metrics.Push(c.PrometheusPushGateway)
97+
if err != nil {
98+
logging.Warnf("failed to push metrics: %v", err)
6899
}
100+
101+
// early init of logger for logs before clusterID is known
69102
payload, err := os.ReadFile(payloadPath)
70103
if err != nil {
71104
return fmt.Errorf("failed to read webhook payload: %w", err)
72105
}
73106
logging.Info("Running CAD with webhook payload:", string(payload))
74107

75-
pdClient, err := pagerduty.GetPDClient(payload)
108+
if c.PagerDutyToken == "" {
109+
return fmt.Errorf("missing PagerDuty token")
110+
}
111+
if c.PagerDutySilentPolicy == "" {
112+
return fmt.Errorf("missing PagerDuty silent policy")
113+
}
114+
115+
pdClient, err := pagerduty.GetPDClient(payload, c.PagerDutyToken, c.PagerDutySilentPolicy)
76116
if err != nil {
77117
return fmt.Errorf("could not initialize pagerduty client: %w", err)
78118
}
@@ -87,8 +127,7 @@ func run(cmd *cobra.Command, _ []string) error {
87127
}
88128
}()
89129

90-
_, cadExperimentalEnabled := os.LookupEnv("CAD_EXPERIMENTAL_ENABLED")
91-
alertInvestigation := investigations.GetInvestigation(pdClient.GetTitle(), cadExperimentalEnabled)
130+
alertInvestigation := investigations.GetInvestigation(pdClient.GetTitle(), c.Experimental)
92131

93132
// Escalate all unsupported alerts
94133
if alertInvestigation == nil {
@@ -109,8 +148,11 @@ func run(cmd *cobra.Command, _ []string) error {
109148
return err
110149
}
111150

112-
ocmClient, err := GetOCMClient()
113-
if err != nil {
151+
var ocmClient *ocm.SdkClient
152+
var ocmErr error
153+
154+
ocmClient, ocmErr = ocm.NewFromClientKeyPair(c.CadOcmURL, c.CadOcmClientID, c.CadOcmClientSecret)
155+
if ocmErr != nil {
114156
return fmt.Errorf("could not initialize ocm client: %w", err)
115157
}
116158

@@ -127,13 +169,8 @@ func run(cmd *cobra.Command, _ []string) error {
127169
// For installing clusters, externalID can be empty.
128170
internalClusterID := cluster.ID()
129171

130-
// re-initialize logger for the internal-cluster-id context
131-
// if log-level flag is set, take priority over env + default
132-
if cmd.Flags().Changed("log-level") {
133-
logging.RawLogger = logging.InitLogger(logLevelFlag, internalClusterID)
134-
} else {
135-
logging.RawLogger = logging.InitLogger(logging.LogLevelString, internalClusterID)
136-
}
172+
// add the internal-cluster-id context to the logger
173+
logging.RawLogger = logging.WithClusterID(logging.RawLogger, internalClusterID)
137174

138175
requiresInvestigation, err := clusterRequiresInvestigation(cluster, pdClient, ocmClient)
139176
if err != nil || !requiresInvestigation {
@@ -145,7 +182,22 @@ func run(cmd *cobra.Command, _ []string) error {
145182
return fmt.Errorf("could not retrieve Cluster Deployment for %s: %w", internalClusterID, err)
146183
}
147184

148-
customerAwsClient, err := managedcloud.CreateCustomerAWSClient(cluster, ocmClient)
185+
if c.BackplaneURL == "" {
186+
return fmt.Errorf("missing backplane URL")
187+
}
188+
if c.BackplaneProxyURL == "" {
189+
logging.Warn("missing backplane proxy URL, using default")
190+
}
191+
if c.BackplaneInitialARN == "" {
192+
return fmt.Errorf("missing backplane initial ARN")
193+
}
194+
customerAwsClient, err := managedcloud.CreateCustomerAWSClient(
195+
cluster,
196+
ocmClient,
197+
c.BackplaneURL,
198+
c.BackplaneProxyURL,
199+
c.BackplaneInitialARN,
200+
)
149201
if err != nil {
150202
ccamResources := &investigation.Resources{Name: "ccam", Cluster: cluster, ClusterDeployment: clusterDeployment, AwsClient: customerAwsClient, OcmClient: ocmClient, PdClient: pdClient, Notes: nil, AdditionalResources: map[string]interface{}{"error": err}}
151203
inv := ccam.Investigation{}
@@ -154,7 +206,16 @@ func run(cmd *cobra.Command, _ []string) error {
154206
return err
155207
}
156208

157-
investigationResources = &investigation.Resources{Name: alertInvestigation.Name(), Cluster: cluster, ClusterDeployment: clusterDeployment, AwsClient: customerAwsClient, OcmClient: ocmClient, PdClient: pdClient, Notes: nil}
209+
investigationResources = &investigation.Resources{
210+
Name: alertInvestigation.Name(),
211+
BackplaneURL: c.BackplaneURL,
212+
Cluster: cluster,
213+
ClusterDeployment: clusterDeployment,
214+
AwsClient: customerAwsClient,
215+
OcmClient: ocmClient,
216+
PdClient: pdClient,
217+
Notes: nil,
218+
}
158219

159220
logging.Infof("Starting investigation for %s", alertInvestigation.Name())
160221
result, err := alertInvestigation.Run(investigationResources)
@@ -189,22 +250,6 @@ func handleCADFailure(err error, resources *investigation.Resources, pdClient *p
189250
}
190251
}
191252

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

cadctl/cmd/root.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ package cmd
1818

1919
import (
2020
investigate "github.com/openshift/configuration-anomaly-detection/cadctl/cmd/investigate"
21-
"github.com/openshift/configuration-anomaly-detection/pkg/logging"
22-
"github.com/openshift/configuration-anomaly-detection/pkg/metrics"
2321
"github.com/spf13/cobra"
2422
)
2523

@@ -31,14 +29,13 @@ var rootCmd = &cobra.Command{
3129

3230
// Execute adds all child commands to the root command and sets flags appropriately.
3331
// This is called by main.main(). It only needs to happen once to the rootCmd.
34-
func Execute() {
32+
func Execute() error {
3533
err := rootCmd.Execute()
36-
metrics.Push()
37-
if err != nil {
38-
logging.Fatal(err)
39-
}
34+
35+
return err
4036
}
4137

4238
func init() {
4339
rootCmd.AddCommand(investigate.InvestigateCmd)
40+
rootCmd.PersistentFlags().StringP("loglevel", "l", "info", "Log level to use. One of: debug, info, warn, error, fatal, panic")
4441
}

0 commit comments

Comments
 (0)