Skip to content

Commit 98cf795

Browse files
committed
hcp mustgather; support MC/SC cluster IDs for --gather mc/sc
1 parent a96132f commit 98cf795

1 file changed

Lines changed: 114 additions & 24 deletions

File tree

cmd/hcp/mustgather/mustGather.go

Lines changed: 114 additions & 24 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
}
@@ -75,26 +76,6 @@ func (mg *mustGather) Run() error {
7576
return fmt.Errorf("failed to get OCM cluster info for %s: %s", mg.clusterId, err)
7677
}
7778

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

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

176177
// 1. Gather logs from DT
@@ -195,6 +196,12 @@ func (mg *mustGather) Run() error {
195196
hcName := cluster.DomainPrefix()
196197
hcNamespace := strings.TrimSuffix(hcpNamespace, "-"+hcName)
197198

199+
mcRestCfg, mcK8sCli, err := resolveMCRestConfig(ocmClient, cluster, mg.reason)
200+
if err != nil {
201+
fmt.Printf("gathered DT logs but failed to resolve MC for ACM must-gather: %v\n", err)
202+
return
203+
}
204+
198205
gatherScript := fmt.Sprintf("/usr/bin/gather hosted-cluster-namespace=%s hosted-cluster-name=%s", hcNamespace, hcName)
199206
if err := createMustGather(mcRestCfg, mcK8sCli, []string{"--dest-dir=" + destDir, "--image=" + mg.acmMustGatherImage, gatherScript}); err != nil {
200207
fmt.Printf("collected HCP dynatrace logs but failed to gather %s: %v\n", gatherTarget, err.Error())
@@ -227,6 +234,90 @@ func (mg *mustGather) Run() error {
227234
return nil
228235
}
229236

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

379470
return nil
380471
})
381-
382472
if err != nil {
383473
return fmt.Errorf("error walking source directory: %v", err)
384474
}

0 commit comments

Comments
 (0)