Skip to content

Commit 2cb0f16

Browse files
committed
Move merging of workflow section into webhook
Currently, the merging of workflow section is done in controllers of related CRs. We want to move the merging logic into webhooks to make the process cleaner. Depends-On: openstack-k8s-operators/ci-framework#2906
1 parent 95715a7 commit 2cb0f16

File tree

5 files changed

+117
-252
lines changed

5 files changed

+117
-252
lines changed

.zuul.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
- openstack-k8s-operators-content-provider
1212
vars:
1313
cifmw_test_operator_bundle: "{{ content_provider_registry_ip }}:5001/openstack-k8s-operators/test-operator:{{ zuul.patchset }}"
14+
cifmw_test_operator_repo: https://github.com/openstack-k8s-operators/test-operator.git
15+
cifmw_test_operator_version: "{{ zuul.patchset }}"
1416
periodic:
1517
jobs:
1618
- openstack-k8s-operators-content-provider:
@@ -85,6 +87,10 @@
8587
tempestRun:
8688
includeList: |
8789
tempest.api.compute.admin.test_flavors.FlavorsAdminTestJSON.test_create_flavor_using_string_ram
90+
concurrency: 8
91+
tempestconfRun:
92+
collectTiming: true
93+
8894
cifmw_test_operator_tempest_extra_images:
8995
- URL: https://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img
9096
name: cirros-0.6.2-test-operator

controllers/ansibletest_controller.go

+15-83
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,12 @@ import (
2222
"fmt"
2323
"strconv"
2424

25-
"reflect"
26-
2725
"github.com/go-logr/logr"
2826
"github.com/openstack-k8s-operators/lib-common/modules/common"
2927
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
3028
"github.com/openstack-k8s-operators/lib-common/modules/common/env"
3129
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
3230
testv1beta1 "github.com/openstack-k8s-operators/test-operator/api/v1beta1"
33-
v1beta1 "github.com/openstack-k8s-operators/test-operator/api/v1beta1"
3431
"github.com/openstack-k8s-operators/test-operator/pkg/ansibletest"
3532
corev1 "k8s.io/api/core/v1"
3633
k8s_errors "k8s.io/apimachinery/pkg/api/errors"
@@ -129,6 +126,9 @@ func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request)
129126

130127
workflowLength := len(instance.Spec.Workflow)
131128
nextAction, nextWorkflowStep, err := r.NextAction(ctx, instance, workflowLength)
129+
if nextWorkflowStep < workflowLength {
130+
MergeSections(&instance.Spec, instance.Spec.Workflow[nextWorkflowStep])
131+
}
132132

133133
switch nextAction {
134134
case Failure:
@@ -206,32 +206,14 @@ func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request)
206206
// Create a new pod
207207
mountCerts := r.CheckSecretExists(ctx, instance, "combined-ca-bundle")
208208
podName := r.GetPodName(instance, nextWorkflowStep)
209-
envVars, workflowOverrideParams := r.PrepareAnsibleEnv(instance, nextWorkflowStep)
209+
envVars, workflowOverrideParams := r.PrepareAnsibleEnv(instance)
210210
logsPVCName := r.GetPVCLogsName(instance, 0)
211211
containerImage, err := r.GetContainerImage(ctx, workflowOverrideParams["ContainerImage"], instance)
212-
privileged := r.OverwriteAnsibleWithWorkflow(instance.Spec, "Privileged", "pbool", nextWorkflowStep).(bool)
212+
privileged := instance.Spec.Privileged
213213
if err != nil {
214214
return ctrl.Result{}, err
215215
}
216216

217-
if nextWorkflowStep < len(instance.Spec.Workflow) {
218-
if instance.Spec.Workflow[nextWorkflowStep].NodeSelector != nil {
219-
instance.Spec.NodeSelector = *instance.Spec.Workflow[nextWorkflowStep].NodeSelector
220-
}
221-
222-
if instance.Spec.Workflow[nextWorkflowStep].Tolerations != nil {
223-
instance.Spec.Tolerations = *instance.Spec.Workflow[nextWorkflowStep].Tolerations
224-
}
225-
226-
if instance.Spec.Workflow[nextWorkflowStep].SELinuxLevel != nil {
227-
instance.Spec.SELinuxLevel = *instance.Spec.Workflow[nextWorkflowStep].SELinuxLevel
228-
}
229-
230-
if instance.Spec.Workflow[nextWorkflowStep].Resources != nil {
231-
instance.Spec.Resources = *instance.Spec.Workflow[nextWorkflowStep].Resources
232-
}
233-
}
234-
235217
podDef := ansibletest.Pod(
236218
instance,
237219
serviceLabels,
@@ -284,82 +266,32 @@ func (r *AnsibleTestReconciler) SetupWithManager(mgr ctrl.Manager) error {
284266
Complete(r)
285267
}
286268

287-
func (r *Reconciler) OverwriteAnsibleWithWorkflow(
288-
instance v1beta1.AnsibleTestSpec,
289-
sectionName string,
290-
workflowValueType string,
291-
workflowStepNum int,
292-
) interface{} {
293-
if len(instance.Workflow)-1 < workflowStepNum {
294-
reflected := reflect.ValueOf(instance)
295-
fieldValue := reflected.FieldByName(sectionName)
296-
return fieldValue.Interface()
297-
}
298-
299-
reflected := reflect.ValueOf(instance)
300-
SpecValue := reflected.FieldByName(sectionName).Interface()
301-
302-
reflected = reflect.ValueOf(instance.Workflow[workflowStepNum])
303-
WorkflowValue := reflected.FieldByName(sectionName).Interface()
304-
305-
if workflowValueType == "pbool" {
306-
if val, ok := WorkflowValue.(*bool); ok && val != nil {
307-
return *(WorkflowValue.(*bool))
308-
}
309-
return SpecValue.(bool)
310-
} else if workflowValueType == "puint8" {
311-
if val, ok := WorkflowValue.(*uint8); ok && val != nil {
312-
return *(WorkflowValue.(*uint8))
313-
}
314-
return SpecValue
315-
} else if workflowValueType == "string" {
316-
if val, ok := WorkflowValue.(string); ok && val != "" {
317-
return WorkflowValue
318-
}
319-
return SpecValue
320-
}
321-
322-
return nil
323-
}
324-
325269
// This function prepares env variables for a single workflow step.
326270
func (r *AnsibleTestReconciler) PrepareAnsibleEnv(
327271
instance *testv1beta1.AnsibleTest,
328-
step int,
329272
) (map[string]env.Setter, map[string]string) {
330273
// Prepare env vars
331274
envVars := make(map[string]env.Setter)
332275
workflowOverrideParams := make(map[string]string)
333276

334277
// volumes workflow override
335-
workflowOverrideParams["WorkloadSSHKeySecretName"] = r.OverwriteAnsibleWithWorkflow(instance.Spec, "WorkloadSSHKeySecretName", "string", step).(string)
336-
workflowOverrideParams["ComputesSSHKeySecretName"] = r.OverwriteAnsibleWithWorkflow(instance.Spec, "ComputesSSHKeySecretName", "string", step).(string)
337-
workflowOverrideParams["ContainerImage"] = r.OverwriteAnsibleWithWorkflow(instance.Spec, "ContainerImage", "string", step).(string)
278+
workflowOverrideParams["WorkloadSSHKeySecretName"] = instance.Spec.WorkloadSSHKeySecretName
279+
workflowOverrideParams["ComputesSSHKeySecretName"] = instance.Spec.ComputesSSHKeySecretName
280+
workflowOverrideParams["ContainerImage"] = instance.Spec.ContainerImage
338281

339282
// bool
340-
debug := r.OverwriteAnsibleWithWorkflow(instance.Spec, "Debug", "pbool", step).(bool)
283+
debug := instance.Spec.Debug
341284
if debug {
342285
envVars["POD_DEBUG"] = env.SetValue("true")
343286
}
344287

345288
// strings
346-
extraVars := r.OverwriteAnsibleWithWorkflow(instance.Spec, "AnsibleExtraVars", "string", step).(string)
347-
envVars["POD_ANSIBLE_EXTRA_VARS"] = env.SetValue(extraVars)
348-
349-
extraVarsFile := r.OverwriteAnsibleWithWorkflow(instance.Spec, "AnsibleVarFiles", "string", step).(string)
350-
envVars["POD_ANSIBLE_FILE_EXTRA_VARS"] = env.SetValue(extraVarsFile)
351-
352-
inventory := r.OverwriteAnsibleWithWorkflow(instance.Spec, "AnsibleInventory", "string", step).(string)
353-
envVars["POD_ANSIBLE_INVENTORY"] = env.SetValue(inventory)
354-
355-
gitRepo := r.OverwriteAnsibleWithWorkflow(instance.Spec, "AnsibleGitRepo", "string", step).(string)
356-
envVars["POD_ANSIBLE_GIT_REPO"] = env.SetValue(gitRepo)
357-
358-
playbookPath := r.OverwriteAnsibleWithWorkflow(instance.Spec, "AnsiblePlaybookPath", "string", step).(string)
359-
envVars["POD_ANSIBLE_PLAYBOOK"] = env.SetValue(playbookPath)
360-
361-
ansibleCollections := r.OverwriteAnsibleWithWorkflow(instance.Spec, "AnsibleCollections", "string", step).(string)
362-
envVars["POD_INSTALL_COLLECTIONS"] = env.SetValue(ansibleCollections)
289+
envVars["POD_ANSIBLE_EXTRA_VARS"] = env.SetValue(instance.Spec.AnsibleExtraVars)
290+
envVars["POD_ANSIBLE_FILE_EXTRA_VARS"] = env.SetValue(instance.Spec.AnsibleVarFiles)
291+
envVars["POD_ANSIBLE_INVENTORY"] = env.SetValue(instance.Spec.AnsibleInventory)
292+
envVars["POD_ANSIBLE_GIT_REPO"] = env.SetValue(instance.Spec.AnsibleGitRepo)
293+
envVars["POD_ANSIBLE_PLAYBOOK"] = env.SetValue(instance.Spec.AnsiblePlaybookPath)
294+
envVars["POD_INSTALL_COLLECTIONS"] = env.SetValue(instance.Spec.AnsibleCollections)
363295

364296
return envVars, workflowOverrideParams
365297
}

controllers/common.go

+43-38
Original file line numberDiff line numberDiff line change
@@ -611,44 +611,6 @@ func (r *Reconciler) setConfigOverwrite(customData map[string]string, configOver
611611
}
612612
}
613613

614-
func (r *Reconciler) OverwriteValueWithWorkflow(
615-
instance v1beta1.TobikoSpec,
616-
sectionName string,
617-
workflowValueType string,
618-
workflowStepNum int,
619-
) interface{} {
620-
if len(instance.Workflow)-1 < workflowStepNum {
621-
reflected := reflect.ValueOf(instance)
622-
fieldValue := reflected.FieldByName(sectionName)
623-
return fieldValue.Interface()
624-
}
625-
626-
reflected := reflect.ValueOf(instance)
627-
tobikoSpecValue := reflected.FieldByName(sectionName).Interface()
628-
629-
reflected = reflect.ValueOf(instance.Workflow[workflowStepNum])
630-
tobikoWorkflowValue := reflected.FieldByName(sectionName).Interface()
631-
632-
if workflowValueType == "pbool" {
633-
if val, ok := tobikoWorkflowValue.(*bool); ok && val != nil {
634-
return *(tobikoWorkflowValue.(*bool))
635-
}
636-
return tobikoSpecValue.(bool)
637-
} else if workflowValueType == "puint8" {
638-
if val, ok := tobikoWorkflowValue.(*uint8); ok && val != nil {
639-
return *(tobikoWorkflowValue.(*uint8))
640-
}
641-
return tobikoSpecValue
642-
} else if workflowValueType == "string" {
643-
if val, ok := tobikoWorkflowValue.(string); ok && val != "" {
644-
return tobikoWorkflowValue
645-
}
646-
return tobikoSpecValue
647-
}
648-
649-
return nil
650-
}
651-
652614
func GetCommonRbacRules(privileged bool) []rbacv1.PolicyRule {
653615
rbacPolicyRule := rbacv1.PolicyRule{
654616
APIGroups: []string{"security.openshift.io"},
@@ -734,3 +696,46 @@ func EnsureCloudsConfigMapExists(
734696

735697
return ctrl.Result{}, nil
736698
}
699+
700+
func IsEmpty(value interface{}) bool {
701+
if v, ok := value.(reflect.Value); ok {
702+
switch v.Kind() {
703+
case reflect.String, reflect.Map:
704+
return v.Len() == 0
705+
case reflect.Ptr, reflect.Interface, reflect.Slice:
706+
return v.IsNil()
707+
}
708+
}
709+
return false
710+
}
711+
712+
// MergeSections iterates through all CR parameters and overrides them
713+
// with non-empty values from the workflow section of the current step.
714+
func MergeSections(main interface{}, workflow interface{}) {
715+
mReflect := reflect.ValueOf(main).Elem()
716+
wReflect := reflect.ValueOf(workflow)
717+
718+
for i := 0; i < mReflect.NumField(); i++ {
719+
name := mReflect.Type().Field(i).Name
720+
mValue := mReflect.Field(i)
721+
wValue := wReflect.FieldByName(name)
722+
723+
if mValue.Kind() == reflect.Struct && wValue.Kind() != reflect.Ptr {
724+
switch name {
725+
case "CommonOptions":
726+
wValue := wReflect.FieldByName("WorkflowCommonOptions")
727+
MergeSections(mValue.Addr().Interface(), wValue.Interface())
728+
case "TempestRun", "TempestconfRun":
729+
MergeSections(mValue.Addr().Interface(), wValue.Interface())
730+
}
731+
continue
732+
}
733+
734+
if wValue.IsValid() && !IsEmpty(wValue) {
735+
if wValue.Kind() == reflect.Ptr && mValue.Kind() != reflect.Ptr {
736+
wValue = wValue.Elem()
737+
}
738+
mValue.Set(wValue)
739+
}
740+
}
741+
}

0 commit comments

Comments
 (0)