Skip to content

Commit 5d56c1b

Browse files
committed
hcp mustgather; support MC/SC cluster IDs for --gather mc/sc
1 parent 2c25fb3 commit 5d56c1b

1 file changed

Lines changed: 115 additions & 27 deletions

File tree

cmd/hcp/mustgather/mustGather.go

Lines changed: 115 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import (
1818
"syscall"
1919
"time"
2020

21+
ocmsdk "github.com/openshift-online/ocm-sdk-go"
22+
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
2123
"github.com/openshift/osdctl/cmd/common"
2224
"github.com/openshift/osdctl/cmd/dynatrace"
2325
"github.com/openshift/osdctl/pkg/osdctlConfig"
@@ -45,7 +47,6 @@ func NewCmdMustGather() *cobra.Command {
4547
Long: "Create a must-gather for an HCP cluster with optional gather targets",
4648
Example: "osdctl hcp must-gather --cluster-id CLUSTER_ID --gather sc,mc,sc_acm --reason OHSS-1234",
4749
RunE: func(cmd *cobra.Command, args []string) error {
48-
4950
return mg.Run()
5051
},
5152
}
@@ -74,26 +75,6 @@ func (mg *mustGather) Run() error {
7475
return fmt.Errorf("failed to get OCM cluster info for %s: %s", mg.clusterId, err)
7576
}
7677

77-
mc, err := utils.GetManagementCluster(cluster.ID())
78-
if err != nil {
79-
return err
80-
}
81-
82-
sc, err := utils.GetServiceCluster(cluster.ID())
83-
if err != nil {
84-
return err
85-
}
86-
87-
_, mcRestCfg, mcK8sCli, err := common.GetKubeConfigAndClient(mc.ID(), mg.reason)
88-
if err != nil {
89-
return err
90-
}
91-
92-
_, scRestCfg, scK8sCli, err := common.GetKubeConfigAndClient(sc.ID(), mg.reason)
93-
if err != nil {
94-
return err
95-
}
96-
9778
// hack(typeid): work around backplane overwriting our config
9879
err = osdctlConfig.EnsureConfigFile()
9980
if err != nil {
@@ -107,7 +88,7 @@ func (mg *mustGather) Run() error {
10788
tarballName := fmt.Sprintf("cluster_dump_%s_%s.tar.gz", mg.clusterId, timestamp)
10889
outputTarballTmp := fmt.Sprintf("%s/%s", baseDir, tarballName)
10990
outputTarballPath := fmt.Sprintf("%s/%s", outputDir, tarballName)
110-
err = os.MkdirAll(outputDir, 0750)
91+
err = os.MkdirAll(outputDir, 0o750)
11192
if err != nil {
11293
return err
11394
}
@@ -118,7 +99,7 @@ func (mg *mustGather) Run() error {
11899

119100
// Progress tracking
120101
var completed sync.Map
121-
var totalGatherTargets = len(gatherTargets)
102+
totalGatherTargets := len(gatherTargets)
122103
go func() {
123104
ticker := time.NewTicker(30 * time.Second)
124105
defer ticker.Stop()
@@ -156,20 +137,40 @@ func (mg *mustGather) Run() error {
156137
switch gatherTarget {
157138
case "sc":
158139
destDir := outputDir + "/sc_infra"
140+
scRestCfg, scK8sCli, err := resolveSCRestConfig(ocmClient, cluster, mg.reason)
141+
if err != nil {
142+
fmt.Printf("failed to resolve service cluster for %s: %v\n", gatherTarget, err)
143+
return
144+
}
159145
if err := createMustGather(scRestCfg, scK8sCli, []string{"--dest-dir=" + destDir}); err != nil {
160146
fmt.Printf("failed to gather %s: %v\n", gatherTarget, err)
161147
}
162148
case "sc_acm":
163149
destDir := outputDir + "/sc_acm"
150+
scRestCfg, scK8sCli, err := resolveSCRestConfig(ocmClient, cluster, mg.reason)
151+
if err != nil {
152+
fmt.Printf("failed to resolve service cluster for %s: %v\n", gatherTarget, err)
153+
return
154+
}
164155
if err := createMustGather(scRestCfg, scK8sCli, []string{"--dest-dir=" + destDir, "--image=" + mg.acmMustGatherImage}); err != nil {
165156
fmt.Printf("failed to gather %s: %v\n", gatherTarget, err)
166157
}
167158
case "mc":
168159
destDir := outputDir + "/mc_infra"
160+
mcRestCfg, mcK8sCli, err := resolveMCRestConfig(ocmClient, cluster, mg.reason)
161+
if err != nil {
162+
fmt.Printf("failed to resolve management cluster for %s: %v\n", gatherTarget, err)
163+
return
164+
}
169165
if err := createMustGather(mcRestCfg, mcK8sCli, []string{"--dest-dir=" + destDir}); err != nil {
170166
fmt.Printf("failed to gather %s: %v\n", gatherTarget, err)
171167
}
172168
case "hcp":
169+
if !cluster.Hypershift().Enabled() {
170+
fmt.Printf("--gather hcp requires an HCP cluster ID; %s is not an HCP cluster\n", mg.clusterId)
171+
return
172+
}
173+
173174
destDir := outputDir + "/hcp"
174175

175176
// 1. Gather logs from DT
@@ -194,10 +195,14 @@ func (mg *mustGather) Run() error {
194195
hcName := cluster.DomainPrefix()
195196
hcNamespace := strings.TrimSuffix(hcpNamespace, "-"+hcName)
196197

197-
// TODO(ACM-16170): replace this with an official ACM release image once it's available
198-
acmHyperShiftImage := "quay.io/rokejungrh/must-gather:v2.13.0-33-linux"
198+
mcRestCfg, mcK8sCli, err := resolveMCRestConfig(ocmClient, cluster, mg.reason)
199+
if err != nil {
200+
fmt.Printf("gathered DT logs but failed to resolve MC for ACM must-gather: %v\n", err)
201+
return
202+
}
203+
199204
gatherScript := fmt.Sprintf("/usr/bin/gather hosted-cluster-namespace=%s hosted-cluster-name=%s", hcNamespace, hcName)
200-
if err := createMustGather(mcRestCfg, mcK8sCli, []string{"--dest-dir=" + destDir, "--image=" + acmHyperShiftImage, gatherScript}); err != nil {
205+
if err := createMustGather(mcRestCfg, mcK8sCli, []string{"--dest-dir=" + destDir, "--image=" + mg.acmMustGatherImage, gatherScript}); err != nil {
201206
fmt.Printf("collected HCP dynatrace logs but failed to gather %s: %v\n", gatherTarget, err.Error())
202207
}
203208

@@ -228,6 +233,90 @@ func (mg *mustGather) Run() error {
228233
return nil
229234
}
230235

236+
// resolveMCRestConfig returns the REST config and k8s client for the management cluster.
237+
func resolveMCRestConfig(ocmClient *ocmsdk.Connection, cluster *cmv1.Cluster, reason string) (*rest.Config, *kubernetes.Clientset, error) {
238+
mcID := cluster.ID()
239+
240+
if cluster.Hypershift().Enabled() {
241+
hypershiftResp, err := ocmClient.ClustersMgmt().V1().Clusters().
242+
Cluster(cluster.ID()).
243+
Hypershift().
244+
Get().
245+
Send()
246+
if err != nil {
247+
return nil, nil, fmt.Errorf("failed to get hypershift info for %s: %w", cluster.ID(), err)
248+
}
249+
250+
mgmtClusterName, ok := hypershiftResp.Body().GetManagementCluster()
251+
if !ok || mgmtClusterName == "" {
252+
return nil, nil, fmt.Errorf("no management cluster found for %s", cluster.ID())
253+
}
254+
255+
mc, err := utils.GetClusterAnyStatus(ocmClient, mgmtClusterName)
256+
if err != nil {
257+
return nil, nil, fmt.Errorf("failed to get management cluster %s: %w", mgmtClusterName, err)
258+
}
259+
mcID = mc.ID()
260+
}
261+
262+
_, restCfg, k8sCli, err := common.GetKubeConfigAndClientWithConn(mcID, ocmClient, reason)
263+
if err != nil {
264+
return nil, nil, fmt.Errorf("failed to get kubeconfig for management cluster %s: %w", mcID, err)
265+
}
266+
267+
return restCfg, k8sCli, nil
268+
}
269+
270+
// resolveSCRestConfig returns the REST config and k8s client for the service cluster.
271+
func resolveSCRestConfig(ocmClient *ocmsdk.Connection, cluster *cmv1.Cluster, reason string) (*rest.Config, *kubernetes.Clientset, error) {
272+
scID := cluster.ID()
273+
274+
if cluster.Hypershift().Enabled() {
275+
hypershiftResp, err := ocmClient.ClustersMgmt().V1().Clusters().
276+
Cluster(cluster.ID()).
277+
Hypershift().
278+
Get().
279+
Send()
280+
if err != nil {
281+
return nil, nil, fmt.Errorf("failed to get hypershift info for %s: %w", cluster.ID(), err)
282+
}
283+
284+
mgmtClusterName := hypershiftResp.Body().ManagementCluster()
285+
if mgmtClusterName == "" {
286+
return nil, nil, fmt.Errorf("failed to lookup management cluster for cluster %s", cluster.ID())
287+
}
288+
289+
ofmResp, err := ocmClient.OSDFleetMgmt().V1().ManagementClusters().
290+
List().
291+
Parameter("search", fmt.Sprintf("name='%s'", mgmtClusterName)).
292+
Send()
293+
if err != nil {
294+
return nil, nil, fmt.Errorf("failed to get fleet manager info for management cluster %s: %w", mgmtClusterName, err)
295+
}
296+
297+
var svcClusterName string
298+
if kind := ofmResp.Items().Get(0).Parent().Kind(); kind == "ServiceCluster" {
299+
svcClusterName = ofmResp.Items().Get(0).Parent().Name()
300+
}
301+
if svcClusterName == "" {
302+
return nil, nil, fmt.Errorf("no service cluster found for management cluster %s", mgmtClusterName)
303+
}
304+
305+
sc, err := utils.GetClusterAnyStatus(ocmClient, svcClusterName)
306+
if err != nil {
307+
return nil, nil, fmt.Errorf("failed to get service cluster %s: %w", svcClusterName, err)
308+
}
309+
scID = sc.ID()
310+
}
311+
312+
_, restCfg, k8sCli, err := common.GetKubeConfigAndClientWithConn(scID, ocmClient, reason)
313+
if err != nil {
314+
return nil, nil, fmt.Errorf("failed to get kubeconfig for service cluster %s: %w", scID, err)
315+
}
316+
317+
return restCfg, k8sCli, nil
318+
}
319+
231320
func createMustGather(restCfg *rest.Config, k8sCli *kubernetes.Clientset, additionalFlags []string) error {
232321
// We used to run this programatically by directly using the must-gather package (see https://github.com/openshift/osdctl/pull/660)
233322
// from the oc cli, but decided to opt for oc.Exec instead.
@@ -379,7 +468,6 @@ func createTarball(sourceDir, tarballName string) error {
379468

380469
return nil
381470
})
382-
383471
if err != nil {
384472
return fmt.Errorf("error walking source directory: %v", err)
385473
}

0 commit comments

Comments
 (0)