From ca2f6b5760ca129c90e781b12ab4231a52a052e3 Mon Sep 17 00:00:00 2001 From: Michael Shen Date: Sun, 11 Feb 2024 17:20:03 -0500 Subject: [PATCH] Add osdctl command to remediate OCPBUGS-23174 Signed-off-by: Michael Shen --- cmd/cluster/cleanup_leaked_ec2.go | 181 +++++++++++++++++++++++++ cmd/cluster/cleanup_leaked_ec2_test.go | 115 ++++++++++++++++ cmd/cluster/cmd.go | 1 + go.mod | 11 +- go.sum | 29 +++- pkg/utils/ocm.go | 2 +- 6 files changed, 329 insertions(+), 10 deletions(-) create mode 100644 cmd/cluster/cleanup_leaked_ec2.go create mode 100644 cmd/cluster/cleanup_leaked_ec2_test.go diff --git a/cmd/cluster/cleanup_leaked_ec2.go b/cmd/cluster/cleanup_leaked_ec2.go new file mode 100644 index 00000000..3ee1ff34 --- /dev/null +++ b/cmd/cluster/cleanup_leaked_ec2.go @@ -0,0 +1,181 @@ +package cluster + +import ( + "context" + "fmt" + "log" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/ec2" + "github.com/aws/aws-sdk-go-v2/service/ec2/types" + cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1" + "github.com/openshift/osdctl/pkg/k8s" + "github.com/openshift/osdctl/pkg/osdCloud" + "github.com/openshift/osdctl/pkg/utils" + "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/runtime" + capav1beta2 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type cleanup struct { + awsClient cleanupAWSClient + client client.Client + cluster *cmv1.Cluster + mgmtCluster *cmv1.Cluster + + // ClusterId is the internal or external OCM cluster ID. + // This is optional, but typically is used to automatically detect the correct settings. + ClusterId string + // Yes default confirmation prompts to yes + Yes bool +} + +type cleanupAWSClient interface { + DescribeInstances(ctx context.Context, params *ec2.DescribeInstancesInput, optFns ...func(options *ec2.Options)) (*ec2.DescribeInstancesOutput, error) + TerminateInstances(ctx context.Context, params *ec2.TerminateInstancesInput, optFns ...func(options *ec2.Options)) (*ec2.TerminateInstancesOutput, error) +} + +func newCmdCleanupLeakedEC2() *cobra.Command { + c := &cleanup{} + + cleanupCmd := &cobra.Command{ + Use: "cleanup-leaked-ec2", + Short: "Remediate impact of https://issues.redhat.com/browse/OCPBUGS-23174", + Example: ` + # Run against a given ROSA HCP cluster + osdctl cluster cleanup-leaked-ec2 --cluster-id ${CLUSTER_ID} + + # Assess all "error" state ROSA HCP clusters for impact + for cluster in $(ocm list cluster -p search="hypershift.enabled='true' and state='error'" --columns='id' --no-headers); + do + osdctl cluster cleanup-leaked-ec2 --cluster-id ${cluster} + done +`, + RunE: func(cmd *cobra.Command, args []string) error { + return c.Run(context.Background()) + }, + } + + cleanupCmd.Flags().StringVarP(&c.ClusterId, "cluster-id", "C", "", "OCM internal/external cluster id to check for impact of OCPBUGS-23174.") + cleanupCmd.Flags().BoolVarP(&c.Yes, "yes", "y", false, "(optional) Skip confirmation prompt when terminating instances") + + cleanupCmd.MarkFlagRequired("cluster-id") + + return cleanupCmd +} + +func (c *cleanup) New(ctx context.Context) error { + log.Printf("searching OCM for cluster: %s", c.ClusterId) + conn, err := utils.CreateConnection() + if err != nil { + return err + } + defer conn.Close() + + cluster, err := utils.GetClusterAnyStatus(conn, c.ClusterId) + if err != nil { + return fmt.Errorf("failed to get OCM cluster info for %s: %v", c.ClusterId, err) + } + c.cluster = cluster + log.Printf("cluster %s found from OCM: %s", c.ClusterId, cluster.ID()) + + if !cluster.Hypershift().Enabled() { + return fmt.Errorf("this command is only meant for ROSA HCP clusters") + } + + log.Printf("getting AWS credentials from backplane-api") + cfg, err := osdCloud.CreateAWSV2Config(conn, c.cluster) + if err != nil { + return fmt.Errorf("failed to get credentials automatically from backplane-api: %v", err) + } + log.Println(ctx, "retrieved AWS credentials from backplane-api") + c.awsClient = ec2.NewFromConfig(cfg) + + mgmtCluster, err := utils.GetManagementCluster(c.cluster.ID()) + if err != nil { + return err + } + c.mgmtCluster = mgmtCluster + + scheme := runtime.NewScheme() + if err := capav1beta2.AddToScheme(scheme); err != nil { + return err + } + client, err := k8s.New(c.mgmtCluster.ID(), client.Options{Scheme: scheme}) + if err != nil { + return err + } + c.client = client + + return nil +} + +func (c *cleanup) Run(ctx context.Context) error { + if err := c.New(ctx); err != nil { + return err + } + + if err := c.RemediateOCPBUGS23174(ctx); err != nil { + return err + } + + return nil +} + +func (c *cleanup) RemediateOCPBUGS23174(ctx context.Context) error { + awsmachines := &capav1beta2.AWSMachineList{} + if err := c.client.List(ctx, awsmachines, client.MatchingLabels{ + "cluster.x-k8s.io/cluster-name": c.cluster.ID(), + }); err != nil { + return err + } + + expectedInstances := map[string]bool{} + for _, awsmachine := range awsmachines.Items { + expectedInstances[*awsmachine.Spec.InstanceID] = true + } + log.Printf("expected instances: %v", expectedInstances) + + resp, err := c.awsClient.DescribeInstances(ctx, &ec2.DescribeInstancesInput{ + Filters: []types.Filter{ + { + Name: aws.String("tag:red-hat-managed"), + Values: []string{"true"}, + }, + { + Name: aws.String(fmt.Sprintf("tag:sigs.k8s.io/cluster-api-provider-aws/cluster/%s", c.cluster.ID())), + Values: []string{"owned"}, + }, + }, + }) + if err != nil { + return fmt.Errorf("failed to find EC2 instances associated with %s: %v", c.cluster.ID(), err) + } + + leakedInstances := []string{} + for _, reservation := range resp.Reservations { + for _, instance := range reservation.Instances { + if _, ok := expectedInstances[*instance.InstanceId]; !ok { + leakedInstances = append(leakedInstances, *instance.InstanceId) + } + } + } + + if len(leakedInstances) > 0 { + log.Printf("terminating %d leaked instances: %v", len(leakedInstances), leakedInstances) + if c.Yes || utils.ConfirmPrompt() { + if _, err := c.awsClient.TerminateInstances(ctx, &ec2.TerminateInstancesInput{ + InstanceIds: leakedInstances, + }); err != nil { + return fmt.Errorf("failed to automatically cleanup EC2 instances: %v", err) + } + + log.Printf("success - the cluster should be uninstalled soon") + return nil + } + } + + log.Println("found 0 leaked instances") + return nil +} diff --git a/cmd/cluster/cleanup_leaked_ec2_test.go b/cmd/cluster/cleanup_leaked_ec2_test.go new file mode 100644 index 00000000..5c24e5c5 --- /dev/null +++ b/cmd/cluster/cleanup_leaked_ec2_test.go @@ -0,0 +1,115 @@ +package cluster + +import ( + "context" + "testing" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/ec2" + "github.com/aws/aws-sdk-go-v2/service/ec2/types" + cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + capav1beta2 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2" + "sigs.k8s.io/controller-runtime/pkg/client/fake" +) + +type mockCleanupAWSClient struct { + describeInstancesResp *ec2.DescribeInstancesOutput + terminateInstancesResp *ec2.TerminateInstancesOutput +} + +func (m mockCleanupAWSClient) DescribeInstances(ctx context.Context, params *ec2.DescribeInstancesInput, optFns ...func(options *ec2.Options)) (*ec2.DescribeInstancesOutput, error) { + return m.describeInstancesResp, nil +} + +func (m mockCleanupAWSClient) TerminateInstances(ctx context.Context, params *ec2.TerminateInstancesInput, optFns ...func(options *ec2.Options)) (*ec2.TerminateInstancesOutput, error) { + return m.terminateInstancesResp, nil +} + +// newTestCluster assembles a *cmv1.Cluster while handling the error to help out with inline test-case generation +func newTestCluster(t *testing.T, cb *cmv1.ClusterBuilder) *cmv1.Cluster { + cluster, err := cb.Build() + if err != nil { + t.Fatalf("failed to build cluster: %s", err) + } + + return cluster +} + +func Test_cleanup_RemediateOCPBUGS23174(t *testing.T) { + scheme := runtime.NewScheme() + if err := capav1beta2.AddToScheme(scheme); err != nil { + t.Fatal(err) + } + + tests := []struct { + name string + c *cleanup + expectErr bool + }{ + { + name: "awsmachines match EC2 instances", + c: &cleanup{ + awsClient: mockCleanupAWSClient{ + describeInstancesResp: &ec2.DescribeInstancesOutput{ + Reservations: []types.Reservation{ + { + Instances: []types.Instance{ + { + InstanceId: aws.String("i-0123456789"), + }, + }, + }, + }, + }, + }, + client: fake.NewClientBuilder().WithScheme(scheme).WithObjects(&capav1beta2.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "cluster.x-k8s.io/cluster-name": "0123456789", + }, + }, + Spec: capav1beta2.AWSMachineSpec{InstanceID: aws.String("i-0123456789")}, + }).Build(), + cluster: newTestCluster(t, cmv1.NewCluster().ID("0123456789")), + }, + }, + { + name: "leaked EC2 instances", + c: &cleanup{ + awsClient: mockCleanupAWSClient{ + describeInstancesResp: &ec2.DescribeInstancesOutput{ + Reservations: []types.Reservation{ + { + Instances: []types.Instance{ + { + InstanceId: aws.String("i-0123456789"), + }, + }, + }, + }, + }, + }, + client: fake.NewClientBuilder().WithScheme(scheme).Build(), + cluster: newTestCluster(t, cmv1.NewCluster().ID("0123456789")), + Yes: true, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := test.c.RemediateOCPBUGS23174(context.Background()) + if err != nil { + if !test.expectErr { + t.Errorf("expected no err, got %v", err) + } + } + + if test.expectErr { + t.Errorf("expected err, got nil") + } + }) + } +} diff --git a/cmd/cluster/cmd.go b/cmd/cluster/cmd.go index e938f149..088bcc0d 100644 --- a/cmd/cluster/cmd.go +++ b/cmd/cluster/cmd.go @@ -40,6 +40,7 @@ func NewCmdCluster(streams genericclioptions.IOStreams, client *k8s.LazyClient, clusterCmd.AddCommand(NewCmdHypershiftInfo(streams)) clusterCmd.AddCommand(newCmdOrgId()) clusterCmd.AddCommand(newCmdDynatraceURL()) + clusterCmd.AddCommand(newCmdCleanupLeakedEC2()) return clusterCmd } diff --git a/go.mod b/go.mod index be9da290..78325caf 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 - github.com/spf13/pflag v1.0.5 + github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace github.com/spf13/viper v1.18.2 go.uber.org/mock v0.3.0 golang.org/x/sync v0.5.0 @@ -58,6 +58,7 @@ require ( k8s.io/client-go v0.28.4 k8s.io/kubectl v0.28.4 k8s.io/utils v0.0.0-20230726121419-3b25d923346b + sigs.k8s.io/cluster-api-provider-aws/v2 v2.3.1 sigs.k8s.io/controller-runtime v0.16.3 sigs.k8s.io/yaml v1.4.0 ) @@ -83,6 +84,8 @@ require ( github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver v3.5.1+incompatible // indirect + github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect @@ -118,7 +121,7 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/css v1.0.0 // indirect - github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect + github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.15 // indirect @@ -133,7 +136,7 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/microcosm-cc/bluemonday v1.0.23 // indirect @@ -159,6 +162,7 @@ require ( github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.11.1 // indirect + github.com/rivo/uniseg v0.4.2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -196,6 +200,7 @@ require ( k8s.io/component-base v0.28.4 // indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e // indirect + sigs.k8s.io/cluster-api v1.5.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.15.0 // indirect sigs.k8s.io/kustomize/kyaml v0.15.0 // indirect diff --git a/go.sum b/go.sum index 40fca3c1..86d91a89 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,8 @@ github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-sdk-go v1.44.298 h1:5qTxdubgV7PptZJmp/2qDwD2JL187ePL7VOxsSh1i3g= +github.com/aws/aws-sdk-go v1.44.298/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU= github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.1 h1:ZY3108YtBNq96jNZTICHxN1gSBSbnvIdYwwqnvCV4Mc= @@ -94,6 +96,10 @@ github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd3 github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/brianvoe/gofakeit/v6 v6.24.0 h1:74yq7RRz/noddscZHRS2T84oHZisW9muwbb8sRnU52A= github.com/brianvoe/gofakeit/v6 v6.24.0/go.mod h1:Ow6qC71xtwm79anlwKRlWZW6zVq9D2XHE4QSSMP/rU8= @@ -188,6 +194,8 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEe github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= +github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= @@ -262,8 +270,8 @@ github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q= +github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -342,8 +350,9 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= @@ -444,6 +453,9 @@ github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdO github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= +github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -452,8 +464,8 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -469,8 +481,9 @@ github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace h1:9PNP1jnUjRhfmGMlkXHjYPishpcw4jpSt/V/xYY3FMA= +github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= @@ -758,6 +771,10 @@ k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/cluster-api v1.5.3 h1:TtxneDCps14sZ9bNr515ivBRMj9OwUE6mRUr6l7fSBA= +sigs.k8s.io/cluster-api v1.5.3/go.mod h1:0fMUk93Wf7AkQHIWLbDoKsiUHaMxnpqfLMlVmx8DX7Q= +sigs.k8s.io/cluster-api-provider-aws/v2 v2.3.1 h1:0HmdPYMYdgmPGETOMhQ0HQzVhDPmdExb/QBiR8YpV5A= +sigs.k8s.io/cluster-api-provider-aws/v2 v2.3.1/go.mod h1:dOX+I3KdLY3C1F0iPQQhV0Po2qPTO9sb6ogN8TOw5sY= sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= diff --git a/pkg/utils/ocm.go b/pkg/utils/ocm.go index c4d5e9ba..abc1d4bb 100644 --- a/pkg/utils/ocm.go +++ b/pkg/utils/ocm.go @@ -58,7 +58,7 @@ type Config struct { } // GetClusterAnyStatus returns an OCM cluster object given an OCM connection and cluster id -// (internal and external ids both supported). +// (internal id, external id, and name all supported). func GetClusterAnyStatus(conn *sdk.Connection, clusterId string) (*cmv1.Cluster, error) { // identifier in the accounts management service. To find those clusters we need to check // directly in the clusters management service.