diff --git a/docs/data-sources/tanzu_kubernetes_cluster.md b/docs/data-sources/tanzu_kubernetes_cluster.md index e0bbdb433..f27062027 100644 --- a/docs/data-sources/tanzu_kubernetes_cluster.md +++ b/docs/data-sources/tanzu_kubernetes_cluster.md @@ -100,6 +100,7 @@ Optional: - `meta` (Block List, Max: 1) Metadata for the resource (see [below for nested schema](#nestedblock--spec--topology--control_plane--meta)) - `os_image` (Block List, Max: 1) OS image block (see [below for nested schema](#nestedblock--spec--topology--control_plane--os_image)) +- `overrides` (String) Overrides can be used to override cluster level variables. ### Nested Schema for `spec.topology.control_plane.meta` diff --git a/docs/resources/tanzu_kubernetes_cluster.md b/docs/resources/tanzu_kubernetes_cluster.md index 3b939f231..15b35cd75 100644 --- a/docs/resources/tanzu_kubernetes_cluster.md +++ b/docs/resources/tanzu_kubernetes_cluster.md @@ -398,6 +398,7 @@ Optional: - `meta` (Block List, Max: 1) Metadata for the resource (see [below for nested schema](#nestedblock--spec--topology--control_plane--meta)) - `os_image` (Block List, Max: 1) OS image block (see [below for nested schema](#nestedblock--spec--topology--control_plane--os_image)) +- `overrides` (String) Overrides can be used to override cluster level variables. ### Nested Schema for `spec.topology.control_plane.meta` diff --git a/internal/models/tanzukubernetescluster/control_plane.go b/internal/models/tanzukubernetescluster/control_plane.go index c893435dc..97d299b11 100644 --- a/internal/models/tanzukubernetescluster/control_plane.go +++ b/internal/models/tanzukubernetescluster/control_plane.go @@ -21,6 +21,9 @@ type VmwareTanzuManageV1alpha1ManagementClusterProvisionerTanzukubernetesCluster // The OS image of the control plane. OsImage *tkccommon.VmwareTanzuManageV1alpha1ManagementClusterProvisionerTanzukubernetesClusterCommonClusterOSImage `json:"osImage,omitempty"` + // Overrides can be used to override cluster level variables. + Overrides []*tkccommon.VmwareTanzuManageV1alpha1ManagementClusterProvisionerTanzukubernetesClusterCommonClusterClusterVariable `json:"overrides"` + // The replicas of the control plane. Replicas int32 `json:"replicas,omitempty"` } diff --git a/internal/resources/tanzukubernetescluster/converter_mapping.go b/internal/resources/tanzukubernetescluster/converter_mapping.go index bf0d744f6..fd8821ec6 100644 --- a/internal/resources/tanzukubernetescluster/converter_mapping.go +++ b/internal/resources/tanzukubernetescluster/converter_mapping.go @@ -78,6 +78,10 @@ var tfModelResourceMap = &tfModelConverterHelper.BlockToStruct{ common.LabelsKey: tfModelConverterHelper.BuildDefaultModelPath("spec", "topology", "controlPlane", "metadata", "labels"), common.AnnotationsKey: tfModelConverterHelper.BuildDefaultModelPath("spec", "topology", "controlPlane", "metadata", "annotations"), }, + OverridesKey: &tfModelConverterHelper.EvaluatedField{ + Field: tfModelConverterHelper.BuildDefaultModelPath("spec", "topology", "controlPlane", tfModelConverterHelper.BuildArrayField("overrides")), + EvalFunc: tfModelConverterHelper.EvaluationFunc(evaluateClusterVariables), + }, }, ClusterVariablesKey: &tfModelConverterHelper.EvaluatedField{ Field: tfModelConverterHelper.BuildDefaultModelPath("spec", "topology", tfModelConverterHelper.BuildArrayField("variables")), diff --git a/internal/resources/tanzukubernetescluster/helper.go b/internal/resources/tanzukubernetescluster/helper.go index 8a047c7ac..bb932ae93 100644 --- a/internal/resources/tanzukubernetescluster/helper.go +++ b/internal/resources/tanzukubernetescluster/helper.go @@ -393,25 +393,41 @@ func removeUnspecifiedNodePoolsOverrides(nodePools []interface{}, kubernetesClus tfNodePoolOverrides := tfNodePoolSpec[OverridesKey] if tfNodePoolOverrides != nil && tfNodePoolOverrides.(string) != "" { - tfOverridesVariablesJSON := make(map[string]interface{}) - _ = json.Unmarshal([]byte(tfNodePoolOverrides.(string)), &tfOverridesVariablesJSON) + overridesToKeep := excludeUnspecifiedOverrides(tfNodePoolOverrides.(string), kubernetesClusterModel.Spec.Topology.NodePools[i].Spec.Overrides) + kubernetesClusterModel.Spec.Topology.NodePools[i].Spec.Overrides = overridesToKeep + } + } +} - overridesToKeep := make([]*tkccommonmodels.VmwareTanzuManageV1alpha1ManagementClusterProvisionerTanzukubernetesClusterCommonClusterClusterVariable, 0) +// removeUnspecifiedControlPlaneOverrides removed node pools overrides returning in the API which do not exist in the Cluster Class schema. +func removeUnspecifiedControlPlaneOverrides(controlPlane interface{}, kubernetesClusterModel *tanzukubernetesclustermodels.VmwareTanzuManageV1alpha1ManagementClusterProvisionerTanzukubernetesClusterTanzuKubernetesCluster) { + tfControlPlaneOverrides := controlPlane.(map[string]interface{})[OverridesKey] - for _, modelOverride := range kubernetesClusterModel.Spec.Topology.NodePools[i].Spec.Overrides { - varKey := modelOverride.Name + if tfControlPlaneOverrides != nil && tfControlPlaneOverrides.(string) != "" { + overridesToKeep := excludeUnspecifiedOverrides(tfControlPlaneOverrides.(string), kubernetesClusterModel.Spec.Topology.ControlPlane.Overrides) + kubernetesClusterModel.Spec.Topology.ControlPlane.Overrides = overridesToKeep + } +} - if tfOverridesVariableValue, exist := tfOverridesVariablesJSON[varKey]; exist { - // This is necessary because some inner values have defaults and are being returned even when not filled - modifiedModelVariableValue := modifyModelVariable(tfOverridesVariableValue, modelOverride.Value) - modelOverride.Value = modifiedModelVariableValue - overridesToKeep = append(overridesToKeep, modelOverride) - } - } +// excludeUnspecifiedOverrides removed overrides returning in the API which do not exist in the Cluster Class schema. +func excludeUnspecifiedOverrides(overridesResource string, overrides []*tkccommonmodels.VmwareTanzuManageV1alpha1ManagementClusterProvisionerTanzukubernetesClusterCommonClusterClusterVariable) []*tkccommonmodels.VmwareTanzuManageV1alpha1ManagementClusterProvisionerTanzukubernetesClusterCommonClusterClusterVariable { + tfOverridesVariablesJSON := make(map[string]interface{}) + _ = json.Unmarshal([]byte(overridesResource), &tfOverridesVariablesJSON) - kubernetesClusterModel.Spec.Topology.NodePools[i].Spec.Overrides = overridesToKeep + overridesToKeep := make([]*tkccommonmodels.VmwareTanzuManageV1alpha1ManagementClusterProvisionerTanzukubernetesClusterCommonClusterClusterVariable, 0) + + for _, modelOverride := range overrides { + varKey := modelOverride.Name + + if tfOverridesVariableValue, exist := tfOverridesVariablesJSON[varKey]; exist { + // This is necessary because some inner values have defaults and are being returned even when not filled + modifiedModelVariableValue := modifyModelVariable(tfOverridesVariableValue, modelOverride.Value) + modelOverride.Value = modifiedModelVariableValue + overridesToKeep = append(overridesToKeep, modelOverride) } } + + return overridesToKeep } // modifyModelVariable helps when certain variables do no return from the API or in a case where some values are returning diff --git a/internal/resources/tanzukubernetescluster/resource_tanzu_kuberenetes_cluster.go b/internal/resources/tanzukubernetescluster/resource_tanzu_kuberenetes_cluster.go index f4aa4dc19..eb100b0b8 100644 --- a/internal/resources/tanzukubernetescluster/resource_tanzu_kuberenetes_cluster.go +++ b/internal/resources/tanzukubernetescluster/resource_tanzu_kuberenetes_cluster.go @@ -147,9 +147,11 @@ func resourceTanzuKubernetesClusterRead(ctx context.Context, data *schema.Resour specData := data.Get(SpecKey).([]interface{})[0].(map[string]interface{}) topologyData := specData[TopologyKey].([]interface{})[0].(map[string]interface{}) clusterVariablesData := topologyData[ClusterVariablesKey].(string) + controlPlaneData := topologyData[ControlPlaneKey].([]interface{})[0] nodePoolsData := topologyData[NodePoolKey].([]interface{}) removeUnspecifiedClusterVariables(clusterVariablesData, kubernetesClusterModel) + removeUnspecifiedControlPlaneOverrides(controlPlaneData, kubernetesClusterModel) removeUnspecifiedNodePoolsOverrides(nodePoolsData, kubernetesClusterModel) err = tfModelResourceConverter.FillTFSchema(kubernetesClusterModel, data) diff --git a/internal/resources/tanzukubernetescluster/schema.go b/internal/resources/tanzukubernetescluster/schema.go index 0e4cbfe00..9a1f91bb2 100644 --- a/internal/resources/tanzukubernetescluster/schema.go +++ b/internal/resources/tanzukubernetescluster/schema.go @@ -21,12 +21,13 @@ const ( ResourceName = "tanzu-mission-control_tanzu_kubernetes_cluster" // Common Keys. - NameKey = "name" - SpecKey = "spec" - VersionKey = "version" - ReplicasKey = "replicas" - OSImageKey = "os_image" - OSArchKey = "arch" + NameKey = "name" + SpecKey = "spec" + VersionKey = "version" + ReplicasKey = "replicas" + OSImageKey = "os_image" + OSArchKey = "arch" + OverridesKey = "overrides" // Root Keys. ManagementClusterNameKey = "management_cluster_name" @@ -57,7 +58,6 @@ const ( // Node Pool Directive Keys. WorkerClassKey = "worker_class" FailureDomainKey = "failure_domain" - OverridesKey = "overrides" // Network Directive Keys. PodCIDRBlocksKey = "pod_cidr_blocks" @@ -266,6 +266,14 @@ var ControlPlaneSchema = &schema.Schema{ ReplicasKey: ReplicasSchema, OSImageKey: OSImageSchema, common.MetaKey: common.Meta, + OverridesKey: { + Type: schema.TypeString, + Description: "Overrides can be used to override cluster level variables.", + Optional: true, + ValidateDiagFunc: validateJSONString, + DiffSuppressOnRefresh: true, + DiffSuppressFunc: isVariablesValuesEqual, + }, }, }, } diff --git a/internal/resources/tanzukubernetescluster/tests/cluster_env_vars.go b/internal/resources/tanzukubernetescluster/tests/cluster_env_vars.go index f5946a593..33cd83c74 100644 --- a/internal/resources/tanzukubernetescluster/tests/cluster_env_vars.go +++ b/internal/resources/tanzukubernetescluster/tests/cluster_env_vars.go @@ -37,6 +37,7 @@ const ( TKGSOSImageVersionEnv ClusterEnvVar = "TKGS_OS_IMAGE_VERSION" TKGSOSImageArchEnv ClusterEnvVar = "TKGS_OS_IMAGE_ARCH" TKGSWorkerClassEnv ClusterEnvVar = "TKGS_WORKER_CLASS" + TKGSControlPlaneOverridesEnv ClusterEnvVar = "TKGS_CONTROL_PLANE_OVERRIDES" TKGSNodePoolOverridesEnv ClusterEnvVar = "TKGS_NODE_POOL_OVERRIDES" ) @@ -81,7 +82,8 @@ var ( TKGSWorkerClassEnv: true, }, OptionalEnvVar: { - TKGSNodePoolOverridesEnv: true, + TKGSControlPlaneOverridesEnv: true, + TKGSNodePoolOverridesEnv: true, }, }, } diff --git a/internal/resources/tanzukubernetescluster/tests/resource_tf_configs.go b/internal/resources/tanzukubernetescluster/tests/resource_tf_configs.go index 5fd27cbc4..c145d83fe 100644 --- a/internal/resources/tanzukubernetescluster/tests/resource_tf_configs.go +++ b/internal/resources/tanzukubernetescluster/tests/resource_tf_configs.go @@ -168,6 +168,8 @@ func (builder *ResourceTFConfigBuilder) GetTKGSClusterConfig(tkgsEnvVars map[Clu version = "%s" arch = "%s" } + + overrides = jsonencode(%s) } %s @@ -199,6 +201,7 @@ func (builder *ResourceTFConfigBuilder) GetTKGSClusterConfig(tkgsEnvVars map[Clu tkgsEnvVars[TKGSOSImageNameEnv], tkgsEnvVars[TKGSOSImageVersionEnv], tkgsEnvVars[TKGSOSImageArchEnv], + tkgsEnvVars[TKGSControlPlaneOverridesEnv], nodePools, ) }