Skip to content

Commit

Permalink
When values section of an helm chart changes, treat it as an upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
mgianluc committed Apr 9, 2024
1 parent 7fa049c commit 99eee82
Show file tree
Hide file tree
Showing 15 changed files with 123 additions and 104 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ARCH ?= amd64
OS ?= $(shell uname -s | tr A-Z a-z)
K8S_LATEST_VER ?= $(shell curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)
export CONTROLLER_IMG ?= $(REGISTRY)/$(IMAGE_NAME)
TAG ?= main
TAG ?= dev

.PHONY: all
all: build
Expand Down Expand Up @@ -351,7 +351,7 @@ run: manifests generate fmt vet ## Run a controller from your host.
.PHONY: docker-build
docker-build: ## Build docker image with the manager.
go generate
docker build --build-arg BUILDOS=linux --build-arg TARGETARCH=amd64 -t $(CONTROLLER_IMG):$(TAG) .
docker build --load --build-arg BUILDOS=linux --build-arg TARGETARCH=amd64 -t $(CONTROLLER_IMG):$(TAG) .
MANIFEST_IMG=$(CONTROLLER_IMG) MANIFEST_TAG=$(TAG) $(MAKE) set-manifest-image
$(MAKE) set-manifest-pull-policy

Expand Down
5 changes: 2 additions & 3 deletions api/v1alpha1/clustersummary_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,9 @@ type HelmChartSummary struct {
// chart or there is a conflict
Status HelmChartStatus `json:"status"`

// MetadataHash represents of a unique value for the extra metadata, extraLabels
// and extraAnnotations, deployed on this helm chart
// ValueHash represents of a unique value for the values section
// +optional
MetadataHash []byte `json:"metadataHash,omitempty"`
ValueHash []byte `json:"valueHash,omitempty"`

// Status indicates whether ClusterSummary can manage the helm
// chart or there is a conflict
Expand Down
4 changes: 2 additions & 2 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 5 additions & 6 deletions config/crd/bases/config.projectsveltos.io_clustersummaries.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -668,12 +668,6 @@ spec:
Status indicates whether ClusterSummary can manage the helm
chart or there is a conflict
type: string
metadataHash:
description: |-
MetadataHash represents of a unique value for the extra metadata, extraLabels
and extraAnnotations, deployed on this helm chart
format: byte
type: string
releaseName:
description: ReleaseName is the chart release
minLength: 1
Expand All @@ -691,6 +685,11 @@ spec:
- Managing
- Conflict
type: string
valueHash:
description: ValueHash represents of a unique value for the
values section
format: byte
type: string
required:
- releaseName
- releaseNamespace
Expand Down
2 changes: 1 addition & 1 deletion config/default/manager_auth_proxy_patch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ spec:
- "--report-mode=0"
- --shard-key=
- "--v=5"
- "--version=main"
- "--version=dev"
2 changes: 1 addition & 1 deletion config/default/manager_image_patch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ spec:
spec:
containers:
# Change the value of image field below to your controller image URL
- image: projectsveltos/addon-controller:main
- image: projectsveltos/addon-controller:dev
name: controller
51 changes: 39 additions & 12 deletions controllers/handlers_helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"crypto/sha256"
"fmt"
"os"
"reflect"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -364,11 +365,6 @@ func helmHash(ctx context.Context, c client.Client, clusterSummaryScope *scope.C
config += getVersion()
}

metadataHash := getMetadataHash(clusterSummary)
if metadataHash != nil {
config += string(metadataHash)
}

h.Write([]byte(config))
return h.Sum(nil), nil
}
Expand Down Expand Up @@ -483,6 +479,11 @@ func walkChartsAndDeploy(ctx context.Context, c client.Client, clusterSummary *c
if err != nil {
return nil, nil, err
}
err = updateValueHashOnHelmChartSummary(ctx, currentChart, clusterSummary)
if err != nil {
return nil, nil, err
}

releaseReports = append(releaseReports, *report)

if currentRelease != nil {
Expand Down Expand Up @@ -1003,6 +1004,14 @@ func shouldUpgrade(currentRelease *releaseInfo, requestedChart *configv1alpha1.H
clusterSummary *configv1alpha1.ClusterSummary) bool {

if clusterSummary.Spec.ClusterProfileSpec.SyncMode != configv1alpha1.SyncModeContinuousWithDriftDetection {
currentValueHash := []byte(requestedChart.Values)
oldValueHash := getValueHashFromHelmChartSummary(requestedChart, clusterSummary)

// If Values configuration has changed, trigger an upgrade
if !reflect.DeepEqual(oldValueHash, currentValueHash) {
return true
}

// With drift detection mode, there is reconciliation due to configuration drift even
// when version is same. So skip this check in SyncModeContinuousWithDriftDetection
if currentRelease != nil {
Expand Down Expand Up @@ -1256,6 +1265,8 @@ func updateStatusForeferencedHelmReleases(ctx context.Context, c client.Client,
ReleaseName: currentChart.ReleaseName,
ReleaseNamespace: currentChart.ReleaseNamespace,
Status: configv1alpha1.HelChartStatusManaging,
ValueHash: getValueHashFromHelmChartSummary(currentChart, clusterSummary), // if a value is currently stored, keep it.
// after chart is deployed such value will be updated
}
currentlyReferenced[helmInfo(currentChart.ReleaseNamespace, currentChart.ReleaseName)] = true
} else {
Expand Down Expand Up @@ -1695,9 +1706,6 @@ func addExtraMetadata(ctx context.Context, requestedChart *configv1alpha1.HelmCh
return nil
}

// Current hash of current metadata (extraLabels and extraAnnotations)
metadataHash := getMetadataHash(clusterSummary)

actionConfig, err := actionConfigInit(requestedChart.ReleaseNamespace, kubeconfig, getEnableClientCacheValue(requestedChart.Options))
if err != nil {
return err
Expand Down Expand Up @@ -1748,7 +1756,7 @@ func addExtraMetadata(ctx context.Context, requestedChart *configv1alpha1.HelmCh
}
}

return updateMetadataHashOnHelmChartSummary(ctx, requestedChart, metadataHash, clusterSummary)
return nil
}

func getResourceNamespace(r *unstructured.Unstructured, releaseNamespace string, config *rest.Config) (string, error) {
Expand All @@ -1766,11 +1774,13 @@ func getResourceNamespace(r *unstructured.Unstructured, releaseNamespace string,
return namespace, nil
}

func updateMetadataHashOnHelmChartSummary(ctx context.Context, requestedChart *configv1alpha1.HelmChart,
metadataHash []byte, clusterSummary *configv1alpha1.ClusterSummary) error {
func updateValueHashOnHelmChartSummary(ctx context.Context, requestedChart *configv1alpha1.HelmChart,
clusterSummary *configv1alpha1.ClusterSummary) error {

c := getManagementClusterClient()

valueHash := []byte(requestedChart.Values)

err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
currentClusterSummary := &configv1alpha1.ClusterSummary{}
err := c.Get(ctx,
Expand All @@ -1784,7 +1794,7 @@ func updateMetadataHashOnHelmChartSummary(ctx context.Context, requestedChart *c
if rs.ReleaseName == requestedChart.ReleaseName &&
rs.ReleaseNamespace == requestedChart.ReleaseNamespace {

rs.MetadataHash = metadataHash
rs.ValueHash = valueHash
}
}

Expand All @@ -1793,3 +1803,20 @@ func updateMetadataHashOnHelmChartSummary(ctx context.Context, requestedChart *c

return err
}

// getValueHashFromHelmChartSummary returns the valueHash stored for this chart
// in the ClusterSummary
func getValueHashFromHelmChartSummary(requestedChart *configv1alpha1.HelmChart,
clusterSummary *configv1alpha1.ClusterSummary) []byte {

for i := range clusterSummary.Status.HelmReleaseSummaries {
rs := &clusterSummary.Status.HelmReleaseSummaries[i]
if rs.ReleaseName == requestedChart.ReleaseName &&
rs.ReleaseNamespace == requestedChart.ReleaseNamespace {

return rs.ValueHash
}
}

return nil
}
5 changes: 0 additions & 5 deletions controllers/handlers_kustomize.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,6 @@ func kustomizationHash(ctx context.Context, c client.Client, clusterSummaryScope
config += getVersion()
}

metadataHash := getMetadataHash(clusterSummaryScope.ClusterSummary)
if metadataHash != nil {
config += string(metadataHash)
}

h.Write([]byte(config))
return h.Sum(nil), nil
}
Expand Down
5 changes: 0 additions & 5 deletions controllers/handlers_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,11 +397,6 @@ func resourcesHash(ctx context.Context, c client.Client, clusterSummaryScope *sc
config += getVersion()
}

metadataHash := getMetadataHash(clusterSummary)
if metadataHash != nil {
config += string(metadataHash)
}

h.Write([]byte(config))
return h.Sum(nil), nil
}
Expand Down
4 changes: 0 additions & 4 deletions controllers/handlers_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,10 +295,6 @@ func deployUnstructured(ctx context.Context, deployingToMgmtCluster bool, destCo
policy.GetKind(), policy.GetNamespace(), policy.GetName(), deployingToMgmtCluster))

resource, policyHash := getResource(policy, referencedObject, featureID, logger)
metadataHash := getMetadataHash(clusterSummary)
if metadataHash != nil {
policyHash += string(metadataHash)
}

// If policy is namespaced, create namespace if not already existing
err = createNamespace(ctx, destClient, clusterSummary, policy.GetNamespace())
Expand Down
41 changes: 0 additions & 41 deletions controllers/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ package controllers
import (
"bytes"
"context"
"crypto/sha256"
"fmt"
"sort"
"strings"
"text/template"

Expand Down Expand Up @@ -375,45 +373,6 @@ func getVersion() string {
return version
}

// getMetadataHash returns hash of current ExtraLabels and ExtraAnnotations
func getMetadataHash(clusterSummary *configv1alpha1.ClusterSummary) []byte {
if clusterSummary.Spec.ClusterProfileSpec.ExtraLabels == nil &&
clusterSummary.Spec.ClusterProfileSpec.ExtraAnnotations == nil {

return nil
}

h := sha256.New()
var config string

if clusterSummary.Spec.ClusterProfileSpec.ExtraLabels != nil {
sortedKey := getSortedKeys(clusterSummary.Spec.ClusterProfileSpec.ExtraLabels)
for i := range sortedKey {
key := sortedKey[i]
config += clusterSummary.Spec.ClusterProfileSpec.ExtraLabels[key]
}
}
if clusterSummary.Spec.ClusterProfileSpec.ExtraAnnotations != nil {
sortedKey := getSortedKeys(clusterSummary.Spec.ClusterProfileSpec.ExtraAnnotations)
for i := range sortedKey {
key := sortedKey[i]
config += clusterSummary.Spec.ClusterProfileSpec.ExtraAnnotations[key]
}
}

h.Write([]byte(config))
return h.Sum(nil)
}

func getSortedKeys(m map[string]string) []string {
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}

func isNamespaced(r *unstructured.Unstructured, config *rest.Config) (bool, error) {
gvk := schema.GroupVersionKind{
Group: r.GroupVersionKind().Group,
Expand Down
4 changes: 2 additions & 2 deletions manifest/deployment-agentless.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ spec:
- --report-mode=0
- --agent-in-mgmt-cluster
- --v=5
- --version=main
- --version=dev
command:
- /manager
image: projectsveltos/addon-controller:main
image: projectsveltos/addon-controller:dev
livenessProbe:
failureThreshold: 3
httpGet:
Expand Down
4 changes: 2 additions & 2 deletions manifest/deployment-shard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ spec:
- --report-mode=0
- --shard-key={{.SHARD}}
- --v=5
- --version=main
- --version=dev
command:
- /manager
image: projectsveltos/addon-controller:main
image: projectsveltos/addon-controller:dev
livenessProbe:
failureThreshold: 3
httpGet:
Expand Down
15 changes: 7 additions & 8 deletions manifest/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2161,12 +2161,6 @@ spec:
Status indicates whether ClusterSummary can manage the helm
chart or there is a conflict
type: string
metadataHash:
description: |-
MetadataHash represents of a unique value for the extra metadata, extraLabels
and extraAnnotations, deployed on this helm chart
format: byte
type: string
releaseName:
description: ReleaseName is the chart release
minLength: 1
Expand All @@ -2184,6 +2178,11 @@ spec:
- Managing
- Conflict
type: string
valueHash:
description: ValueHash represents of a unique value for the
values section
format: byte
type: string
required:
- releaseName
- releaseNamespace
Expand Down Expand Up @@ -3444,10 +3443,10 @@ spec:
- --report-mode=0
- --shard-key=
- --v=5
- --version=main
- --version=dev
command:
- /manager
image: projectsveltos/addon-controller:main
image: projectsveltos/addon-controller:dev
livenessProbe:
failureThreshold: 3
httpGet:
Expand Down
Loading

0 comments on commit 99eee82

Please sign in to comment.