Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions internal/controller/ansibletest_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request)
// Initialize conditions used later as Status=Unknown
cl := condition.CreateList(
condition.UnknownCondition(condition.ReadyCondition, condition.InitReason, condition.ReadyInitMessage),
condition.UnknownCondition(condition.ServiceConfigReadyCondition, condition.InitReason, condition.ServiceConfigReadyMessage),
condition.UnknownCondition(condition.InputReadyCondition, condition.InitReason, condition.InputReadyInitMessage),
condition.UnknownCondition(condition.DeploymentReadyCondition, condition.InitReason, condition.DeploymentReadyInitMessage),
)
instance.Status.Conditions.Init(&cl)
Expand Down Expand Up @@ -207,7 +207,17 @@ func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request)
}
// Create PersistentVolumeClaim - end

instance.Status.Conditions.MarkTrue(condition.ServiceConfigReadyCondition, condition.ServiceConfigReadyMessage)
err = r.ValidateOpenstackInputs(ctx, instance, instance.Spec.OpenStackConfigMap, instance.Spec.OpenStackConfigSecret)
if err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.InputReadyCondition,
condition.ErrorReason,
condition.SeverityError,
condition.InputReadyErrorMessage,
err.Error()))
return ctrl.Result{RequeueAfter: RequeueAfterValue}, err
}
instance.Status.Conditions.MarkTrue(condition.InputReadyCondition, condition.InputReadyMessage)

// Create a new pod
mountCerts := r.CheckSecretExists(ctx, instance, "combined-ca-bundle")
Expand Down
54 changes: 54 additions & 0 deletions internal/controller/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ var (

// ErrFieldNotFound indicates a field name does not exist on the struct.
ErrFieldNotFound = errors.New("field not found")

// ErrConfigMapMissingKey indicates that a required key is missing in a config map.
ErrConfigMapMissingKey = errors.New("config map is missing required key")

// ErrSecretMissingKey indicates that a required key is missing in a secret.
ErrSecretMissingKey = errors.New("secret is missing required key")
)

// Reconciler provides common functionality for all test framework reconcilers
Expand Down Expand Up @@ -350,6 +356,22 @@ func (r *Reconciler) CheckSecretExists(ctx context.Context, instance client.Obje
return true
}

// ValidateSecret returns error if the secret name is provided but the secret doesn't exist
func (r *Reconciler) ValidateSecret(ctx context.Context, instance client.Object, secretName string) error {
// when secret is not specified, skip it
if secretName == "" {
return nil
}

secret := &corev1.Secret{}
err := r.Client.Get(ctx, client.ObjectKey{Namespace: instance.GetNamespace(), Name: secretName}, secret)
if err != nil {
return fmt.Errorf("secret %s: %w", secretName, err)
}

return nil
}

// GetStringHash returns a hash of the given string with the specified length
func GetStringHash(str string, hashLength int) string {
hash := sha256.New()
Expand Down Expand Up @@ -639,6 +661,38 @@ func (r *Reconciler) VerifyNetworkAttachments(
return ctrl.Result{}, nil
}

// ValidateOpenstackInputs validates that required Openstack config map and secret exist
func (r *Reconciler) ValidateOpenstackInputs(
ctx context.Context,
instance client.Object,
openstackConfigMapName string,
openstackConfigSecretName string,
) error {
cm := &corev1.ConfigMap{}
if err := r.Client.Get(ctx, client.ObjectKey{
Namespace: instance.GetNamespace(),
Name: openstackConfigMapName,
}, cm); err != nil {
return fmt.Errorf("openstack config map %s: %w", openstackConfigMapName, err)
}
if _, ok := cm.Data["clouds.yaml"]; !ok {
return fmt.Errorf("%w 'clouds.yaml': %s", ErrConfigMapMissingKey, openstackConfigMapName)
}

secret := &corev1.Secret{}
if err := r.Client.Get(ctx, client.ObjectKey{
Namespace: instance.GetNamespace(),
Name: openstackConfigSecretName,
}, secret); err != nil {
return fmt.Errorf("openstack secret %s: %w", openstackConfigSecretName, err)
}
if _, ok := secret.Data["secure.yaml"]; !ok {
return fmt.Errorf("%w 'secure.yaml': %s", ErrSecretMissingKey, openstackConfigSecretName)
}

return nil
}

// EnsureCloudsConfigMapExists ensures that frameworks like Tobiko and Horizon have password values
// present in clouds.yaml. This code ensures that we set a default value of
// 12345678 when password value is missing in the clouds.yaml
Expand Down
25 changes: 24 additions & 1 deletion internal/controller/horizontest_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ func (r *HorizonTestReconciler) Reconcile(ctx context.Context, req ctrl.Request)
// Initialize conditions used later as Status=Unknown
cl := condition.CreateList(
condition.UnknownCondition(condition.ReadyCondition, condition.InitReason, condition.ReadyInitMessage),
condition.UnknownCondition(condition.InputReadyCondition, condition.InitReason, condition.InputReadyInitMessage),
condition.UnknownCondition(condition.DeploymentReadyCondition, condition.InitReason, condition.DeploymentReadyInitMessage),
)
instance.Status.Conditions.Init(&cl)
Expand Down Expand Up @@ -214,9 +215,31 @@ func (r *HorizonTestReconciler) Reconcile(ctx context.Context, req ctrl.Request)
}
// Create PersistentVolumeClaim - end

err = r.ValidateOpenstackInputs(ctx, instance, instance.Spec.OpenStackConfigMap, instance.Spec.OpenStackConfigSecret)
if err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.InputReadyCondition,
condition.ErrorReason,
condition.SeverityError,
condition.InputReadyErrorMessage,
err.Error()))
return ctrl.Result{RequeueAfter: RequeueAfterValue}, err
}
instance.Status.Conditions.MarkTrue(condition.InputReadyCondition, condition.InputReadyMessage)

if err := r.ValidateSecret(ctx, instance, instance.Spec.KubeconfigSecretName); err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.InputReadyCondition,
condition.ErrorReason,
condition.SeverityWarning,
condition.InputReadyErrorMessage,
err.Error()))
return ctrl.Result{}, err
}
mountKubeconfig := len(instance.Spec.KubeconfigSecretName) != 0

// Create Pod
mountCerts := r.CheckSecretExists(ctx, instance, "combined-ca-bundle")
mountKubeconfig := len(instance.Spec.KubeconfigSecretName) != 0

// Prepare HorizonTest env vars
envVars := r.PrepareHorizonTestEnvVars(instance)
Expand Down
25 changes: 22 additions & 3 deletions internal/controller/tempest_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ func (r *TempestReconciler) Reconcile(ctx context.Context, req ctrl.Request) (re
// Initialize conditions used later as Status=Unknown
cl := condition.CreateList(
condition.UnknownCondition(condition.ReadyCondition, condition.InitReason, condition.ReadyInitMessage),
condition.UnknownCondition(condition.InputReadyCondition, condition.InitReason, condition.InputReadyInitMessage),
condition.UnknownCondition(condition.ServiceConfigReadyCondition, condition.InitReason, condition.ServiceConfigReadyInitMessage),
condition.UnknownCondition(condition.DeploymentReadyCondition, condition.InitReason, condition.DeploymentReadyInitMessage),
condition.UnknownCondition(condition.NetworkAttachmentsReadyCondition, condition.InitReason, condition.NetworkAttachmentsReadyInitMessage),
Expand Down Expand Up @@ -232,10 +233,28 @@ func (r *TempestReconciler) Reconcile(ctx context.Context, req ctrl.Request) (re
}
// Create PersistentVolumeClaim - end

mountSSHKey := false
if instance.Spec.SSHKeySecretName != "" {
mountSSHKey = r.CheckSecretExists(ctx, instance, instance.Spec.SSHKeySecretName)
err = r.ValidateOpenstackInputs(ctx, instance, instance.Spec.OpenStackConfigMap, instance.Spec.OpenStackConfigSecret)
if err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.InputReadyCondition,
condition.ErrorReason,
condition.SeverityError,
condition.InputReadyErrorMessage,
err.Error()))
return ctrl.Result{RequeueAfter: RequeueAfterValue}, err
}
instance.Status.Conditions.MarkTrue(condition.InputReadyCondition, condition.InputReadyMessage)

if err := r.ValidateSecret(ctx, instance, instance.Spec.SSHKeySecretName); err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.InputReadyCondition,
condition.ErrorReason,
condition.SeverityWarning,
condition.InputReadyErrorMessage,
err.Error()))
return ctrl.Result{}, err
}
mountSSHKey := len(instance.Spec.SSHKeySecretName) != 0

// Generate ConfigMaps
err = r.generateServiceConfigMaps(ctx, helper, instance, nextWorkflowStep)
Expand Down
26 changes: 24 additions & 2 deletions internal/controller/tobiko_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ func (r *TobikoReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
// Initialize conditions used later as Status=Unknown
cl := condition.CreateList(
condition.UnknownCondition(condition.ReadyCondition, condition.InitReason, condition.ReadyInitMessage),
condition.UnknownCondition(condition.InputReadyCondition, condition.InitReason, condition.InputReadyInitMessage),
condition.UnknownCondition(condition.DeploymentReadyCondition, condition.InitReason, condition.DeploymentReadyInitMessage),
condition.UnknownCondition(condition.NetworkAttachmentsReadyCondition, condition.InitReason, condition.NetworkAttachmentsReadyInitMessage),
)
Expand Down Expand Up @@ -229,6 +230,29 @@ func (r *TobikoReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
}
// Create PersistentVolumeClaim - end

err = r.ValidateOpenstackInputs(ctx, instance, instance.Spec.OpenStackConfigMap, instance.Spec.OpenStackConfigSecret)
if err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.InputReadyCondition,
condition.ErrorReason,
condition.SeverityError,
condition.InputReadyErrorMessage,
err.Error()))
return ctrl.Result{RequeueAfter: RequeueAfterValue}, err
}
instance.Status.Conditions.MarkTrue(condition.InputReadyCondition, condition.InputReadyMessage)

if err := r.ValidateSecret(ctx, instance, instance.Spec.KubeconfigSecretName); err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.InputReadyCondition,
condition.ErrorReason,
condition.SeverityWarning,
condition.InputReadyErrorMessage,
err.Error()))
return ctrl.Result{}, err
}
mountKubeconfig := len(instance.Spec.KubeconfigSecretName) != 0

serviceAnnotations, ctrlResult, err := r.EnsureNetworkAttachments(
ctx,
Log,
Expand Down Expand Up @@ -266,8 +290,6 @@ func (r *TobikoReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
mountKeys = true
}

mountKubeconfig := len(instance.Spec.KubeconfigSecretName) != 0

// Prepare Tobiko env vars
envVars := r.PrepareTobikoEnvVars(ctx, serviceLabels, instance, helper, nextWorkflowStep)
podName := r.GetPodName(instance, nextWorkflowStep)
Expand Down
2 changes: 1 addition & 1 deletion test/functional/horizontest_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ var _ = Describe("HorizonTest controller", func() {
It("initializes the status fields", func() {
Eventually(func(g Gomega) {
horizonTest := GetHorizonTest(horizonTestName)
g.Expect(horizonTest.Status.Conditions).To(HaveLen(2))
g.Expect(horizonTest.Status.Conditions).To(HaveLen(3))
}, timeout*2, interval).Should(Succeed())
})

Expand Down
2 changes: 1 addition & 1 deletion test/functional/tempest_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ var _ = Describe("Tempest controller", func() {
It("initializes the status fields", func() {
Eventually(func(g Gomega) {
tempest := GetTempest(tempestName)
g.Expect(tempest.Status.Conditions).To(HaveLen(4))
g.Expect(tempest.Status.Conditions).To(HaveLen(5))
}, timeout*2, interval).Should(Succeed())
})

Expand Down
2 changes: 1 addition & 1 deletion test/functional/tobiko_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ var _ = Describe("Tobiko controller", func() {
It("initializes the status fields", func() {
Eventually(func(g Gomega) {
tobiko := GetTobiko(tobikoName)
g.Expect(tobiko.Status.Conditions).To(HaveLen(3))
g.Expect(tobiko.Status.Conditions).To(HaveLen(4))
}, timeout*2, interval).Should(Succeed())
})

Expand Down