11package investigation
22
33import (
4+ "context"
5+
46 cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
5- "github.com/openshift/configuration-anomaly-detection/pkg/backplane"
7+ "github.com/openshift/backplane-cli/pkg/cli/config"
8+ bpremediation "github.com/openshift/backplane-cli/pkg/remediation"
9+
610 hivev1 "github.com/openshift/hive/apis/hive/v1"
11+ "k8s.io/client-go/rest"
712
813 "github.com/openshift/configuration-anomaly-detection/pkg/aws"
14+ "github.com/openshift/configuration-anomaly-detection/pkg/backplane"
915 k8sclient "github.com/openshift/configuration-anomaly-detection/pkg/k8s"
1016 "github.com/openshift/configuration-anomaly-detection/pkg/logging"
1117 "github.com/openshift/configuration-anomaly-detection/pkg/managedcloud"
1218 "github.com/openshift/configuration-anomaly-detection/pkg/notewriter"
19+ "github.com/openshift/configuration-anomaly-detection/pkg/oc"
1320 "github.com/openshift/configuration-anomaly-detection/pkg/ocm"
1421 "github.com/openshift/configuration-anomaly-detection/pkg/pagerduty"
1522)
@@ -37,6 +44,7 @@ func NewResourceBuilder(
3744 name string ,
3845 logLevel string ,
3946 pipelineName string ,
47+ backplaneUrl string ,
4048) (ResourceBuilder , error ) {
4149 rb := & ResourceBuilderT {
4250 buildLogger : true ,
@@ -45,6 +53,7 @@ func NewResourceBuilder(
4553 logLevel : logLevel ,
4654 pipelineName : pipelineName ,
4755 ocmClient : ocmClient ,
56+ backplaneUrl : backplaneUrl ,
4857 builtResources : & Resources {
4958 BpClient : bpClient ,
5059 PdClient : pdClient ,
@@ -72,17 +81,21 @@ type Resources struct {
7281 ClusterDeployment * hivev1.ClusterDeployment
7382 AwsClient aws.Client
7483 BpClient backplane.Client
84+ RestConfig * RestConfig
7585 K8sClient k8sclient.Client
7686 OcmClient ocm.Client
7787 PdClient pagerduty.Client
7888 Notes * notewriter.NoteWriter
89+ OCClient oc.Client
7990}
8091
8192type ResourceBuilder interface {
8293 WithCluster () ResourceBuilder
8394 WithClusterDeployment () ResourceBuilder
8495 WithAwsClient () ResourceBuilder
96+ WithRestConfig () ResourceBuilder
8597 WithK8sClient () ResourceBuilder
98+ WithOC () ResourceBuilder
8699 WithNotes () ResourceBuilder
87100 Build () (* Resources , error )
88101}
@@ -91,14 +104,17 @@ type ResourceBuilderT struct {
91104 buildCluster bool
92105 buildClusterDeployment bool
93106 buildAwsClient bool
107+ buildRestConfig bool
94108 buildK8sClient bool
109+ buildOC bool
95110 buildNotes bool
96111 buildLogger bool
97112
98113 clusterId string
99114 name string
100115 logLevel string
101116 pipelineName string
117+ backplaneUrl string
102118
103119 ocmClient * ocm.SdkClient
104120
@@ -118,13 +134,26 @@ func (r *ResourceBuilderT) WithClusterDeployment() ResourceBuilder {
118134 return r
119135}
120136
137+ func (r * ResourceBuilderT ) WithRestConfig () ResourceBuilder {
138+ r .WithCluster ()
139+ r .buildRestConfig = true
140+ return r
141+ }
142+
121143func (r * ResourceBuilderT ) WithAwsClient () ResourceBuilder {
122144 r .WithCluster ()
123145 r .buildAwsClient = true
124146 return r
125147}
126148
149+ func (r * ResourceBuilderT ) WithOC () ResourceBuilder {
150+ r .WithRestConfig ()
151+ r .buildOC = true
152+ return r
153+ }
154+
127155func (r * ResourceBuilderT ) WithK8sClient () ResourceBuilder {
156+ r .WithRestConfig ()
128157 r .buildK8sClient = true
129158 return r
130159}
@@ -154,49 +183,107 @@ func (r *ResourceBuilderT) Build() (*Resources, error) {
154183 }
155184 }
156185
157- // Dependent resources can only be built if a cluster object exists.
158- //nolint:nestif
159- if r . builtResources . Cluster != nil {
160- internalClusterId := r . builtResources . Cluster . ID ()
161-
162- if r . buildAwsClient && r . builtResources . AwsClient == nil {
163- r . builtResources . AwsClient , err = managedcloud . CreateCustomerAWSClient ( r .builtResources .Cluster , r . ocmClient )
164- if err != nil {
165- r . buildErr = AWSClientError { ClusterID : r . clusterId , Err : err }
166- return r . builtResources , r . buildErr
167- }
186+ if r . buildNotes && r . builtResources . Notes == nil {
187+ r . builtResources . Notes = notewriter . New ( r . name , logging . RawLogger )
188+ }
189+
190+ internalClusterId := r . builtResources . Cluster . ID ()
191+
192+ if r . buildAwsClient && r .builtResources .AwsClient == nil {
193+ r . builtResources . AwsClient , err = managedcloud . CreateCustomerAWSClient ( r . builtResources . Cluster , r . ocmClient )
194+ if err != nil {
195+ r . buildErr = AWSClientError { ClusterID : r . clusterId , Err : err }
196+ return r . builtResources , r . buildErr
168197 }
198+ }
169199
170- if r .buildK8sClient && r .builtResources .K8sClient == nil {
171- logging .Infof ("creating k8s client for %s" , r .name )
172- r .builtResources .K8sClient , err = k8sclient .New (r .builtResources .Cluster .ID (), r .ocmClient , r .name )
173- if err != nil {
174- r .buildErr = K8SClientError {ClusterID : r .clusterId , Err : err }
175- return r .builtResources , r .buildErr
176- }
200+ if r .buildRestConfig && r .builtResources .RestConfig == nil {
201+ r .builtResources .RestConfig , err = newRestConfig (r .builtResources .Cluster .ID (), r .backplaneUrl , r .ocmClient , r .name )
202+ if err != nil {
203+ r .buildErr = RestConfigError {ClusterID : r .clusterId , Err : err }
204+ return r .builtResources , r .buildErr
177205 }
206+ }
207+
208+ if r .buildK8sClient && r .builtResources .K8sClient == nil {
209+ logging .Infof ("creating k8s client for %s" , r .name )
210+ r .builtResources .K8sClient , err = k8sclient .New (& r .builtResources .RestConfig .Config )
211+ if err != nil {
212+ r .buildErr = K8SClientError {ClusterID : r .clusterId , Err : err }
213+ return r .builtResources , r .buildErr
214+ }
215+ }
178216
179- if r .buildClusterDeployment && r .builtResources .ClusterDeployment == nil {
180- r .builtResources .ClusterDeployment , err = r .ocmClient .GetClusterDeployment (internalClusterId )
181- if err != nil {
182- r .buildErr = ClusterDeploymentNotFoundError {ClusterID : r .clusterId , Err : err }
183- return r .builtResources , r .buildErr
184- }
217+ if r .buildOC && r .builtResources .OCClient == nil {
218+ r .builtResources .OCClient , err = oc .New (context .Background (), & r .builtResources .RestConfig .Config )
219+ if err != nil {
220+ r .buildErr = OCClientError {ClusterID : r .clusterId , Err : err }
221+ return r .builtResources , r .buildErr
185222 }
223+ }
186224
187- if r .buildLogger {
188- // Re-initialize the logger with the cluster ID.
189- logging .RawLogger = logging .InitLogger (r .logLevel , r .pipelineName , internalClusterId )
225+ if r .buildClusterDeployment && r .builtResources .ClusterDeployment == nil {
226+ r .builtResources .ClusterDeployment , err = r .ocmClient .GetClusterDeployment (internalClusterId )
227+ if err != nil {
228+ r .buildErr = ClusterDeploymentNotFoundError {ClusterID : r .clusterId , Err : err }
229+ return r .builtResources , r .buildErr
190230 }
191231 }
192232
193- if r .buildNotes && r .builtResources .Notes == nil {
194- r .builtResources .Notes = notewriter .New (r .name , logging .RawLogger )
233+ if r .buildLogger {
234+ // Re-initialize the logger with the cluster ID.
235+ logging .RawLogger = logging .InitLogger (r .logLevel , r .pipelineName , internalClusterId )
195236 }
196237
197238 return r .builtResources , nil
198239}
199240
241+ type remediationCleaner struct {
242+ clusterID string
243+ ocmClient ocm.Client
244+ remediationInstanceId string
245+ backplaneUrl string
246+ }
247+
248+ type Cleaner interface {
249+ Clean () error
250+ }
251+
252+ type RestConfig struct {
253+ rest.Config
254+ backplaneUrl string
255+ Cleaner
256+ }
257+
258+ func (cleaner remediationCleaner ) Clean () error {
259+ return deleteRemediation (cleaner .clusterID , cleaner .backplaneUrl , cleaner .ocmClient , cleaner .remediationInstanceId )
260+ }
261+
262+ // New returns a k8s rest config for the given cluster scoped to a given remediation's permissions.
263+ func newRestConfig (clusterID , backplaneUrl string , ocmClient ocm.Client , remediationName string ) (* RestConfig , error ) {
264+ decoratedCfg , remediationInstanceId , err := bpremediation .CreateRemediationWithConn (
265+ config.BackplaneConfiguration {URL : backplaneUrl },
266+ ocmClient .GetConnection (),
267+ clusterID ,
268+ remediationName ,
269+ )
270+ if err != nil {
271+ return nil , err
272+ }
273+
274+ return & RestConfig {* decoratedCfg , backplaneUrl , remediationCleaner {clusterID , ocmClient , remediationInstanceId , backplaneUrl }}, nil
275+ }
276+
277+ // Cleanup removes the remediation created for the cluster.
278+ func deleteRemediation (clusterID , backplaneUrl string , ocmClient ocm.Client , remediationInstanceId string ) error {
279+ return bpremediation .DeleteRemediationWithConn (
280+ config.BackplaneConfiguration {URL : backplaneUrl },
281+ ocmClient .GetConnection (),
282+ clusterID ,
283+ remediationInstanceId ,
284+ )
285+ }
286+
200287// This is an implementation to be used in tests, but putting it into a _test.go file will make it not resolvable.
201288type ResourceBuilderMock struct {
202289 Resources * Resources
@@ -215,6 +302,14 @@ func (r *ResourceBuilderMock) WithAwsClient() ResourceBuilder {
215302 return r
216303}
217304
305+ func (r * ResourceBuilderMock ) WithRestConfig () ResourceBuilder {
306+ return r
307+ }
308+
309+ func (r * ResourceBuilderMock ) WithOC () ResourceBuilder {
310+ return r
311+ }
312+
218313func (r * ResourceBuilderMock ) WithNotes () ResourceBuilder {
219314 return r
220315}
0 commit comments