Skip to content

Add ManagedClusterLabels to hub template context #95

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
1 change: 1 addition & 0 deletions .github/workflows/kind.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
env:
REGISTRY: localhost:5000
strategy:
fail-fast: false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should have known this would be in here 😉

matrix:
# Run tests on minimum and newest supported OCP Kubernetes
# The "minimum" tag is set in the Makefile
Expand Down
33 changes: 28 additions & 5 deletions controllers/propagator/propagation.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"os"
"sort"
"strconv"
"strings"
"time"

templates "github.com/stolostron/go-template-utils/v3/pkg/templates"
Expand All @@ -21,6 +22,7 @@ import (
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
clusterv1 "open-cluster-management.io/api/cluster/v1"
clusterv1beta1 "open-cluster-management.io/api/cluster/v1beta1"
appsv1 "open-cluster-management.io/multicloud-operators-subscription/pkg/apis/apps/placementrule/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -860,10 +862,10 @@ func policyHasTemplates(instance *policiesv1.Policy) bool {
return false
}

// iterates through policy definitions and processes hub templates
// a special annotation policy.open-cluster-management.io/trigger-update is used to trigger reprocessing of the
// templates and ensuring that the replicated-policies in cluster is updated only if there is a change.
// this annotation is deleted from the replicated policies and not propagated to the cluster namespaces.
// Iterates through policy definitions and processes hub templates. A special annotation
// policy.open-cluster-management.io/trigger-update is used to trigger reprocessing of the templates
// and ensure that replicated-policies in the cluster are updated only if there is a change. This
// annotation is deleted from the replicated policies and not propagated to the cluster namespaces.
func (r *PolicyReconciler) processTemplates(
replicatedPlc *policiesv1.Policy, decision appsv1.PlacementDecision, rootPlc *policiesv1.Policy,
) (
Expand Down Expand Up @@ -934,11 +936,32 @@ func (r *PolicyReconciler) processTemplates(
log.V(1).Info("Found an object definition with templates")

templateContext := struct {
ManagedClusterName string
ManagedClusterName string
ManagedClusterLabels map[string]string
}{
ManagedClusterName: decision.ClusterName,
}

if strings.Contains(string(policyT.ObjectDefinition.Raw), "ManagedClusterLabels") {
templateRefObjs[k8sdepwatches.ObjectIdentifier{
Group: "cluster.open-cluster-management.io",
Version: "v1",
Kind: "ManagedCluster",
Namespace: "",
Name: decision.ClusterName,
}] = true

managedCluster := &clusterv1.ManagedCluster{}

err := r.Get(context.TODO(), types.NamespacedName{Name: decision.ClusterName}, managedCluster)
if err != nil {
log.Error(err, "Failed to get the ManagedCluster in order to use its labels in a hub template")
}

// if an error occurred, the ManagedClusterLabels will just be left empty
templateContext.ManagedClusterLabels = managedCluster.Labels
}

// Handle value encryption initialization
usesEncryption := templates.UsesEncryption(
policyT.ObjectDefinition.Raw, templateCfg.StartDelim, templateCfg.StopDelim,
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/prometheus/client_golang v1.12.1
github.com/spf13/pflag v1.0.5
github.com/stolostron/go-log-utils v0.1.1
github.com/stolostron/go-template-utils/v3 v3.0.1
github.com/stolostron/go-template-utils/v3 v3.1.0
github.com/stolostron/kubernetes-dependency-watches v0.2.0
k8s.io/api v0.23.9
k8s.io/apimachinery v0.23.9
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -479,8 +479,8 @@ github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stolostron/go-log-utils v0.1.1 h1:T48GyfuGpn2+6817FQVec1CyxGf0ibuVhoBiz9SeCec=
github.com/stolostron/go-log-utils v0.1.1/go.mod h1:2Uc5mbuLvSFpoXFFEKRTEFOlR7nqGVMu9mbU+FIttTI=
github.com/stolostron/go-template-utils/v3 v3.0.1 h1:E+BcQZubHmHWepXjqcSXUNPmzXoWzCLF3pO26w4NNVQ=
github.com/stolostron/go-template-utils/v3 v3.0.1/go.mod h1:k9qoQ/OH/jOQI5ovfC11QJ6ApWsa3E5rmbkfUAEUF3g=
github.com/stolostron/go-template-utils/v3 v3.1.0 h1:wizzuURDnI2fewOx/AxHLpKx06FXUGjkUnMjdcgat3o=
github.com/stolostron/go-template-utils/v3 v3.1.0/go.mod h1:k9qoQ/OH/jOQI5ovfC11QJ6ApWsa3E5rmbkfUAEUF3g=
github.com/stolostron/kubernetes-dependency-watches v0.2.0 h1:5MWK4xv5OOglyov7qoiKQ/M1Q5MTrEKSWuh/ed3zauQ=
github.com/stolostron/kubernetes-dependency-watches v0.2.0/go.mod h1:zFj8nBxKVn9QtmQIMlM0QSIqRSCKoMUtoY8G6Q+LJAc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/case14_root_policy_metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ var _ = Describe("Test root policy metrics", Ordered, func() {
By("Checking metric endpoint for root policy hub template watches")
Eventually(func() interface{} {
return utils.GetMetrics("hub_templates_active_watches", "\"[0-9]\"")
}, defaultTimeoutSeconds, 1).Should(Equal([]string{"2"}))
}, defaultTimeoutSeconds, 1).Should(Equal([]string{"3"}))
})

cleanup := func() {
Expand Down
50 changes: 36 additions & 14 deletions test/e2e/case9_templates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,22 @@ import (
)

const (
case9PolicyName = "case9-test-policy"
case9PolicyYaml = "../resources/case9_templates/case9-test-policy.yaml"
case9ReplicatedPolicyYamlM1 = "../resources/case9_templates/case9-test-replpolicy-managed1.yaml"
case9ReplicatedPolicyYamlM2 = "../resources/case9_templates/case9-test-replpolicy-managed2.yaml"
case9PolicyNameEncrypted = "case9-test-policy-encrypted"
case9PolicyYamlEncrypted = "../resources/case9_templates/case9-test-policy_encrypted.yaml"
case9PolicyYamlEncryptedRepl = "../resources/case9_templates/case9-test-replpolicy_encrypted-"
case9EncryptionSecret = "../resources/case9_templates/case9-test-encryption-secret.yaml"
case9EncryptionSecretName = "policy-encryption-key"
case9SecretName = "case9-secret"
IVAnnotation = "policy.open-cluster-management.io/encryption-iv"
case9PolicyName = "case9-test-policy"
case9PolicyYaml = "../resources/case9_templates/case9-test-policy.yaml"
case9ReplicatedPolicyYamlM1 = "../resources/case9_templates/case9-test-replpolicy-managed1.yaml"
case9ReplicatedPolicyYamlM1Update = "../resources/case9_templates/case9-test-replpolicy-managed1-relabelled.yaml"
case9ReplicatedPolicyYamlM2 = "../resources/case9_templates/case9-test-replpolicy-managed2.yaml"
case9PolicyNameEncrypted = "case9-test-policy-encrypted"
case9PolicyYamlEncrypted = "../resources/case9_templates/case9-test-policy_encrypted.yaml"
case9PolicyYamlEncryptedRepl = "../resources/case9_templates/case9-test-replpolicy_encrypted-"
case9EncryptionSecret = "../resources/case9_templates/case9-test-encryption-secret.yaml"
case9EncryptionSecretName = "policy-encryption-key"
case9SecretName = "case9-secret"
IVAnnotation = "policy.open-cluster-management.io/encryption-iv"
)

var _ = Describe("Test policy templates", func() {
Describe("Create policy, placement and referenced resource in ns:"+testNamespace, func() {
Describe("Create policy, placement and referenced resource in ns:"+testNamespace, Ordered, func() {
It("should be created in user ns", func() {
By("Creating " + case9PolicyYaml)
utils.Kubectl("apply",
Expand Down Expand Up @@ -73,6 +74,25 @@ var _ = Describe("Test policy templates", func() {
return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(yamlPlc.Object["spec"]))
})
It("should update the templated value when the managed cluster labels change", func() {
By("Updating the label on managed1")
utils.Kubectl("label", "managedcluster", "managed1", "vendor=Fake", "--overwrite")

By("Verifying the policy is updated")
yamlPlc := utils.ParseYaml(case9ReplicatedPolicyYamlM1Update)
Eventually(func() interface{} {
replicatedPlc := utils.GetWithTimeout(
clientHubDynamic,
gvrPolicy,
testNamespace+"."+case9PolicyName,
"managed1",
true,
defaultTimeoutSeconds,
)

return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(yamlPlc.Object["spec"]))
})
It("should resolve templates and propagate to cluster ns managed2", func() {
By("Patching test-policy-plr with decision of cluster managed2")
plr := utils.GetWithTimeout(
Expand Down Expand Up @@ -104,10 +124,12 @@ var _ = Describe("Test policy templates", func() {
return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(yamlPlc.Object["spec"]))
})
It("should clean up", func() {
AfterAll(func() {
utils.Kubectl("delete",
"-f", case9PolicyYaml,
"-n", testNamespace)
"-n", testNamespace,
"--ignore-not-found")
utils.Kubectl("label", "managedcluster", "managed1", "vendor=auto-detect", "--overwrite")
opt := metav1.ListOptions{}
utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, false, defaultTimeoutSeconds)
})
Expand Down
2 changes: 2 additions & 0 deletions test/resources/case9_templates/case9-test-policy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ spec:
{{hub fromConfigMap "policy-propagator-test" "case9-config2" "saying" | base64dec | indent 4 hub}}
autoindent-test: |
{{hub fromConfigMap "policy-propagator-test" "case9-config2" "saying" | base64dec | autoindent hub}}
label-vendor-test: |
{{hub .ManagedClusterLabels.vendor hub}}
---
apiVersion: policy.open-cluster-management.io/v1
kind: PlacementBinding
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
apiVersion: policy.open-cluster-management.io/v1
kind: Policy
metadata:
name: case9-test-policy
spec:
remediationAction: inform
disabled: false
policy-templates:
- objectDefinition:
apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
name: case9-test-configpolicy
spec:
remediationAction: inform
namespaceSelector:
exclude: ["kube-*"]
include: ["default"]
object-templates:
- complianceType: musthave
objectDefinition:
kind: ConfigMap
apiVersion: v1
metadata:
name: case9-test-configmap
namespace: test
data:
Clustername: managed1
Clusterid: '{{ fromClusterClaim id.openshift.io }}'
Vlanid: 123
indent-test: |
Do.
Or do not.
There is no try.
autoindent-test: |
Do.
Or do not.
There is no try.
label-vendor-test: |
Fake
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ spec:
Do.
Or do not.
There is no try.
label-vendor-test: |
auto-detect
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ spec:
Do.
Or do not.
There is no try.
label-vendor-test: |
auto-detect