Skip to content

Commit 6c7cc90

Browse files
authored
NO-JIRA: gather only in-use MachineConfigs (openshift#992)
* gather only in-use MachineConfigs * describe the change in docs
1 parent 53d9627 commit 6c7cc90

File tree

94 files changed

+12209
-88
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+12209
-88
lines changed

docs/gathered-data.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,10 @@ None
10771077

10781078
## MachineConfigs
10791079

1080-
Collects `MachineConfigs` definitions. Following data is intentionally removed from the definitions:
1080+
Collects definitions of in-use 'MachineConfigs'. MachineConfig is used when it's referenced in
1081+
a MachineConfigPool or in Node `machineconfiguration.openshift.io/desiredConfig` and `machineconfiguration.openshift.io/currentConfig`
1082+
annotations
1083+
Following data is intentionally removed from the definitions:
10811084
- `spec.config.storage.files`
10821085
- `spec.config.passwd.users`
10831086

@@ -1100,7 +1103,7 @@ Collects `MachineConfigs` definitions. Following data is intentionally removed f
11001103
- 4.8.5
11011104

11021105
### Changes
1103-
None
1106+
- gathers only in-use MachineConfigs since 4.18+
11041107

11051108

11061109
## MachineHealthCheck

pkg/gatherers/clusterconfig/gather_machine_configs.go

+69-5
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,20 @@ import (
77
"k8s.io/apimachinery/pkg/api/errors"
88
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
99
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
10+
"k8s.io/apimachinery/pkg/util/sets"
1011
"k8s.io/client-go/dynamic"
12+
"k8s.io/client-go/kubernetes"
13+
"k8s.io/client-go/rest"
1114
"k8s.io/klog/v2"
1215

16+
mcfgclientset "github.com/openshift/client-go/machineconfiguration/clientset/versioned"
1317
"github.com/openshift/insights-operator/pkg/record"
1418
)
1519

16-
// GatherMachineConfigs Collects `MachineConfigs` definitions. Following data is intentionally removed from the definitions:
20+
// GatherMachineConfigs Collects definitions of in-use 'MachineConfigs'. MachineConfig is used when it's referenced in
21+
// a MachineConfigPool or in Node `machineconfiguration.openshift.io/desiredConfig` and `machineconfiguration.openshift.io/currentConfig`
22+
// annotations
23+
// Following data is intentionally removed from the definitions:
1724
// - `spec.config.storage.files`
1825
// - `spec.config.passwd.users`
1926
//
@@ -36,28 +43,40 @@ import (
3643
// - 4.8.5
3744
//
3845
// ### Changes
39-
// None
46+
// - gathers only in-use MachineConfigs since 4.18+
4047
func (g *Gatherer) GatherMachineConfigs(ctx context.Context) ([]record.Record, []error) {
4148
gatherDynamicClient, err := dynamic.NewForConfig(g.gatherKubeConfig)
4249
if err != nil {
4350
return nil, []error{err}
4451
}
45-
46-
return gatherMachineConfigs(ctx, gatherDynamicClient)
52+
var errs []error
53+
inUseMachineConfigs, err := getInUseMachineConfigs(ctx, g.gatherKubeConfig)
54+
if err != nil {
55+
errs = append(errs, err)
56+
}
57+
records, gatherErrs := gatherMachineConfigs(ctx, gatherDynamicClient, inUseMachineConfigs)
58+
errs = append(errs, gatherErrs...)
59+
return records, errs
4760
}
4861

49-
func gatherMachineConfigs(ctx context.Context, dynamicClient dynamic.Interface) ([]record.Record, []error) {
62+
func gatherMachineConfigs(ctx context.Context, dynamicClient dynamic.Interface,
63+
inUseMachineConfigs sets.Set[string]) ([]record.Record, []error) {
5064
mcList, err := dynamicClient.Resource(machineConfigGroupVersionResource).List(ctx, metav1.ListOptions{})
5165
if errors.IsNotFound(err) {
5266
return nil, nil
5367
}
5468
if err != nil {
5569
return nil, []error{err}
5670
}
71+
5772
records := []record.Record{}
5873
var errs []error
5974
for i := range mcList.Items {
6075
mc := mcList.Items[i]
76+
// skip machine configs which are not in use
77+
if len(inUseMachineConfigs) != 0 && !inUseMachineConfigs.Has(mc.GetName()) {
78+
continue
79+
}
6180
// remove the sensitive content by overwriting the values
6281
err := unstructured.SetNestedField(mc.Object, nil, "spec", "config", "storage", "files")
6382
if err != nil {
@@ -79,3 +98,48 @@ func gatherMachineConfigs(ctx context.Context, dynamicClient dynamic.Interface)
7998
}
8099
return records, nil
81100
}
101+
102+
// GetInUseMachineConfigs filters in-use MachineConfig resources and returns set of their names.
103+
func getInUseMachineConfigs(ctx context.Context, clientConfig *rest.Config) (sets.Set[string], error) {
104+
// Create a set to store in-use configs
105+
inuseConfigs := sets.New[string]()
106+
107+
machineConfigClient, err := mcfgclientset.NewForConfig(clientConfig)
108+
if err != nil {
109+
return nil, err
110+
}
111+
112+
poolList, err := machineConfigClient.MachineconfigurationV1().MachineConfigPools().List(ctx, metav1.ListOptions{})
113+
if err != nil {
114+
return nil, fmt.Errorf("getting MachineConfigPools failed: %w", err)
115+
}
116+
117+
for i := range poolList.Items {
118+
pool := poolList.Items[i]
119+
// Get the rendered config name from the status section
120+
inuseConfigs.Insert(pool.Status.Configuration.Name)
121+
inuseConfigs.Insert(pool.Spec.Configuration.Name)
122+
}
123+
124+
kubeClient, err := kubernetes.NewForConfig(clientConfig)
125+
if err != nil {
126+
return nil, err
127+
}
128+
nodeList, err := kubeClient.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
129+
if err != nil {
130+
return nil, err
131+
}
132+
for i := range nodeList.Items {
133+
node := nodeList.Items[i]
134+
current, ok := node.Annotations["machineconfiguration.openshift.io/currentConfig"]
135+
if ok {
136+
inuseConfigs.Insert(current)
137+
}
138+
desired, ok := node.Annotations["machineconfiguration.openshift.io/desiredConfig"]
139+
if ok {
140+
inuseConfigs.Insert(desired)
141+
}
142+
}
143+
144+
return inuseConfigs, nil
145+
}

pkg/gatherers/clusterconfig/gather_machine_configs_test.go

+86-81
Original file line numberDiff line numberDiff line change
@@ -4,113 +4,118 @@ import (
44
"context"
55
"testing"
66

7+
"github.com/stretchr/testify/assert"
78
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
89
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
910
"k8s.io/apimachinery/pkg/runtime"
1011
"k8s.io/apimachinery/pkg/runtime/schema"
1112
"k8s.io/apimachinery/pkg/runtime/serializer/yaml"
13+
"k8s.io/apimachinery/pkg/util/sets"
1214
"k8s.io/client-go/dynamic"
1315
dynamicfake "k8s.io/client-go/dynamic/fake"
1416
)
1517

16-
func createMockConfigMachine(t *testing.T, c dynamic.Interface, data string) {
18+
func createMockConfigMachine(ctx context.Context, c dynamic.Interface, data string) error {
1719
decUnstructured1 := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme)
1820
testMachineConfig := &unstructured.Unstructured{}
1921
_, _, err := decUnstructured1.Decode([]byte(data), nil, testMachineConfig)
2022
if err != nil {
21-
t.Fatal("unable to decode MachineConfig YAML", err)
23+
return err
2224
}
2325

24-
_, _ = c.
26+
_, err = c.
2527
Resource(machineConfigGroupVersionResource).
26-
Create(context.Background(), testMachineConfig, metav1.CreateOptions{})
27-
}
28-
29-
func Test_MachineConfigs(t *testing.T) {
30-
// Initialize the fake dynamic client.
31-
machineConfigClient := dynamicfake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), map[schema.GroupVersionResource]string{
32-
machineConfigGroupVersionResource: "MachineConfigsList",
33-
})
34-
35-
records, errs := gatherMachineConfigs(context.Background(), machineConfigClient)
36-
if len(errs) > 0 {
37-
t.Fatalf("unexpected errors: %#v", errs)
38-
}
39-
// 0 records because there is no MachineConfigs yet.
40-
if len(records) != 0 {
41-
t.Fatalf("unexpected number or records in the first run: %d", len(records))
28+
Create(ctx, testMachineConfig, metav1.CreateOptions{})
29+
if err != nil {
30+
return err
4231
}
32+
return nil
33+
}
4334

44-
// Create first MachineConfig resource.
45-
machineConfigYAML1 := `apiVersion: machineconfiguration.openshift.io/v1
35+
func TestGatherMachineConfigs(t *testing.T) {
36+
tests := []struct {
37+
name string
38+
machineConfigYAMLs []string
39+
inUseMachineConfigs sets.Set[string]
40+
expectedNumberOfRecords int
41+
}{
42+
{
43+
name: "no machine configs exists",
44+
machineConfigYAMLs: []string{},
45+
inUseMachineConfigs: sets.Set[string]{},
46+
expectedNumberOfRecords: 0,
47+
},
48+
{
49+
name: "one machine config which is in use",
50+
machineConfigYAMLs: []string{
51+
`apiVersion: machineconfiguration.openshift.io/v1
52+
kind: MachineConfig
53+
metadata:
54+
name: 75-worker-sap-data-intelligence`},
55+
inUseMachineConfigs: sets.Set[string]{"75-worker-sap-data-intelligence": {}},
56+
expectedNumberOfRecords: 1,
57+
},
58+
{
59+
name: "two machine configs but only one in use",
60+
expectedNumberOfRecords: 1,
61+
machineConfigYAMLs: []string{
62+
`apiVersion: machineconfiguration.openshift.io/v1
4663
kind: MachineConfig
4764
metadata:
48-
name: 75-worker-sap-data-intelligence
49-
`
50-
51-
createMockConfigMachine(t, machineConfigClient, machineConfigYAML1)
52-
records, errs = gatherMachineConfigs(context.Background(), machineConfigClient)
53-
if len(errs) > 0 {
54-
t.Fatalf("unexpected errors: %#v", errs)
55-
}
56-
// 1 record because there is now 1 MachineConfig resource.
57-
if len(records) != 1 {
58-
t.Fatalf("unexpected number or records in the second run: %d", len(records))
59-
}
60-
61-
// Create second MachineConfig resource.
62-
machineConfigYAML2 := `apiVersion: machineconfiguration.openshift.io/v1
65+
name: test-not-in-use`,
66+
`apiVersion: machineconfiguration.openshift.io/v1
6367
kind: MachineConfig
6468
metadata:
65-
name: 75-master-sap-data-intelligence
66-
`
67-
68-
createMockConfigMachine(t, machineConfigClient, machineConfigYAML2)
69-
records, errs = gatherMachineConfigs(context.Background(), machineConfigClient)
70-
if len(errs) > 0 {
71-
t.Fatalf("unexpected errors: %#v", errs)
72-
}
73-
// 2 record because there are now 2 MachineConfig resource.
74-
if len(records) != 2 {
75-
t.Fatalf("unexpected number or records in the third run: %d", len(records))
76-
}
77-
78-
// Create third MachineConfig resource.
79-
machineConfigYAML3 := `apiVersion: machineconfiguration.openshift.io/v1
69+
name: in-use`,
70+
},
71+
inUseMachineConfigs: sets.Set[string]{"in-use": {}},
72+
},
73+
{
74+
name: "no machine config in use",
75+
expectedNumberOfRecords: 0,
76+
machineConfigYAMLs: []string{
77+
`apiVersion: machineconfiguration.openshift.io/v1
8078
kind: MachineConfig
8179
metadata:
82-
name: 99-sdi-generated-containerruntime
83-
ownerReferences:
84-
- kind: ContainerRuntimeConfig
85-
name: sdi-pids-limit
86-
`
87-
88-
createMockConfigMachine(t, machineConfigClient, machineConfigYAML3)
89-
records, errs = gatherMachineConfigs(context.Background(), machineConfigClient)
90-
if len(errs) > 0 {
91-
t.Fatalf("unexpected errors: %#v", errs)
92-
}
93-
// 3 record because there are now 3 MachineConfig resource.
94-
if len(records) != 3 {
95-
t.Fatalf("unexpected number or records in the fourth run: %d", len(records))
96-
}
97-
98-
// Create fourth MachineConfig resource.
99-
machineConfigYAML4 := `apiVersion: machineconfiguration.openshift.io/v1
80+
name: test-not-in-use-1`,
81+
`apiVersion: machineconfiguration.openshift.io/v1
10082
kind: MachineConfig
10183
metadata:
102-
name: 00-example-machine-config
103-
labels:
104-
workload: sap-data-intelligence
105-
`
106-
107-
createMockConfigMachine(t, machineConfigClient, machineConfigYAML4)
108-
records, errs = gatherMachineConfigs(context.Background(), machineConfigClient)
109-
if len(errs) > 0 {
110-
t.Fatalf("unexpected errors: %#v", errs)
84+
name: test-not-in-use-2`,
85+
},
86+
inUseMachineConfigs: sets.Set[string]{"in-use": {}, "in-use-2": {}},
87+
},
88+
{
89+
name: "two machine configs in use",
90+
expectedNumberOfRecords: 2,
91+
machineConfigYAMLs: []string{
92+
`apiVersion: machineconfiguration.openshift.io/v1
93+
kind: MachineConfig
94+
metadata:
95+
name: in-use-1`,
96+
`apiVersion: machineconfiguration.openshift.io/v1
97+
kind: MachineConfig
98+
metadata:
99+
name: in-use-2`,
100+
},
101+
inUseMachineConfigs: sets.Set[string]{"in-use-1": {}, "in-use-2": {}},
102+
},
111103
}
112-
// 4 record because there are now 4 MachineConfig resource.
113-
if len(records) != 4 {
114-
t.Fatalf("unexpected number or records in the fifth run: %d", len(records))
104+
105+
for _, tt := range tests {
106+
t.Run(tt.name, func(t *testing.T) {
107+
ctx := context.Background()
108+
// Initialize the fake dynamic client.
109+
machineConfigClient := dynamicfake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), map[schema.GroupVersionResource]string{
110+
machineConfigGroupVersionResource: "MachineConfigsList",
111+
})
112+
for _, mcYAML := range tt.machineConfigYAMLs {
113+
err := createMockConfigMachine(ctx, machineConfigClient, mcYAML)
114+
assert.NoError(t, err)
115+
}
116+
records, errs := gatherMachineConfigs(ctx, machineConfigClient, tt.inUseMachineConfigs)
117+
assert.Len(t, errs, 0)
118+
assert.Len(t, records, tt.expectedNumberOfRecords)
119+
})
115120
}
116121
}

vendor/github.com/openshift/api/machineconfiguration/v1/Makefile

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/openshift/api/machineconfiguration/v1/doc.go

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)