Skip to content

Commit 59a73a5

Browse files
committed
feat(must gather): include configmaps and add option to write output to a file
1 parent b224117 commit 59a73a5

File tree

4 files changed

+129
-39
lines changed

4 files changed

+129
-39
lines changed

rhoc/pkg/cmd/must_gather/must_gather.go

Lines changed: 80 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
package must_gather
22

33
import (
4+
"bufio"
5+
"errors"
46
"fmt"
5-
"github.com/bf2fc6cc711aee1a0c2a/cos-tools/rhoc/pkg/util/kubernetes/pods"
6-
"github.com/bf2fc6cc711aee1a0c2a/cos-tools/rhoc/pkg/util/kubernetes/resources"
7-
"gopkg.in/yaml.v3"
8-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9-
"k8s.io/apimachinery/pkg/runtime/schema"
7+
"io"
108
"os"
119

1210
"github.com/bf2fc6cc711aee1a0c2a/cos-tools/rhoc/pkg/util/cmdutil"
11+
"github.com/bf2fc6cc711aee1a0c2a/cos-tools/rhoc/pkg/util/kubernetes/pods"
12+
"github.com/bf2fc6cc711aee1a0c2a/cos-tools/rhoc/pkg/util/kubernetes/resources"
1313
"github.com/redhat-developer/app-services-cli/pkg/shared/factory"
14+
1415
"github.com/spf13/cobra"
16+
"gopkg.in/yaml.v3"
1517

18+
"k8s.io/apimachinery/pkg/runtime/schema"
1619
"k8s.io/cli-runtime/pkg/genericclioptions"
1720
"k8s.io/cli-runtime/pkg/printers"
1821
"k8s.io/client-go/discovery"
@@ -24,6 +27,7 @@ import (
2427
type options struct {
2528
id string
2629
logs bool
30+
file string
2731
resources []string
2832
gvrs []schema.GroupVersionResource
2933
f *factory.Factory
@@ -73,62 +77,101 @@ func NewMustGatherCommand(f *factory.Factory) *cobra.Command {
7377
}
7478
}
7579

76-
ulist := make([]map[string]interface{}, 0)
80+
for i := range opts.gvrs {
81+
// exclude secrets
82+
if opts.gvrs[i].Group == "" && opts.gvrs[i].Version == "v1" && opts.gvrs[i].Resource == "secrets" {
83+
opts.gvrs[i].Group = ""
84+
opts.gvrs[i].Version = ""
85+
opts.gvrs[i].Resource = ""
86+
}
87+
}
88+
89+
var o io.Writer
90+
var mustClose bool
91+
92+
if opts.file == "" {
93+
o = f.IOStreams.Out
94+
mustClose = false
95+
} else {
96+
f, err := os.Create(opts.file)
97+
if err != nil {
98+
return err
99+
}
100+
101+
o = f
102+
mustClose = true
103+
}
104+
105+
out := bufio.NewWriter(o)
106+
defer func() {
107+
_ = out.Flush()
77108

78-
for _, gvr := range opts.gvrs {
109+
if mustClose {
110+
if c, ok := o.(io.Closer); ok {
111+
_ = c.Close()
112+
}
113+
}
114+
}()
115+
116+
items, err := resources.List(f.Context, dynamicClient, opts.gvrs, opts.id)
117+
if err != nil {
118+
return err
119+
}
79120

80-
resList, err := dynamicClient.Resource(gvr).List(f.Context, metav1.ListOptions{
81-
LabelSelector: "cos.bf2.org/connector.id=" + opts.id,
82-
})
121+
if len(items) != 0 {
122+
raw, err := yaml.Marshal(items)
83123
if err != nil {
84124
return err
85125
}
86126

87-
for _, res := range resList.Items {
88-
switch {
89-
case res.GetAPIVersion() == "v1" && res.GetKind() == "Secret":
90-
continue
91-
case res.GetAPIVersion() == "v1" && res.GetKind() == "ConfigMap":
92-
continue
93-
default:
94-
fmt.Printf("Gathering -> %s:%s\n", res.GetAPIVersion(), gvr.Resource)
127+
_, err = out.Write(raw)
128+
if err != nil {
129+
return err
130+
}
131+
}
95132

96-
// remove managed fields as they are only making noise
97-
res.SetManagedFields(nil)
133+
if opts.logs {
134+
for _, item := range items {
135+
if item.GetAPIVersion() == "v1" && item.GetKind() == "Pod" {
136+
containers, err := pods.ListContainers(f.Context, client, item.GetNamespace(), item.GetName())
137+
if err != nil {
138+
return err
139+
}
98140

99-
ulist = append(ulist, res.Object)
141+
for _, container := range containers {
142+
_, err = fmt.Fprintf(
143+
out,
144+
"%s/%s:%s:%s@%s\n",
145+
item.GetAPIVersion(),
146+
item.GetKind(),
147+
item.GetNamespace(),
148+
item.GetName(),
149+
container)
100150

101-
if res.GetAPIVersion() == "v1" && res.GetKind() == "Pod" && opts.logs {
102-
containers, err := pods.ListContainers(f.Context, client, res.GetNamespace(), res.GetName())
103151
if err != nil {
104152
return err
105153
}
106154

107-
for _, container := range containers {
108-
err := pods.Logs(f.Context, client, res.GetNamespace(), res.GetName(), container, os.Stdout)
109-
if err != nil {
110-
return err
111-
}
155+
err := pods.Logs(f.Context, client, item.GetNamespace(), item.GetName(), container, out)
156+
if err != nil && !errors.Is(err, io.EOF) {
157+
return err
112158
}
113159
}
114-
}
115-
}
116-
}
117160

118-
if len(ulist) != 0 {
119-
out, err := yaml.Marshal(ulist)
120-
if err != nil {
121-
return err
161+
_, err = out.Write([]byte{'\n'})
162+
if err != nil {
163+
return err
164+
}
165+
}
122166
}
123-
124-
fmt.Println(string(out))
125167
}
126168

127169
return nil
128170
},
129171
}
130172

131173
cmdutil.AddID(cmd, &opts.id).Required()
174+
cmdutil.AddFile(cmd, &opts.file)
132175

133176
cmd.Flags().BoolVar(&opts.logs, "logs", opts.logs, "Include logs")
134177
cmd.Flags().StringSliceVar(&opts.resources, "resource", nil, "resources to include apiVersion:plural")

rhoc/pkg/util/cmdutil/cmdutil.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,19 @@ func AddRevision(cmd *cobra.Command, output *int64) *FlagOptions {
351351
return withFlagOptions(cmd, name)
352352
}
353353

354+
func AddFile(cmd *cobra.Command, output *string) *FlagOptions {
355+
name := "file"
356+
357+
cmd.Flags().StringVar(
358+
output,
359+
name,
360+
"",
361+
"file",
362+
)
363+
364+
return withFlagOptions(cmd, name)
365+
}
366+
354367
func withFlagOptions(cmd *cobra.Command, flagName string) *FlagOptions {
355368
options := FlagOptions{}
356369

rhoc/pkg/util/kubernetes/pods/pods.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ func Logs(ctx context.Context, client kubernetes.Interface, namespace string, na
4848
for {
4949
data, err := reader.ReadBytes('\n')
5050
if errors.Is(err, io.EOF) {
51-
return err
51+
return nil
5252
}
5353
if err != nil {
54-
break
54+
return err
5555
}
5656

5757
data = re.ReplaceAll(data, empty)

rhoc/pkg/util/kubernetes/resources/resources.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package resources
22

33
import (
4+
"context"
45
"github.com/bf2fc6cc711aee1a0c2a/cos-tools/rhoc/pkg/util/collections"
6+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
58
"k8s.io/apimachinery/pkg/runtime/schema"
69
"k8s.io/client-go/discovery"
10+
"k8s.io/client-go/dynamic"
711
"strings"
812
)
913

@@ -62,3 +66,33 @@ func Parse(resources []string) ([]schema.GroupVersionResource, error) {
6266

6367
return answer, nil
6468
}
69+
70+
func List(ctx context.Context, client dynamic.Interface, resources []schema.GroupVersionResource, connectorId string) ([]unstructured.Unstructured, error) {
71+
items := make([]unstructured.Unstructured, 0)
72+
73+
for _, gvr := range resources {
74+
75+
if gvr.Resource == "" {
76+
continue
77+
}
78+
79+
resList, err := client.Resource(gvr).List(ctx, metav1.ListOptions{
80+
LabelSelector: "cos.bf2.org/connector.id=" + connectorId,
81+
})
82+
if err != nil {
83+
return nil, err
84+
}
85+
86+
//case item.GetAPIVersion() == "v1" && item.GetKind() == "Secret":
87+
//continue
88+
89+
for i := range resList.Items {
90+
// remove managed fields as they are only making noise
91+
resList.Items[i].SetManagedFields(nil)
92+
93+
items = append(items, resList.Items[i])
94+
}
95+
}
96+
97+
return items, nil
98+
}

0 commit comments

Comments
 (0)