Skip to content

Commit

Permalink
Set NodeSet.Status.DeployedVersion when update service is complete
Browse files Browse the repository at this point in the history
Changes setting NodeSet.Status.DeployedVersion to be only when a
Deployment has completed that contains a service where EDPMServiceType
== 'update'. When satisfied, the Deployment's Status.DeployedVersion
will be copied to NodeSet.Status.DeployedVersion.

Jira: https://issues.redhat.com/browse/OSPRH-8176
Signed-off-by: James Slagle <[email protected]>
  • Loading branch information
slagle committed Jul 2, 2024
1 parent 8b2b3bf commit 4837c75
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 3 deletions.
38 changes: 35 additions & 3 deletions controllers/dataplane/openstackdataplanenodeset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ func (r *OpenStackDataPlaneNodeSetReconciler) Reconcile(ctx context.Context, req
}
}

isDeploymentReady, isDeploymentRunning, isDeploymentFailed, failedDeployment, err := checkDeployment(helper, instance)
isDeploymentReady, isDeploymentRunning, isDeploymentFailed, failedDeployment, err := checkDeployment(helper, instance, version)
if !isDeploymentFailed && err != nil {
instance.Status.Conditions.MarkFalse(
condition.DeploymentReadyCondition,
Expand Down Expand Up @@ -464,6 +464,7 @@ func (r *OpenStackDataPlaneNodeSetReconciler) Reconcile(ctx context.Context, req

func checkDeployment(helper *helper.Helper,
instance *dataplanev1.OpenStackDataPlaneNodeSet,
version *openstackv1.OpenStackVersion,
) (bool, bool, bool, string, error) {
// Get all completed deployments
var failedDeployment string
Expand Down Expand Up @@ -529,9 +530,40 @@ func checkDeployment(helper *helper.Helper,
instance.Status.ContainerImages[k] = v
}
instance.Status.DeployedConfigHash = deployment.Status.NodeSetHashes[instance.Name]
instance.Status.DeployedVersion = deployment.Status.DeployedVersion
}

// Get list of services by name, either from ServicesOverride or
// the NodeSet.
var services []string
if len(deployment.Spec.ServicesOverride) != 0 {
services = deployment.Spec.ServicesOverride
} else {
services = instance.Spec.Services
}

// For each service, check if EDPMServiceType is "update", and the
// deployment deployed the latest version.
for _, serviceName := range services {
service := &dataplanev1.OpenStackDataPlaneService{}
name := types.NamespacedName{
Namespace: instance.Namespace,
Name: serviceName,
}
err := helper.GetClient().Get(context.Background(), name, service)
if err != nil {
helper.GetLogger().Error(err, "Unable to retrieve OpenStackDataPlaneService %v")
return false, false, false, failedDeployment, err
}

if service.Spec.EDPMServiceType != "update" {
continue
}

// An "update" service Deployment has been completed, so
// set the NodeSet's DeployedVersion to the Deployment's
// DeployedVersion.
instance.Status.DeployedVersion = deployment.Status.DeployedVersion
}
}
}
}

Expand Down
33 changes: 33 additions & 0 deletions tests/functional/dataplane/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,31 @@ func CreateSSHSecret(name types.NamespacedName) *corev1.Secret {
)
}

// Create OpenStackVersion
func CreateOpenStackVersion(name types.NamespacedName) *unstructured.Unstructured {
raw := DefaultOpenStackVersion(name)
return th.CreateUnstructured(raw)
}

// Struct initialization

func DefaultOpenStackVersion(name types.NamespacedName) map[string]interface{} {
return map[string]interface{}{
"apiVersion": "core.openstack.org/v1beta1",
"kind": "OpenStackVersion",
"metadata": map[string]interface{}{
"name": name.Name,
"namespace": name.Namespace,
},
"spec": map[string]interface{}{
"targetVersion": "0.0.1",
},
"status": map[string]interface{}{
"availableVersion": "0.0.1",
},
}
}

// Build OpenStackDataPlaneNodeSetSpec struct and fill it with preset values
func DefaultDataPlaneNodeSetSpec(nodeSetName string) map[string]interface{} {

Expand Down Expand Up @@ -180,6 +203,16 @@ func DefaultDataPlaneDeploymentSpec() map[string]interface{} {
}
}

func MinorUpdateDataPlaneDeploymentSpec() map[string]interface{} {

return map[string]interface{}{
"nodeSets": []string{
"edpm-compute-nodeset",
},
"servicesOverride": []string{"update"},
}
}

func DefaultNetConfigSpec() map[string]interface{} {
return map[string]interface{}{
"networks": []map[string]interface{}{{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
. "github.com/onsi/ginkgo/v2" //revive:disable:dot-imports
. "github.com/onsi/gomega" //revive:disable:dot-imports
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
ansibleeev1 "github.com/openstack-k8s-operators/openstack-ansibleee-operator/api/v1beta1"
openstackv1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1"
dataplanev1 "github.com/openstack-k8s-operators/openstack-operator/apis/dataplane/v1beta1"

//revive:disable-next-line:dot-imports
Expand Down Expand Up @@ -64,6 +66,7 @@ var _ = Describe("Dataplane NodeSet Test", func() {
var dataplaneDeploymentName types.NamespacedName
var dataplaneConfigHash string
var dataplaneGlobalServiceName types.NamespacedName
var dataplaneUpdateServiceName types.NamespacedName

defaultEdpmServiceList := []string{
"edpm_frr_image",
Expand Down Expand Up @@ -108,6 +111,10 @@ var _ = Describe("Dataplane NodeSet Test", func() {
Name: "global-service",
Namespace: namespace,
}
dataplaneUpdateServiceName = types.NamespacedName{
Name: "update",
Namespace: namespace,
}
err := os.Setenv("OPERATOR_SERVICES", "../../../config/services")
Expect(err).NotTo(HaveOccurred())
})
Expand Down Expand Up @@ -1290,4 +1297,51 @@ var _ = Describe("Dataplane NodeSet Test", func() {
}).Should(BeTrue())
})
})

When("A DataPlaneNodeSet is created with NoNodes and a MinorUpdate OpenStackDataPlaneDeployment is created", func() {
BeforeEach(func() {

updateServiceSpec := map[string]interface{}{
"playbook": "osp.edpm.update",
}
CreateDataPlaneServiceFromSpec(dataplaneUpdateServiceName, updateServiceSpec)
DeferCleanup(th.DeleteService, dataplaneUpdateServiceName)
DeferCleanup(th.DeleteInstance, CreateNetConfig(dataplaneNetConfigName, DefaultNetConfigSpec()))
DeferCleanup(th.DeleteInstance, CreateDNSMasq(dnsMasqName, DefaultDNSMasqSpec()))
DeferCleanup(th.DeleteInstance, CreateDataplaneNodeSet(dataplaneNodeSetName, DefaultDataPlaneNoNodeSetSpec(false)))
DeferCleanup(th.DeleteInstance, CreateDataplaneDeployment(dataplaneDeploymentName, MinorUpdateDataPlaneDeploymentSpec()))
openstackVersionName := types.NamespacedName{
Name: "openstackversion",
Namespace: namespace,
}
err := os.Setenv("OPENSTACK_RELEASE_VERSION", "0.0.1")
Expect(err).NotTo(HaveOccurred())
openstackv1.SetupVersionDefaults()
DeferCleanup(th.DeleteInstance, CreateOpenStackVersion(openstackVersionName))

CreateSSHSecret(dataplaneSSHSecretName)
SimulateDNSMasqComplete(dnsMasqName)
SimulateIPSetComplete(dataplaneNodeName)
SimulateDNSDataComplete(dataplaneNodeSetName)

Eventually(func(g Gomega) {
// Make an AnsibleEE name for each service
ansibleeeName := types.NamespacedName{
Name: "update-edpm-deployment-edpm-compute-nodeset",
Namespace: namespace,
}
ansibleEE := GetAnsibleee(ansibleeeName)
ansibleEE.Status.JobStatus = ansibleeev1.JobStatusSucceeded
g.Expect(th.K8sClient.Status().Update(th.Ctx, ansibleEE)).To(Succeed())
}, th.Timeout, th.Interval).Should(Succeed())

})
It("NodeSet.Status.DeployedVersion should be set to latest version", Label("update"), func() {
Eventually(func() string {
dataplaneNodeSetInstance := GetDataplaneNodeSet(dataplaneNodeSetName)
return dataplaneNodeSetInstance.Status.DeployedVersion
}).Should(Equal("0.0.1"))
})
})

})
3 changes: 3 additions & 0 deletions tests/functional/dataplane/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ var _ = BeforeSuite(func() {
err = (&dataplanev1.OpenStackDataPlaneService{}).SetupWebhookWithManager(k8sManager)
Expect(err).NotTo(HaveOccurred())

err = (&openstackv1.OpenStackVersion{}).SetupWebhookWithManager(k8sManager)
Expect(err).NotTo(HaveOccurred())

kclient, err := kubernetes.NewForConfig(cfg)
Expect(err).ToNot(HaveOccurred(), "failed to create kclient")
err = (&dataplanecontrollers.OpenStackDataPlaneNodeSetReconciler{
Expand Down

0 comments on commit 4837c75

Please sign in to comment.