Skip to content

Commit 9f5367d

Browse files
committed
operator: add admin_ack unit tests
1 parent ec75d6e commit 9f5367d

File tree

5 files changed

+220
-2
lines changed

5 files changed

+220
-2
lines changed

pkg/apihelpers/apihelpers.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,3 +486,13 @@ func CheckNodeDisruptionActionsForTargetActions(actions []opv1.NodeDisruptionPol
486486

487487
return currentActions.HasAny(targetActions...)
488488
}
489+
490+
// Returns a MachineConfiguration object with the cluster opted out of boot image updates.
491+
func GetManagedBootImagesWithUpdateDisabled() opv1.ManagedBootImages {
492+
return opv1.ManagedBootImages{MachineManagers: []opv1.MachineManager{}}
493+
}
494+
495+
// Returns a MachineConfiguration object with an empty configuration; to be used in testing a situation where admin has no opinion.
496+
func GetManagedBootImagesWithNoConfiguration() opv1.ManagedBootImages {
497+
return opv1.ManagedBootImages{}
498+
}

pkg/operator/admin_ack.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ import (
1717

1818
const (
1919
BootImageAWSGCPKey = "ack-4.18-boot-image-opt-out-in-4.19"
20-
BootImageAWSGCPMsg = "GCP or AWS platform with no boot image configuration detected. OCP will automatically opt-in all GCP and AWS clusters that currently do not a boot image configuration in 4.19. Please add a configuration to disable boot image updates if this is not desired. See [insert-doc-link] "
20+
BootImageAWSGCPMsg = "GCP or AWS platform with no boot image configuration detected. OCP will automatically opt-in all GCP and AWS clusters that currently do not a boot image configuration in 4.19. Please add a configuration to disable boot image updates if this is not desired. See https://docs.redhat.com/en/documentation/openshift_container_platform/4.18/html/machine_configuration/mco-update-boot-images#mco-update-boot-images for more details."
2121

2222
AArch64BootImageKey = "ack-4.18-aarch64-bootloader-4.19"
23-
AArch64BootImageMsg = "aarch64 nodes detected. Please ensure boot image are updated by following the KCS:(insertlink) prior to upgrading to 4.19."
23+
AArch64BootImageMsg = "aarch64 nodes detected. Please ensure boot images are not too old by following KCS https://access.redhat.com/solutions/7119697 prior to upgrading to 4.19."
2424

2525
AdminAckGatesConfigMapName = "admin-gates"
2626
)

pkg/operator/admin_ack_test.go

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package operator
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
configv1 "github.com/openshift/api/config/v1"
8+
opv1 "github.com/openshift/api/operator/v1"
9+
configlistersv1 "github.com/openshift/client-go/config/listers/config/v1"
10+
mcoplistersv1 "github.com/openshift/client-go/operator/listers/operator/v1"
11+
"github.com/openshift/machine-config-operator/pkg/apihelpers"
12+
ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common"
13+
"github.com/stretchr/testify/assert"
14+
corev1 "k8s.io/api/core/v1"
15+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+
"k8s.io/client-go/kubernetes/fake"
17+
corelisterv1 "k8s.io/client-go/listers/core/v1"
18+
"k8s.io/client-go/tools/cache"
19+
)
20+
21+
func TestAdminAck(t *testing.T) {
22+
cases := []struct {
23+
name string
24+
infra *configv1.Infrastructure
25+
mcop *opv1.MachineConfiguration
26+
adminCM *corev1.ConfigMap
27+
node *corev1.Node
28+
expectBootImageGate bool
29+
expectAArch64Gate bool
30+
}{
31+
{
32+
name: "non AWS/GCP platform, with no boot image configuration",
33+
infra: buildInfra(withPlatformType(configv1.AzurePlatformType)),
34+
mcop: buildMachineConfigurationWithNoBootImageConfiguration(),
35+
adminCM: buildAdminAckConfigMapWithData(nil),
36+
},
37+
{
38+
name: "AWS platform, with no boot image configuration",
39+
infra: buildInfra(withPlatformType(configv1.AWSPlatformType)),
40+
mcop: buildMachineConfigurationWithNoBootImageConfiguration(),
41+
adminCM: buildAdminAckConfigMapWithData(nil),
42+
expectBootImageGate: true,
43+
},
44+
{
45+
name: "GCP platform, with no boot image configuration",
46+
infra: buildInfra(withPlatformType(configv1.GCPPlatformType)),
47+
mcop: buildMachineConfigurationWithNoBootImageConfiguration(),
48+
adminCM: buildAdminAckConfigMapWithData(nil),
49+
expectBootImageGate: true,
50+
},
51+
{
52+
name: "non AWS/GCP platform, with a boot image configuration",
53+
infra: buildInfra(withPlatformType(configv1.AzurePlatformType)),
54+
mcop: buildMachineConfigurationWithBootImageUpdateDisabled(),
55+
adminCM: buildAdminAckConfigMapWithData(nil),
56+
},
57+
{
58+
name: "AWS platform, with a boot image configuration",
59+
infra: buildInfra(withPlatformType(configv1.AWSPlatformType)),
60+
mcop: buildMachineConfigurationWithBootImageUpdateDisabled(),
61+
adminCM: buildAdminAckConfigMapWithData(map[string]string{BootImageAWSGCPKey: BootImageAWSGCPMsg}),
62+
},
63+
{
64+
name: "GCP platform, with a boot image configuration",
65+
infra: buildInfra(withPlatformType(configv1.GCPPlatformType)),
66+
mcop: buildMachineConfigurationWithBootImageUpdateDisabled(),
67+
adminCM: buildAdminAckConfigMapWithData(map[string]string{BootImageAWSGCPKey: BootImageAWSGCPMsg}),
68+
},
69+
{
70+
name: "aarch64 Nodes present",
71+
infra: buildInfra(withPlatformType(configv1.GCPPlatformType)),
72+
mcop: buildMachineConfigurationWithBootImageUpdateDisabled(),
73+
adminCM: buildAdminAckConfigMapWithData(nil),
74+
node: buildNodeWithArch("arm64"),
75+
expectAArch64Gate: true,
76+
},
77+
{
78+
name: "aarch64 Nodes not present",
79+
infra: buildInfra(withPlatformType(configv1.GCPPlatformType)),
80+
mcop: buildMachineConfigurationWithBootImageUpdateDisabled(),
81+
adminCM: buildAdminAckConfigMapWithData(nil),
82+
node: buildNodeWithArch("amd64"),
83+
},
84+
}
85+
for _, tc := range cases {
86+
t.Run(tc.name, func(t *testing.T) {
87+
t.Parallel()
88+
89+
// Create clients and listers
90+
kubeClient := fake.NewSimpleClientset()
91+
infraIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
92+
infraIndexer.Add(tc.infra)
93+
mcopIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
94+
mcopIndexer.Add(tc.mcop)
95+
96+
configMapIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
97+
configMapIndexer.Add(tc.adminCM)
98+
_, err := kubeClient.CoreV1().ConfigMaps(ctrlcommon.OpenshiftConfigManagedNamespace).Create(context.TODO(), tc.adminCM, metav1.CreateOptions{})
99+
assert.NoError(t, err)
100+
101+
nodeIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
102+
if tc.node != nil {
103+
nodeIndexer.Add(tc.node)
104+
_, err = kubeClient.CoreV1().Nodes().Create(context.TODO(), tc.node, metav1.CreateOptions{})
105+
assert.NoError(t, err)
106+
}
107+
108+
optr := &Operator{
109+
kubeClient: kubeClient,
110+
infraLister: configlistersv1.NewInfrastructureLister(infraIndexer),
111+
mcopLister: mcoplistersv1.NewMachineConfigurationLister(mcopIndexer),
112+
ocManagedConfigMapLister: corelisterv1.NewConfigMapLister(configMapIndexer),
113+
nodeLister: corelisterv1.NewNodeLister(nodeIndexer),
114+
}
115+
err = optr.syncAdminAckConfigMap()
116+
assert.NoError(t, err)
117+
118+
adminCM, err := kubeClient.CoreV1().ConfigMaps(ctrlcommon.OpenshiftConfigManagedNamespace).Get(context.TODO(), AdminAckGatesConfigMapName, metav1.GetOptions{})
119+
assert.NoError(t, err)
120+
121+
_, gateFound := adminCM.Data[BootImageAWSGCPKey]
122+
assert.Equal(t, tc.expectBootImageGate, gateFound)
123+
124+
_, gateFound = adminCM.Data[AArch64BootImageKey]
125+
assert.Equal(t, tc.expectAArch64Gate, gateFound)
126+
})
127+
}
128+
}
129+
130+
func buildMachineConfigurationWithBootImageUpdateDisabled() *opv1.MachineConfiguration {
131+
return &opv1.MachineConfiguration{Spec: opv1.MachineConfigurationSpec{ManagedBootImages: apihelpers.GetManagedBootImagesWithUpdateDisabled()}, ObjectMeta: metav1.ObjectMeta{Name: "cluster"}}
132+
}
133+
134+
func buildMachineConfigurationWithNoBootImageConfiguration() *opv1.MachineConfiguration {
135+
return &opv1.MachineConfiguration{Spec: opv1.MachineConfigurationSpec{ManagedBootImages: apihelpers.GetManagedBootImagesWithNoConfiguration()}, ObjectMeta: metav1.ObjectMeta{Name: "cluster"}}
136+
}
137+
138+
func buildAdminAckConfigMapWithData(data map[string]string) *corev1.ConfigMap {
139+
return &corev1.ConfigMap{
140+
ObjectMeta: metav1.ObjectMeta{Name: AdminAckGatesConfigMapName, Namespace: ctrlcommon.OpenshiftConfigManagedNamespace},
141+
Data: data,
142+
}
143+
}
144+
145+
func buildNodeWithArch(arch string) *corev1.Node {
146+
return &corev1.Node{
147+
ObjectMeta: metav1.ObjectMeta{Name: "node-1"},
148+
Status: corev1.NodeStatus{
149+
NodeInfo: corev1.NodeSystemInfo{
150+
Architecture: arch,
151+
},
152+
},
153+
}
154+
}

pkg/operator/operator_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import (
2121
corelisterv1 "k8s.io/client-go/listers/core/v1"
2222
"k8s.io/client-go/tools/cache"
2323
"k8s.io/client-go/tools/record"
24+
25+
opv1 "github.com/openshift/api/operator/v1"
26+
mcoplistersv1 "github.com/openshift/client-go/operator/listers/operator/v1"
2427
)
2528

2629
func TestMetrics(t *testing.T) {
@@ -79,6 +82,27 @@ func TestMetrics(t *testing.T) {
7982
optr.nodeClusterLister = configlistersv1.NewNodeLister(configNodeIndexer)
8083
configNodeIndexer.Add(configNode)
8184

85+
managedConfigMapIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
86+
optr.ocManagedConfigMapLister = corelisterv1.NewConfigMapLister(managedConfigMapIndexer)
87+
managedConfigMapIndexer.Add(&corev1.ConfigMap{
88+
ObjectMeta: metav1.ObjectMeta{Name: "admin-gates", Namespace: "openshift-config-managed"},
89+
})
90+
91+
infraIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
92+
optr.infraLister = configlistersv1.NewInfrastructureLister(infraIndexer)
93+
infraIndexer.Add(&configv1.Infrastructure{
94+
ObjectMeta: metav1.ObjectMeta{Name: "cluster"},
95+
Status: configv1.InfrastructureStatus{
96+
PlatformStatus: &configv1.PlatformStatus{},
97+
},
98+
})
99+
100+
mcopIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
101+
optr.mcopLister = mcoplistersv1.NewMachineConfigurationLister(mcopIndexer)
102+
mcopIndexer.Add(&opv1.MachineConfiguration{
103+
ObjectMeta: metav1.ObjectMeta{Name: "cluster"},
104+
})
105+
82106
optr.configClient = fakeconfigclientset.NewSimpleClientset(co, kasOperator)
83107
err := optr.syncAll([]syncFunc{
84108
{name: "fn1",

pkg/operator/status_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,21 @@ func TestOperatorSyncStatus(t *testing.T) {
697697
optr.nodeClusterLister = configlistersv1.NewNodeLister(configNodeIndexer)
698698
configNodeIndexer.Add(configNode)
699699

700+
managedConfigMapIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
701+
optr.ocManagedConfigMapLister = corelisterv1.NewConfigMapLister(managedConfigMapIndexer)
702+
managedConfigMapIndexer.Add(&corev1.ConfigMap{
703+
ObjectMeta: metav1.ObjectMeta{Name: "admin-gates", Namespace: "openshift-config-managed"},
704+
})
705+
706+
infraIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
707+
optr.infraLister = configlistersv1.NewInfrastructureLister(infraIndexer)
708+
infraIndexer.Add(&configv1.Infrastructure{
709+
ObjectMeta: metav1.ObjectMeta{Name: "cluster"},
710+
Status: configv1.InfrastructureStatus{
711+
PlatformStatus: &configv1.PlatformStatus{},
712+
},
713+
})
714+
700715
for j, sync := range testCase.syncs {
701716
optr.inClusterBringup = sync.inClusterBringUp
702717
if sync.nextVersion != "" {
@@ -784,6 +799,21 @@ func TestInClusterBringUpStayOnErr(t *testing.T) {
784799
configMapIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
785800
optr.mcoCmLister = corelisterv1.NewConfigMapLister(configMapIndexer)
786801

802+
managedConfigMapIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
803+
optr.ocManagedConfigMapLister = corelisterv1.NewConfigMapLister(managedConfigMapIndexer)
804+
managedConfigMapIndexer.Add(&corev1.ConfigMap{
805+
ObjectMeta: metav1.ObjectMeta{Name: "admin-gates", Namespace: "openshift-config-managed"},
806+
})
807+
808+
infraIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
809+
optr.infraLister = configlistersv1.NewInfrastructureLister(infraIndexer)
810+
infraIndexer.Add(&configv1.Infrastructure{
811+
ObjectMeta: metav1.ObjectMeta{Name: "cluster"},
812+
Status: configv1.InfrastructureStatus{
813+
PlatformStatus: &configv1.PlatformStatus{},
814+
},
815+
})
816+
787817
fn1 := func(config *renderConfig, co *configv1.ClusterOperator) error {
788818
return errors.New("mocked fn1")
789819
}

0 commit comments

Comments
 (0)