Skip to content

Commit

Permalink
Revert the host back to default value (#1083)
Browse files Browse the repository at this point in the history
* revert host back to default in route

Signed-off-by: YuChen <yuchen.shen@mail.utoronto.ca>

* fix go format

Signed-off-by: YuChen <yuchen.shen@mail.utoronto.ca>

---------

Signed-off-by: YuChen <yuchen.shen@mail.utoronto.ca>
  • Loading branch information
YCShen1010 authored Sep 25, 2024
1 parent dfc27df commit f6260a6
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 44 deletions.
198 changes: 154 additions & 44 deletions controllers/operandrequest/reconcile_operand.go
Original file line number Diff line number Diff line change
Expand Up @@ -1010,10 +1010,22 @@ func (r *Reconciler) createK8sResource(ctx context.Context, k8sResTemplate unstr
if k8sResConfigUnmarshalErr != nil {
klog.Errorf("failed to unmarshal k8s Resource Config: %v", k8sResConfigUnmarshalErr)
}

for k, v := range k8sResConfigDecoded {
k8sResTemplate.Object[k] = v
}

if kind == "Route" {
if host, found := k8sResConfigDecoded["spec"].(map[string]interface{})["host"].(string); found {
hostHash := util.CalculateHash(host)

if newAnnotations == nil {
newAnnotations = make(map[string]string)
}
newAnnotations["operator.ibm.com/odlm.route.hashedData"] = hostHash
} else {
klog.Warningf("spec.host not found in Route %s/%s", namespace, name)
}
}
}

r.EnsureLabel(k8sResTemplate, map[string]string{constant.OpreqLabel: "true"})
Expand All @@ -1039,59 +1051,36 @@ func (r *Reconciler) updateK8sResource(ctx context.Context, existingK8sRes unstr
apiversion := existingK8sRes.GetAPIVersion()
name := existingK8sRes.GetName()
namespace := existingK8sRes.GetNamespace()
if kind == "Job" {
existingK8sRes := unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": apiversion,
"kind": kind,
},
}

err := r.Client.Get(ctx, types.NamespacedName{
Name: name,
Namespace: namespace,
}, &existingK8sRes)

if err != nil {
return errors.Wrapf(err, "failed to get k8s resource -- Kind: %s, NamespacedName: %s/%s", kind, namespace, name)
}
if !r.CheckLabel(existingK8sRes, map[string]string{constant.OpreqLabel: "true"}) && (newLabels == nil || newLabels[constant.OpreqLabel] != "true") {
return nil
if kind == "Job" {
if err := r.updateK8sJob(ctx, existingK8sRes, k8sResConfig, newLabels, newAnnotations, ownerReferences); err != nil {
return errors.Wrap(err, "failed to update Job")
}
return nil
}

var existingHashedData string
var newHashedData string
if existingK8sRes.GetAnnotations() != nil {
existingHashedData = existingK8sRes.GetAnnotations()[constant.HashedData]
if kind == "Route" {
if err := r.updateK8sRoute(ctx, existingK8sRes, k8sResConfig, newLabels, newAnnotations, ownerReferences); err != nil {
return errors.Wrap(err, "failed to update Route")
}

if k8sResConfig != nil {
hashedData := sha256.Sum256(k8sResConfig.Raw)
newHashedData = hex.EncodeToString(hashedData[:7])
}

if existingHashedData != newHashedData {
// create a new template of k8s resource
var templatek8sRes unstructured.Unstructured
templatek8sRes.SetAPIVersion(apiversion)
templatek8sRes.SetKind(kind)
templatek8sRes.SetName(name)
templatek8sRes.SetNamespace(namespace)

if newAnnotations == nil {
newAnnotations = make(map[string]string)
k8sResConfigDecoded := make(map[string]interface{})
if k8sResConfigUnmarshalErr := json.Unmarshal(k8sResConfig.Raw, &k8sResConfigDecoded); k8sResConfigUnmarshalErr != nil {
return errors.Wrap(k8sResConfigUnmarshalErr, "failed to unmarshal k8s Resource Config")
}
newAnnotations[constant.HashedData] = newHashedData

if err := r.deleteK8sResource(ctx, existingK8sRes, namespace); err != nil {
return errors.Wrap(err, "failed to update k8s resource")
}
if err := r.createK8sResource(ctx, templatek8sRes, k8sResConfig, newLabels, newAnnotations, ownerReferences); err != nil {
return errors.Wrap(err, "failed to update k8s resource")
if host, found := k8sResConfigDecoded["spec"].(map[string]interface{})["host"].(string); found {
hostHash := util.CalculateHash(host)

if newAnnotations == nil {
newAnnotations = make(map[string]string)
}
newAnnotations["operator.ibm.com/odlm.route.hashedData"] = hostHash
} else {
klog.Warningf("spec.host not found in Route %s/%s", namespace, name)
}
}

return nil
}

// Update the k8s res
Expand Down Expand Up @@ -1178,6 +1167,127 @@ func (r *Reconciler) updateK8sResource(ctx context.Context, existingK8sRes unstr
return nil
}

func (r *Reconciler) updateK8sJob(ctx context.Context, existingK8sRes unstructured.Unstructured, k8sResConfig *runtime.RawExtension, newLabels, newAnnotations map[string]string, ownerReferences *[]operatorv1alpha1.OwnerReference) error {

kind := existingK8sRes.GetKind()
apiversion := existingK8sRes.GetAPIVersion()
name := existingK8sRes.GetName()
namespace := existingK8sRes.GetNamespace()

existingRes := unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": apiversion,
"kind": kind,
},
}

err := r.Client.Get(ctx, types.NamespacedName{
Name: name,
Namespace: namespace,
}, &existingRes)

if err != nil {
return errors.Wrapf(err, "failed to get k8s resource -- Kind: %s, NamespacedName: %s/%s", kind, namespace, name)
}
if !r.CheckLabel(existingRes, map[string]string{constant.OpreqLabel: "true"}) && (newLabels == nil || newLabels[constant.OpreqLabel] != "true") {
return nil
}

var existingHashedData string
var newHashedData string
if existingRes.GetAnnotations() != nil {
existingHashedData = existingRes.GetAnnotations()[constant.HashedData]
}

if k8sResConfig != nil {
hashedData := sha256.Sum256(k8sResConfig.Raw)
newHashedData = hex.EncodeToString(hashedData[:7])
}

if existingHashedData != newHashedData {
// create a new template of k8s resource
var templatek8sRes unstructured.Unstructured
templatek8sRes.SetAPIVersion(apiversion)
templatek8sRes.SetKind(kind)
templatek8sRes.SetName(name)
templatek8sRes.SetNamespace(namespace)

if newAnnotations == nil {
newAnnotations = make(map[string]string)
}
newAnnotations[constant.HashedData] = newHashedData

if err := r.deleteK8sResource(ctx, existingRes, namespace); err != nil {
return errors.Wrap(err, "failed to update k8s resource")
}
if err := r.createK8sResource(ctx, templatek8sRes, k8sResConfig, newLabels, newAnnotations, ownerReferences); err != nil {
return errors.Wrap(err, "failed to update k8s resource")
}
}
return nil
}

// update route resource
func (r *Reconciler) updateK8sRoute(ctx context.Context, existingK8sRes unstructured.Unstructured, k8sResConfig *runtime.RawExtension, newLabels, newAnnotations map[string]string, ownerReferences *[]operatorv1alpha1.OwnerReference) error {
kind := existingK8sRes.GetKind()
apiversion := existingK8sRes.GetAPIVersion()
name := existingK8sRes.GetName()
namespace := existingK8sRes.GetNamespace()

existingRes := unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": apiversion,
"kind": kind,
},
}
err := r.Client.Get(ctx, types.NamespacedName{
Name: name,
Namespace: namespace,
}, &existingRes)

if err != nil {
return errors.Wrapf(err, "failed to get k8s resource -- Kind: %s, NamespacedName: %s/%s", kind, namespace, name)
}
if !r.CheckLabel(existingRes, map[string]string{constant.OpreqLabel: "true"}) && (newLabels == nil || newLabels[constant.OpreqLabel] != "true") {
return nil
}

existingAnnos := existingRes.GetAnnotations()
existingHostHash := existingAnnos["operator.ibm.com/odlm.route.hashedData"]

if k8sResConfig != nil {
k8sResConfigDecoded := make(map[string]interface{})
k8sResConfigUnmarshalErr := json.Unmarshal(k8sResConfig.Raw, &k8sResConfigDecoded)
if k8sResConfigUnmarshalErr != nil {
klog.Errorf("failed to unmarshal k8s Resource Config: %v", k8sResConfigUnmarshalErr)
}

// Read the host from the OperandConfig
if newHost, found := k8sResConfigDecoded["spec"].(map[string]interface{})["host"].(string); found {
newHostHash := util.CalculateHash(newHost)

// Only re-create the route if the custom host has been removed
if newHost == "" && existingHostHash != newHostHash {

// create a new template of k8s resource
var templatek8sRes unstructured.Unstructured
templatek8sRes.SetAPIVersion(apiversion)
templatek8sRes.SetKind(kind)
templatek8sRes.SetName(name)
templatek8sRes.SetNamespace(namespace)

if err := r.deleteK8sResource(ctx, existingRes, namespace); err != nil {
return errors.Wrap(err, "failed to delete Route for recreation")
}
if err := r.createK8sResource(ctx, templatek8sRes, k8sResConfig, newLabels, newAnnotations, ownerReferences); err != nil {
return errors.Wrap(err, "failed to update k8s resource")
}
}
}
}
return nil
}

func (r *Reconciler) deleteK8sResource(ctx context.Context, existingK8sRes unstructured.Unstructured, namespace string) error {

kind := existingK8sRes.GetKind()
Expand Down
10 changes: 10 additions & 0 deletions controllers/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package util

import (
"bytes"
"crypto/sha256"
"encoding/hex"
"fmt"
"os"
"regexp"
Expand Down Expand Up @@ -152,6 +154,14 @@ func StringSliceContentEqual(a, b []string) bool {
return true
}

func CalculateHash(input string) string {
if input == "" {
return ""
}
hashedData := sha256.Sum256([]byte(input))
return hex.EncodeToString(hashedData[:7])
}

// WaitTimeout waits for the waitgroup for the specified max timeout.
// Returns true if waiting timed out.
func WaitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
Expand Down

0 comments on commit f6260a6

Please sign in to comment.