From 5b182108e64a4baeeb6865d158e8602bebcba741 Mon Sep 17 00:00:00 2001 From: Sagar Muchhal Date: Tue, 2 Jul 2024 06:57:54 -0700 Subject: [PATCH] Extend cluster builtin to include UID This patch extends the cluster builtins to include the UID of the Cluster object. This can be used by the runtime extensions or JSON patches to set owner references on objects owned by the Cluster object. Signed-off-by: Sagar Muchhal --- .../cluster-class/write-clusterclass.md | 2 +- .../api/v1alpha1/topologymutation_variable_types.go | 5 +++++ .../hooks/api/v1alpha1/zz_generated.openapi.go | 7 +++++++ .../topology/cluster/patches/engine_test.go | 2 ++ .../topology/cluster/patches/variables/variables.go | 1 + .../cluster/patches/variables/variables_test.go | 12 ++++++++++++ internal/webhooks/patch_validation.go | 1 + 7 files changed, 29 insertions(+), 1 deletion(-) diff --git a/docs/book/src/tasks/experimental-features/cluster-class/write-clusterclass.md b/docs/book/src/tasks/experimental-features/cluster-class/write-clusterclass.md index 5e6f32acc61f..6ddb621c7abd 100644 --- a/docs/book/src/tasks/experimental-features/cluster-class/write-clusterclass.md +++ b/docs/book/src/tasks/experimental-features/cluster-class/write-clusterclass.md @@ -532,7 +532,7 @@ spec: In addition to variables specified in the ClusterClass, the following builtin variables can be referenced in patches: -- `builtin.cluster.{name,namespace}` +- `builtin.cluster.{name,namespace,uid}` - `builtin.cluster.topology.{version,class}` - `builtin.cluster.network.{serviceDomain,services,pods,ipFamily}` - `builtin.controlPlane.{replicas,version,name}` diff --git a/exp/runtime/hooks/api/v1alpha1/topologymutation_variable_types.go b/exp/runtime/hooks/api/v1alpha1/topologymutation_variable_types.go index caa2408cb9df..701499d8104a 100644 --- a/exp/runtime/hooks/api/v1alpha1/topologymutation_variable_types.go +++ b/exp/runtime/hooks/api/v1alpha1/topologymutation_variable_types.go @@ -16,6 +16,8 @@ limitations under the License. package v1alpha1 +import "k8s.io/apimachinery/pkg/types" + // BuiltinsName is the name of the builtin variable. const BuiltinsName = "builtin" @@ -35,6 +37,9 @@ type ClusterBuiltins struct { // Namespace is the namespace of the cluster. Namespace string `json:"namespace,omitempty"` + // UID is the unqiue identifier of the cluster. + UID types.UID `json:"uid,omitempty"` + // Topology represents the cluster topology variables. Topology *ClusterTopologyBuiltins `json:"topology,omitempty"` diff --git a/exp/runtime/hooks/api/v1alpha1/zz_generated.openapi.go b/exp/runtime/hooks/api/v1alpha1/zz_generated.openapi.go index 27ffa4288242..c8d991286cb1 100644 --- a/exp/runtime/hooks/api/v1alpha1/zz_generated.openapi.go +++ b/exp/runtime/hooks/api/v1alpha1/zz_generated.openapi.go @@ -781,6 +781,13 @@ func schema_runtime_hooks_api_v1alpha1_ClusterBuiltins(ref common.ReferenceCallb Format: "", }, }, + "uid": { + SchemaProps: spec.SchemaProps{ + Description: "UID is the unqiue identifier of the cluster.", + Type: []string{"string"}, + Format: "", + }, + }, "topology": { SchemaProps: spec.SchemaProps{ Description: "Topology represents the cluster topology variables.", diff --git a/internal/controllers/topology/cluster/patches/engine_test.go b/internal/controllers/topology/cluster/patches/engine_test.go index a288df6dc36c..563c5731c951 100644 --- a/internal/controllers/topology/cluster/patches/engine_test.go +++ b/internal/controllers/topology/cluster/patches/engine_test.go @@ -28,6 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/uuid" utilfeature "k8s.io/component-base/featuregate/testing" "k8s.io/utils/ptr" . "sigs.k8s.io/controller-runtime/pkg/envtest/komega" @@ -1073,6 +1074,7 @@ func setupTestObjects() (*scope.ClusterBlueprint, *scope.ClusterState) { ObjectMeta: metav1.ObjectMeta{ Name: "cluster1", Namespace: metav1.NamespaceDefault, + UID: uuid.NewUUID(), }, Spec: clusterv1.ClusterSpec{ Paused: false, diff --git a/internal/controllers/topology/cluster/patches/variables/variables.go b/internal/controllers/topology/cluster/patches/variables/variables.go index e47380e12d92..f5ca9b110220 100644 --- a/internal/controllers/topology/cluster/patches/variables/variables.go +++ b/internal/controllers/topology/cluster/patches/variables/variables.go @@ -61,6 +61,7 @@ func Global(clusterTopology *clusterv1.Topology, cluster *clusterv1.Cluster, def Cluster: &runtimehooksv1.ClusterBuiltins{ Name: cluster.Name, Namespace: cluster.Namespace, + UID: cluster.UID, Topology: &runtimehooksv1.ClusterTopologyBuiltins{ Version: cluster.Spec.Topology.Version, Class: cluster.Spec.Topology.Class, diff --git a/internal/controllers/topology/cluster/patches/variables/variables_test.go b/internal/controllers/topology/cluster/patches/variables/variables_test.go index f564df166393..1e3c0286dd27 100644 --- a/internal/controllers/topology/cluster/patches/variables/variables_test.go +++ b/internal/controllers/topology/cluster/patches/variables/variables_test.go @@ -25,6 +25,7 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" @@ -34,6 +35,7 @@ import ( ) func TestGlobal(t *testing.T) { + clusterUID := "8a35f406-6b9b-4b78-8c93-a7f878d90623" tests := []struct { name string clusterTopology *clusterv1.Topology @@ -68,6 +70,7 @@ func TestGlobal(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cluster1", Namespace: metav1.NamespaceDefault, + UID: types.UID(clusterUID), }, Spec: clusterv1.ClusterSpec{ Topology: &clusterv1.Topology{ @@ -100,6 +103,7 @@ func TestGlobal(t *testing.T) { "cluster":{ "name": "cluster1", "namespace": "default", + "uid": "8a35f406-6b9b-4b78-8c93-a7f878d90623", "topology":{ "version": "v1.21.1", "class": "clusterClass1" @@ -149,6 +153,7 @@ func TestGlobal(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cluster1", Namespace: metav1.NamespaceDefault, + UID: types.UID(clusterUID), }, Spec: clusterv1.ClusterSpec{ Topology: &clusterv1.Topology{ @@ -181,6 +186,7 @@ func TestGlobal(t *testing.T) { "cluster":{ "name": "cluster1", "namespace": "default", + "uid": "8a35f406-6b9b-4b78-8c93-a7f878d90623", "topology":{ "version": "v1.21.1", "class": "clusterClass1" @@ -221,6 +227,7 @@ func TestGlobal(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cluster1", Namespace: metav1.NamespaceDefault, + UID: types.UID(clusterUID), }, Spec: clusterv1.ClusterSpec{ Topology: &clusterv1.Topology{ @@ -252,6 +259,7 @@ func TestGlobal(t *testing.T) { "cluster":{ "name": "cluster1", "namespace": "default", + "uid": "8a35f406-6b9b-4b78-8c93-a7f878d90623", "topology":{ "version": "v1.21.1", "class": "clusterClass1" @@ -291,6 +299,7 @@ func TestGlobal(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cluster1", Namespace: metav1.NamespaceDefault, + UID: types.UID(clusterUID), }, Spec: clusterv1.ClusterSpec{ Topology: &clusterv1.Topology{ @@ -319,6 +328,7 @@ func TestGlobal(t *testing.T) { "cluster":{ "name": "cluster1", "namespace": "default", + "uid": "8a35f406-6b9b-4b78-8c93-a7f878d90623", "topology":{ "version": "v1.21.1", "class": "clusterClass1" @@ -357,6 +367,7 @@ func TestGlobal(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cluster1", Namespace: metav1.NamespaceDefault, + UID: types.UID(clusterUID), }, Spec: clusterv1.ClusterSpec{ Topology: &clusterv1.Topology{ @@ -381,6 +392,7 @@ func TestGlobal(t *testing.T) { "cluster":{ "name": "cluster1", "namespace": "default", + "uid": "8a35f406-6b9b-4b78-8c93-a7f878d90623", "topology":{ "version": "v1.21.1", "class": "clusterClass1" diff --git a/internal/webhooks/patch_validation.go b/internal/webhooks/patch_validation.go index f7e2166ee458..2fee9ea73913 100644 --- a/internal/webhooks/patch_validation.go +++ b/internal/webhooks/patch_validation.go @@ -471,6 +471,7 @@ var builtinVariables = sets.Set[string]{}.Insert( "builtin.cluster", "builtin.cluster.name", "builtin.cluster.namespace", + "builtin.cluster.uid", // ClusterTopology builtins. "builtin.cluster.topology",