Skip to content

Commit

Permalink
Fix status when system is insync (#410)
Browse files Browse the repository at this point in the history
DM must not have status.delta when controllers are insync. This commit
ensures no delta for host, system and data network controllers.

Test plan:
PASS - perform day-2 operations, ensure no delta once controllers are
insync.

Signed-off-by: Wallysson Silva <wallysson.silva@windriver.com>
  • Loading branch information
wasnio authored Dec 11, 2024
1 parent bc5a0fe commit cca29ec
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 73 deletions.
5 changes: 5 additions & 0 deletions api/v1/constructors.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package v1
import (
"fmt"
"regexp"
"slices"
"strconv"
"strings"

Expand Down Expand Up @@ -202,6 +203,10 @@ func parseProcessorInfo(profile *HostProfileSpec, host v1info.HostInfo) error {
node.Functions = append(node.Functions, data)
}

slices.SortFunc(node.Functions, func(a, b ProcessorFunctionInfo) int {
return strings.Compare(a.Function, b.Function)
})

result = append(result, node)
}

Expand Down
12 changes: 12 additions & 0 deletions api/v1/host_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,18 @@ type HostStatus struct {
Delta string `json:"delta"`
}

func (h *Host) SetStatusDelta(delta string) {
h.Status.Delta = delta
}

func (h *Host) GetStatusDelta() string {
return h.Status.Delta
}

func (h *Host) GetInsync() bool {
return h.Status.InSync
}

func (h *Host) GetStrategyRequired() string {
return h.Status.StrategyRequired
}
Expand Down
12 changes: 12 additions & 0 deletions api/v1/system_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,18 @@ type System struct {
Status SystemStatus `json:"status,omitempty"`
}

func (s *System) SetStatusDelta(delta string) {
s.Status.Delta = delta
}

func (s *System) GetStatusDelta() string {
return s.Status.Delta
}

func (s *System) GetInsync() bool {
return s.Status.InSync
}

// +kubebuilder:object:root=true
// SystemList contains a list of System
// +deepequal-gen=false
Expand Down
40 changes: 8 additions & 32 deletions controllers/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"time"

"github.com/go-logr/logr"
"github.com/google/go-cmp/cmp"
"github.com/gophercloud/gophercloud"
perrors "github.com/pkg/errors"
starlingxv1 "github.com/wind-river/cloud-platform-deployment-manager/api/v1"
Expand Down Expand Up @@ -92,6 +91,14 @@ var (
// mechanism and no retry is necessary.
RetryNever = reconcile.Result{Requeue: false}

// Properties contained on DataNetwork resouce
DataNetworkPropers = map[string]interface{}{
"type": nil,
"description": nil,
"mtu": nil,
"vxlan": []string{"multicastgroup", "udpPortNumber", "ttl", "endpointMode"},
}

// Properties contained on System resource
SystemProperties = map[string]interface{}{
"certificates": nil,
Expand Down Expand Up @@ -397,37 +404,6 @@ func (in *EventLogger) WarningEvent(object runtime.Object, reason string, messag
in.event(object, v1.EventTypeWarning, 1, reason, messageFmt, args...)
}

func GetDeltaString(spec interface{}, current interface{}, parameters map[string]interface{}) (string, error) {

specBytes, err := json.Marshal(spec)
if err != nil {
return "", err
}

currentBytes, err := json.Marshal(current)
if err != nil {
return "", err
}

var specData map[string]interface{}
var currentData map[string]interface{}

err = json.Unmarshal([]byte(specBytes), &specData)
if err != nil {
return "", err
}

err = json.Unmarshal([]byte(currentBytes), &currentData)
if err != nil {
return "", err
}

diff := cmp.Diff(currentData, specData)
deltaString := collectDiffValues(diff, parameters)
deltaString = strings.TrimSuffix(deltaString, "\n")
return deltaString, nil
}

/*
CollectDiffValues collects and returns the diff values from the given diff string.
The function returns lines starting with '+' or '-' that represent the differences,
Expand Down
76 changes: 76 additions & 0 deletions controllers/common/delta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package common

import (
"context"
"encoding/json"
"fmt"
"strings"

"github.com/go-logr/logr"
"github.com/google/go-cmp/cmp"
"sigs.k8s.io/controller-runtime/pkg/client"
)

type instance interface {
client.Object

SetStatusDelta(string)
GetStatusDelta() string
GetInsync() bool
}

func GetDeltaString(spec interface{}, current interface{}, parameters map[string]interface{}) (string, error) {

specBytes, err := json.Marshal(spec)
if err != nil {
return "", err
}

currentBytes, err := json.Marshal(current)
if err != nil {
return "", err
}

var specData map[string]interface{}
var currentData map[string]interface{}

err = json.Unmarshal([]byte(specBytes), &specData)
if err != nil {
return "", err
}

err = json.Unmarshal([]byte(currentBytes), &currentData)
if err != nil {
return "", err
}

diff := cmp.Diff(currentData, specData)
deltaString := collectDiffValues(diff, parameters)
deltaString = strings.TrimSuffix(deltaString, "\n")
return deltaString, nil
}

func SetInstanceDelta(
inst instance, spec, current interface{},
parameters map[string]interface{},
status client.StatusWriter, log logr.Logger,
) {
kind := inst.GetObjectKind().GroupVersionKind().Kind
log.Info(fmt.Sprintf("Updating delta for kind %s", kind))

oldDelta := inst.GetStatusDelta()
if inst.GetInsync() {
inst.SetStatusDelta("")
} else if delta, err := GetDeltaString(spec, current, parameters); err == nil {
inst.SetStatusDelta(delta)
} else {
log.Info(fmt.Sprintf("Failed to get Delta string for kind %s: %s\n", kind, err))
}

if oldDelta != inst.GetStatusDelta() {
err := status.Update(context.TODO(), inst)
if err != nil {
log.Info(fmt.Sprintf("Failed to update the status for kind %s: %s", kind, err))
}
}
}
24 changes: 3 additions & 21 deletions controllers/host/host_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1774,37 +1774,19 @@ func (r *HostReconciler) ReconcileExistingHost(client *gophercloud.ServiceClient
}

logHost.Info("comparing profile attributes", "host", host.ID)
inSync := r.CompareAttributes(profile, current, instance, host.Personality, system_info)
instance.Status.InSync = r.CompareAttributes(profile, current, instance, host.Personality, system_info)
common.SetInstanceDelta(instance, profile, current, common.HostProperties, r.Client.Status(), logHost)

// Continue the following steps even inSync:
// strategy not finished
if inSync && (instance.Status.StrategyRequired == cloudManager.StrategyNotRequired) {
if instance.Status.InSync && (instance.Status.StrategyRequired == cloudManager.StrategyNotRequired) {
logHost.V(2).Info("no changes between composite profile and current config", "host", host.ID)
instance.Status.Delta = ""
return nil
}

logHost.Info("defaults are:", "values", defaults)

logHost.Info("final profile is:", "values", profile)

logHost.Info("current config is:", "values", current)

deltaString, err := common.GetDeltaString(profile, current, common.HostProperties)
if err != nil {
logHost.Info(fmt.Sprintf("failed to get Delta status: %s\n", err))
}

if deltaString != "" {
logHost.V(2).Info(fmt.Sprintf("delta configuration:%s\n", deltaString))
instance.Status.Delta = deltaString

err = r.Client.Status().Update(context.TODO(), instance)
if err != nil {
logHost.Info(fmt.Sprintf("failed to update status: %s", err))
}
}

if instance.Status.Reconciled &&
r.StopAfterInSync() &&
instance.Status.StrategyRequired != cloudManager.StrategyLockRequired {
Expand Down
23 changes: 3 additions & 20 deletions controllers/system/system_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1125,29 +1125,12 @@ func (r *SystemReconciler) ReconcileRequired(instance *starlingxv1.System, spec
current.Certificates = &res
}

if spec.DeepEqual(current) {
logSystem.V(2).Info("no changes between spec and current configuration")
instance.Status.Delta = ""
return nil, false
}

logSystem.Info("spec is:", "values", spec)

logSystem.Info("current is:", "values", current)

deltaString, err := common.GetDeltaString(current, spec, common.SystemProperties)
if err != nil {
logSystem.Info(fmt.Sprintf("failed to get Delta status: %s\n", err))
}

if deltaString != "" {
logSystem.Info(fmt.Sprintf("delta configuration:%s\n", deltaString))
instance.Status.Delta = deltaString
err = r.Client.Status().Update(context.TODO(), instance)
if err != nil {
logSystem.Info(fmt.Sprintf("failed to update status: %s\n", err))
}
}
instance.Status.InSync = spec.DeepEqual(current)
common.SetInstanceDelta(instance, current, spec, common.SystemProperties, r.Client.Status(), logSystem)

if instance.Status.Reconciled && r.StopAfterInSync() {
// Do not process any further changes once we have reached a
Expand Down Expand Up @@ -1497,7 +1480,7 @@ func (r *SystemReconciler) ReconcileResource(client *gophercloud.ServiceClient,
}

if r.statusUpdateRequired(instance, systemInfo, inSync) {
logSystem.Info("updating status for system", "status", instance.Status)
logSystem.V(2).Info("updating status for system", "status", instance.Status)

err3 := r.Client.Status().Update(context.TODO(), instance)
if err3 != nil {
Expand Down

0 comments on commit cca29ec

Please sign in to comment.