Skip to content

Commit ba89a24

Browse files
committed
mco: unit tests and runtime client for mcp
This switches the MCP resource to the runtime client and adds unit tests for most of the methods on the builder. For brevity, the unit tests for the list functions and the wait*** methods will come in another PR.
1 parent c80566d commit ba89a24

File tree

3 files changed

+486
-40
lines changed

3 files changed

+486
-40
lines changed

pkg/mco/mco_test.go

Lines changed: 0 additions & 1 deletion
This file was deleted.

pkg/mco/mcp.go

Lines changed: 85 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,27 @@ import (
99
"github.com/openshift-kni/eco-goinfra/pkg/clients"
1010
"github.com/openshift-kni/eco-goinfra/pkg/msg"
1111
k8serrors "k8s.io/apimachinery/pkg/api/errors"
12+
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
1213

13-
mcov1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
14+
mcv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
1415
corev1 "k8s.io/api/core/v1"
1516
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1617
"k8s.io/apimachinery/pkg/util/wait"
1718
)
1819

1920
const (
20-
fiveScds time.Duration = 5 * time.Second
21-
isTrue = "True"
22-
machineConfigPool = "MachineConfigPool"
21+
fiveScds time.Duration = 5 * time.Second
2322
)
2423

2524
// MCPBuilder provides struct for MachineConfigPool object which contains connection to cluster
2625
// and MachineConfigPool definitions.
2726
type MCPBuilder struct {
2827
// MachineConfigPool definition. Used to create MachineConfigPool object with minimum set of required elements.
29-
Definition *mcov1.MachineConfigPool
28+
Definition *mcv1.MachineConfigPool
3029
// Created MachineConfigPool object on the cluster.
31-
Object *mcov1.MachineConfigPool
30+
Object *mcv1.MachineConfigPool
3231
// api client to interact with the cluster.
33-
apiClient *clients.Settings
32+
apiClient runtimeclient.Client
3433
// errorMsg is processed before MachineConfigPool object is created.
3534
errorMsg string
3635
}
@@ -43,9 +42,22 @@ func NewMCPBuilder(apiClient *clients.Settings, mcpName string) *MCPBuilder {
4342
glog.V(100).Infof(
4443
"Initializing new MCPBuilder structure with the following params: %s", mcpName)
4544

45+
if apiClient == nil {
46+
glog.V(100).Info("The apiClient of the MachineConfigPool is nil")
47+
48+
return nil
49+
}
50+
51+
err := apiClient.AttachScheme(mcv1.Install)
52+
if err != nil {
53+
glog.V(100).Info("Failed to add machineconfig v1 scheme to client schemes")
54+
55+
return nil
56+
}
57+
4658
builder := &MCPBuilder{
47-
apiClient: apiClient,
48-
Definition: &mcov1.MachineConfigPool{
59+
apiClient: apiClient.Client,
60+
Definition: &mcv1.MachineConfigPool{
4961
ObjectMeta: metav1.ObjectMeta{
5062
Name: mcpName,
5163
},
@@ -55,7 +67,7 @@ func NewMCPBuilder(apiClient *clients.Settings, mcpName string) *MCPBuilder {
5567
if mcpName == "" {
5668
glog.V(100).Infof("The name of the MachineConfigPool is empty")
5769

58-
builder.errorMsg = "MachineConfigPool 'name' cannot be empty"
70+
builder.errorMsg = "machineconfigpool 'name' cannot be empty"
5971
}
6072

6173
return builder
@@ -65,9 +77,22 @@ func NewMCPBuilder(apiClient *clients.Settings, mcpName string) *MCPBuilder {
6577
func Pull(apiClient *clients.Settings, name string) (*MCPBuilder, error) {
6678
glog.V(100).Infof("Pulling existing machineconfigpool name %s from cluster", name)
6779

80+
if apiClient == nil {
81+
glog.V(100).Info("The apiClient of the MachineConfigPool is nil")
82+
83+
return nil, fmt.Errorf("machineconfigpool 'apiClient' cannot be nil")
84+
}
85+
86+
err := apiClient.AttachScheme(mcv1.Install)
87+
if err != nil {
88+
glog.V(100).Info("Failed to add machineconfig v1 scheme to client schemes")
89+
90+
return nil, err
91+
}
92+
6893
builder := MCPBuilder{
69-
apiClient: apiClient,
70-
Definition: &mcov1.MachineConfigPool{
94+
apiClient: apiClient.Client,
95+
Definition: &mcv1.MachineConfigPool{
7196
ObjectMeta: metav1.ObjectMeta{
7297
Name: name,
7398
},
@@ -77,7 +102,7 @@ func Pull(apiClient *clients.Settings, name string) (*MCPBuilder, error) {
77102
if name == "" {
78103
glog.V(100).Infof("The name of the machineconfigpool is empty")
79104

80-
builder.errorMsg = "machineconfigpool 'name' cannot be empty"
105+
return nil, fmt.Errorf("machineconfigpool 'name' cannot be empty")
81106
}
82107

83108
if !builder.Exists() {
@@ -89,6 +114,26 @@ func Pull(apiClient *clients.Settings, name string) (*MCPBuilder, error) {
89114
return &builder, nil
90115
}
91116

117+
// Get returns the MachineConfigPool object if found.
118+
func (builder *MCPBuilder) Get() (*mcv1.MachineConfigPool, error) {
119+
if valid, err := builder.validate(); !valid {
120+
return nil, err
121+
}
122+
123+
glog.V(100).Infof("Getting MachineConfigPool object %s", builder.Definition.Name)
124+
125+
machineConfigPool := &mcv1.MachineConfigPool{}
126+
err := builder.apiClient.Get(context.TODO(), runtimeclient.ObjectKey{Name: builder.Definition.Name}, machineConfigPool)
127+
128+
if err != nil {
129+
glog.V(100).Infof("MachineConfigPool object %s does not exist", builder.Definition.Name)
130+
131+
return nil, err
132+
}
133+
134+
return machineConfigPool, nil
135+
}
136+
92137
// Create makes a MachineConfigPool in cluster and stores the created object in struct.
93138
func (builder *MCPBuilder) Create() (*MCPBuilder, error) {
94139
if valid, err := builder.validate(); !valid {
@@ -100,8 +145,10 @@ func (builder *MCPBuilder) Create() (*MCPBuilder, error) {
100145

101146
var err error
102147
if !builder.Exists() {
103-
builder.Object, err = builder.apiClient.MachineConfigPools().Create(
104-
context.TODO(), builder.Definition, metav1.CreateOptions{})
148+
err = builder.apiClient.Create(context.TODO(), builder.Definition)
149+
if err == nil {
150+
builder.Object = builder.Definition
151+
}
105152
}
106153

107154
return builder, err
@@ -117,16 +164,20 @@ func (builder *MCPBuilder) Delete() error {
117164
builder.Definition.Name)
118165

119166
if !builder.Exists() {
120-
return fmt.Errorf("MachineConfigPool cannot be deleted because it does not exist")
121-
}
167+
glog.V(100).Infof("MachineConfigPool %s cannot be deleted because it does not exist", builder.Definition.Name)
122168

123-
err := builder.apiClient.MachineConfigPools().Delete(
124-
context.TODO(), builder.Object.Name, metav1.DeleteOptions{})
169+
builder.Object = nil
125170

171+
return nil
172+
}
173+
174+
err := builder.apiClient.Delete(context.TODO(), builder.Object)
126175
if err != nil {
127-
return fmt.Errorf("cannot delete MachineConfigPool: %w", err)
176+
return fmt.Errorf("cannot delete machineconfigpool: %w", err)
128177
}
129178

179+
builder.Object = nil
180+
130181
return err
131182
}
132183

@@ -140,8 +191,7 @@ func (builder *MCPBuilder) Exists() bool {
140191
builder.Definition.Name)
141192

142193
var err error
143-
builder.Object, err = builder.apiClient.MachineConfigPools().Get(
144-
context.TODO(), builder.Definition.Name, metav1.GetOptions{})
194+
builder.Object, err = builder.Get()
145195

146196
return err == nil || !k8serrors.IsNotFound(err)
147197
}
@@ -156,13 +206,15 @@ func (builder *MCPBuilder) WithMcSelector(mcSelector map[string]string) *MCPBuil
156206
"machineConfigSelector label: %v", mcSelector)
157207

158208
if len(mcSelector) == 0 {
159-
builder.errorMsg = "'machineConfigSelector MatchLabels' field cannot be empty"
160-
}
209+
builder.errorMsg = "machineConfigSelector 'MatchLabels' field cannot be empty"
161210

162-
if builder.errorMsg != "" {
163211
return builder
164212
}
165213

214+
if builder.Definition.Spec.MachineConfigSelector == nil {
215+
builder.Definition.Spec.MachineConfigSelector = &metav1.LabelSelector{}
216+
}
217+
166218
builder.Definition.Spec.MachineConfigSelector.MatchLabels = mcSelector
167219

168220
return builder
@@ -171,7 +223,7 @@ func (builder *MCPBuilder) WithMcSelector(mcSelector map[string]string) *MCPBuil
171223
// WaitToBeInCondition waits for a specific time duration until the MachineConfigPool will have a
172224
// specified condition type with the expected status.
173225
func (builder *MCPBuilder) WaitToBeInCondition(
174-
conditionType mcov1.MachineConfigPoolConditionType,
226+
conditionType mcv1.MachineConfigPoolConditionType,
175227
conditionStatus corev1.ConditionStatus,
176228
timeout time.Duration,
177229
) error {
@@ -184,9 +236,7 @@ func (builder *MCPBuilder) WaitToBeInCondition(
184236

185237
return wait.PollUntilContextTimeout(
186238
context.TODO(), fiveScds, timeout, true, func(ctx context.Context) (bool, error) {
187-
mcp, err := builder.apiClient.MachineConfigPools().Get(context.TODO(),
188-
builder.Object.Name, metav1.GetOptions{})
189-
239+
mcp, err := builder.Get()
190240
if err != nil {
191241
return false, nil
192242
}
@@ -210,26 +260,22 @@ func (builder *MCPBuilder) WaitForUpdate(timeout time.Duration) error {
210260
glog.V(100).Infof("WaitForUpdate waits up to specified time %v until updating"+
211261
" machineConfigPool object is updated", timeout)
212262

213-
mcpUpdating, err := builder.apiClient.MachineConfigPools().Get(context.TODO(),
214-
builder.Object.Name, metav1.GetOptions{})
215-
263+
mcpUpdating, err := builder.Get()
216264
if err != nil {
217265
return err
218266
}
219267

220268
for _, condition := range mcpUpdating.Status.Conditions {
221-
if condition.Type == "Updating" && condition.Status == isTrue {
269+
if condition.Type == "Updating" && condition.Status == corev1.ConditionTrue {
222270
err := wait.PollUntilContextTimeout(
223271
context.TODO(), fiveScds, timeout, true, func(ctx context.Context) (bool, error) {
224-
mcpUpdated, err := builder.apiClient.MachineConfigPools().Get(context.TODO(),
225-
builder.Object.Name, metav1.GetOptions{})
226-
272+
mcpUpdated, err := builder.Get()
227273
if err != nil {
228274
return false, nil
229275
}
230276

231277
for _, condition := range mcpUpdated.Status.Conditions {
232-
if condition.Type == "Updated" && condition.Status == isTrue {
278+
if condition.Type == "Updated" && condition.Status == corev1.ConditionTrue {
233279
return true, nil
234280
}
235281
}
@@ -339,7 +385,7 @@ func (builder *MCPBuilder) WithOptions(options ...MCPAdditionalOptions) *MCPBuil
339385

340386
// IsInCondition parses MachineConfigPool conditions.
341387
// Returns true if given MachineConfigPool is in given condition, otherwise false.
342-
func (builder *MCPBuilder) IsInCondition(mcpConditionType mcov1.MachineConfigPoolConditionType) bool {
388+
func (builder *MCPBuilder) IsInCondition(mcpConditionType mcv1.MachineConfigPoolConditionType) bool {
343389
if valid, _ := builder.validate(); !valid {
344390
return false
345391
}
@@ -349,7 +395,7 @@ func (builder *MCPBuilder) IsInCondition(mcpConditionType mcov1.MachineConfigPoo
349395

350396
if builder.Exists() {
351397
for _, condition := range builder.Object.Status.Conditions {
352-
if condition.Type == mcpConditionType && condition.Status == isTrue {
398+
if condition.Type == mcpConditionType && condition.Status == corev1.ConditionTrue {
353399
return true
354400
}
355401
}

0 commit comments

Comments
 (0)