From 29cb6c7ee0012c2d8aa084aba4f8b00feef0c57f Mon Sep 17 00:00:00 2001 From: Jaylon McShan Date: Thu, 29 Aug 2024 10:21:51 -0700 Subject: [PATCH 1/4] Adding namespace_selector field. initial state --- kubernetes/schema_affinity_spec.go | 8 ++++++++ kubernetes/structure_label_selector.go | 26 ++++++++++++++++++++++++++ kubernetes/structures_affinity.go | 6 ++++++ 3 files changed, 40 insertions(+) diff --git a/kubernetes/schema_affinity_spec.go b/kubernetes/schema_affinity_spec.go index 10f3029dc8..04111a0532 100644 --- a/kubernetes/schema_affinity_spec.go +++ b/kubernetes/schema_affinity_spec.go @@ -166,6 +166,14 @@ func podAffinityTermFields() map[string]*schema.Schema { Schema: labelSelectorFields(true), }, }, + "namespace_selector": { + Type: schema.TypeList, + Description: "A label query over a set of namespaces that matches the namespaceSelector in Kubernetes.", + Optional: true, + Elem: &schema.Resource{ + Schema: labelSelectorFields(true), + }, + }, "namespaces": { Type: schema.TypeSet, Description: "namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace'", diff --git a/kubernetes/structure_label_selector.go b/kubernetes/structure_label_selector.go index f78e8ee2fa..1e20bf825e 100644 --- a/kubernetes/structure_label_selector.go +++ b/kubernetes/structure_label_selector.go @@ -21,6 +21,17 @@ func flattenLabelSelector(in *metav1.LabelSelector) []interface{} { return []interface{}{att} } +func flattenNamespaceSelector(in *metav1.LabelSelector) []interface{} { + att := make(map[string]interface{}) + if len(in.MatchLabels) > 0 { + att["match_labels"] = in.MatchLabels + } + if len(in.MatchExpressions) > 0 { + att["match_expressions"] = flattenLabelSelectorRequirement(in.MatchExpressions) + } + return []interface{}{att} +} + func flattenLabelSelectorRequirement(in []metav1.LabelSelectorRequirement) []interface{} { att := make([]interface{}, len(in)) for i, n := range in { @@ -50,6 +61,21 @@ func expandLabelSelector(l []interface{}) *metav1.LabelSelector { return obj } +func expandNamespaceSelector(n []interface{}) *metav1.LabelSelector { + if len(n) == 0 || n[0] == nil { + return &metav1.LabelSelector{} + } + in := n[0].(map[string]interface{}) + obj := &metav1.LabelSelector{} + if v, ok := in["match_labels"].(map[string]interface{}); ok && len(v) > 0 { + obj.MatchLabels = expandStringMap(v) + } + if v, ok := in["match_expressions"].([]interface{}); ok && len(v) > 0 { + obj.MatchExpressions = expandLabelSelectorRequirement(v) + } + return obj +} + func expandLabelSelectorRequirement(l []interface{}) []metav1.LabelSelectorRequirement { if len(l) == 0 || l[0] == nil { return []metav1.LabelSelectorRequirement{} diff --git a/kubernetes/structures_affinity.go b/kubernetes/structures_affinity.go index 366c7e2e65..778ff57f69 100644 --- a/kubernetes/structures_affinity.go +++ b/kubernetes/structures_affinity.go @@ -86,6 +86,9 @@ func flattenPodAffinityTerms(in []v1.PodAffinityTerm) []interface{} { m := make(map[string]interface{}) m["namespaces"] = newStringSet(schema.HashString, n.Namespaces) m["topology_key"] = n.TopologyKey + if n.NamespaceSelector != nil { + m["namespace_selector"] = flattenNamespaceSelector(n.NamespaceSelector) + } if n.LabelSelector != nil { m["label_selector"] = flattenLabelSelector(n.LabelSelector) } @@ -220,6 +223,9 @@ func expandPodAffinityTerms(t []interface{}) []v1.PodAffinityTerm { if v, ok := in["label_selector"].([]interface{}); ok && len(v) > 0 { obj[i].LabelSelector = expandLabelSelector(v) } + if v, ok := in["namespace_selector"].([]interface{}); ok && len(v) > 0 { + obj[i].NamespaceSelector = expandNamespaceSelector(v) + } if v, ok := in["namespaces"].(*schema.Set); ok { obj[i].Namespaces = sliceOfString(v.List()) } From 3ec2f92fa416a09fb989800a44c2cd1d70ce77e8 Mon Sep 17 00:00:00 2001 From: Jaylon McShan Date: Mon, 9 Sep 2024 09:08:17 -0700 Subject: [PATCH 2/4] Adding test case handling for namespace_selector field, and adding new field in MD --- docs/resources/deployment_v1.md | 16 +++++ docs/resources/stateful_set_v1.md | 16 +++++ ...esource_kubernetes_pod_v1_affinity_test.go | 64 +++++++++++++++++++ kubernetes/resource_kubernetes_pod_v1_test.go | 5 +- kubernetes/structure_label_selector.go | 7 +- 5 files changed, 104 insertions(+), 4 deletions(-) diff --git a/docs/resources/deployment_v1.md b/docs/resources/deployment_v1.md index fbff60a8ef..bc8ff7f61b 100644 --- a/docs/resources/deployment_v1.md +++ b/docs/resources/deployment_v1.md @@ -248,11 +248,15 @@ Required: Optional: - `label_selector` (Block List) A label query over a set of resources, in this case pods. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_affinity--preferred_during_scheduling_ignored_during_execution--pod_affinity_term--label_selector)) +- `namespace_selector` (Block List) A label query over a set of namespaces. This allows pod anti-affinity to select pods from a specified namespace, based on namespace labels. - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' ### Nested Schema for `spec.template.spec.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector` + +### Nested Schema for `spec.template.spec.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.namespace_selector` + Optional: - `match_expressions` (Block List) A list of label selector requirements. The requirements are ANDed. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_affinity--preferred_during_scheduling_ignored_during_execution--pod_affinity_term--label_selector--match_expressions)) @@ -281,11 +285,15 @@ Required: Optional: - `label_selector` (Block List) A label query over a set of resources, in this case pods. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_affinity--required_during_scheduling_ignored_during_execution--label_selector)) +- `namespace_selector` (Block List) A label query over a set of namespaces. This allows pod anti-affinity to select pods from a specified namespace, based on namespace labels. - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' ### Nested Schema for `spec.template.spec.affinity.pod_affinity.required_during_scheduling_ignored_during_execution.label_selector` + +### Nested Schema for `spec.template.spec.affinity.pod_affinity.required_during_scheduling_ignored_during_execution.namespace_selector` + Optional: - `match_expressions` (Block List) A list of label selector requirements. The requirements are ANDed. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_affinity--required_during_scheduling_ignored_during_execution--label_selector--match_expressions)) @@ -330,11 +338,15 @@ Required: Optional: - `label_selector` (Block List) A label query over a set of resources, in this case pods. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_anti_affinity--preferred_during_scheduling_ignored_during_execution--pod_affinity_term--label_selector)) +- `namespace_selector` (Block List) A label query over a set of namespaces. This allows pod anti-affinity to select pods from a specified namespace, based on namespace labels. - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' ### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector` + +### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.namespace_selector` + Optional: - `match_expressions` (Block List) A list of label selector requirements. The requirements are ANDed. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_anti_affinity--preferred_during_scheduling_ignored_during_execution--pod_affinity_term--label_selector--match_expressions)) @@ -363,11 +375,15 @@ Required: Optional: - `label_selector` (Block List) A label query over a set of resources, in this case pods. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_anti_affinity--required_during_scheduling_ignored_during_execution--label_selector)) +- `namespace_selector` (Block List) A label query over a set of namespaces. This allows pod anti-affinity to select pods from a specified namespace, based on namespace labels. - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' ### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.label_selector` + +### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.namespace_selector` + Optional: - `match_expressions` (Block List) A list of label selector requirements. The requirements are ANDed. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_anti_affinity--required_during_scheduling_ignored_during_execution--label_selector--match_expressions)) diff --git a/docs/resources/stateful_set_v1.md b/docs/resources/stateful_set_v1.md index c8b68bc5c6..17d0d8d1eb 100644 --- a/docs/resources/stateful_set_v1.md +++ b/docs/resources/stateful_set_v1.md @@ -272,11 +272,15 @@ Required: Optional: - `label_selector` (Block List) A label query over a set of resources, in this case pods. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_affinity--preferred_during_scheduling_ignored_during_execution--pod_affinity_term--label_selector)) +- `namespace_selector` (Block List) A label query over a set of namespaces. This allows pod affinity to select pods from a specified namespace, based on namespace labels. - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' ### Nested Schema for `spec.template.spec.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector` + +### Nested Schema for `spec.template.spec.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.namespace_selector` + Optional: - `match_expressions` (Block List) A list of label selector requirements. The requirements are ANDed. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_affinity--preferred_during_scheduling_ignored_during_execution--pod_affinity_term--label_selector--match_expressions)) @@ -305,11 +309,15 @@ Required: Optional: - `label_selector` (Block List) A label query over a set of resources, in this case pods. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_affinity--required_during_scheduling_ignored_during_execution--label_selector)) +- `namespace_selector` (Block List) A label query over a set of namespaces. This allows pod affinity to select pods from a specified namespace, based on namespace labels. - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' ### Nested Schema for `spec.template.spec.affinity.pod_affinity.required_during_scheduling_ignored_during_execution.label_selector` + +### Nested Schema for `spec.template.spec.affinity.pod_affinity.required_during_scheduling_ignored_during_execution.namespace_selector` + Optional: - `match_expressions` (Block List) A list of label selector requirements. The requirements are ANDed. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_affinity--required_during_scheduling_ignored_during_execution--label_selector--match_expressions)) @@ -354,11 +362,15 @@ Required: Optional: - `label_selector` (Block List) A label query over a set of resources, in this case pods. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_anti_affinity--preferred_during_scheduling_ignored_during_execution--pod_affinity_term--label_selector)) +- `namespace_selector` (Block List) A label query over a set of namespaces. This allows pod anti-affinity to select pods from a specified namespace, based on namespace labels. - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' ### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector` + +### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.namespace_selector` + Optional: - `match_expressions` (Block List) A list of label selector requirements. The requirements are ANDed. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_anti_affinity--preferred_during_scheduling_ignored_during_execution--pod_affinity_term--label_selector--match_expressions)) @@ -387,11 +399,15 @@ Required: Optional: - `label_selector` (Block List) A label query over a set of resources, in this case pods. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_anti_affinity--required_during_scheduling_ignored_during_execution--label_selector)) +- `namespace_selector` (Block List) A label query over a set of namespaces. This allows pod anti-affinity to select pods from a specified namespace, based on namespace labels. - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' ### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.label_selector` + +### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.namespace_selector` + Optional: - `match_expressions` (Block List) A list of label selector requirements. The requirements are ANDed. (see [below for nested schema](#nestedblock--spec--template--spec--affinity--pod_anti_affinity--required_during_scheduling_ignored_during_execution--label_selector--match_expressions)) diff --git a/kubernetes/resource_kubernetes_pod_v1_affinity_test.go b/kubernetes/resource_kubernetes_pod_v1_affinity_test.go index 33347554ee..d4f9cc9fd2 100644 --- a/kubernetes/resource_kubernetes_pod_v1_affinity_test.go +++ b/kubernetes/resource_kubernetes_pod_v1_affinity_test.go @@ -142,6 +142,12 @@ func TestAccKubernetesPodV1_with_pod_affinity_with_required_during_scheduling_ig resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.label_selector.0.match_expressions.0.values.0", keyName), "bar"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.label_selector.0.match_expressions.0.values.1", keyName), "foo"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.label_selector.0.match_labels.%%", keyName), "0"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespace_selector.#", keyName), "1"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespace_selector.0.match_expressions.#", keyName), "1"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespace_selector.0.match_expressions.0.key", keyName), "environment"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespace_selector.0.match_expressions.0.operator", keyName), "In"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespace_selector.0.match_expressions.0.values.#", keyName), "1"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespace_selector.0.match_expressions.0.values.0", keyName), "production"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespaces.#", keyName), "0"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.topology_key", keyName), "kubernetes.io/hostname"), ), @@ -178,6 +184,12 @@ func TestAccKubernetesPodV1_with_pod_affinity_with_preferred_during_scheduling_i resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.label_selector.0.match_expressions.0.values.0", keyName), "bar"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.label_selector.0.match_expressions.0.values.1", keyName), "foo"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.label_selector.0.match_labels.%%", keyName), "0"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespace_selector.#", keyName), "1"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespace_selector.0.match_expressions.#", keyName), "1"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespace_selector.0.match_expressions.0.key", keyName), "environment"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespace_selector.0.match_expressions.0.operator", keyName), "In"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespace_selector.0.match_expressions.0.values.#", keyName), "1"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespace_selector.0.match_expressions.0.values.0", keyName), "production"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespaces.#", keyName), "1"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespaces.0", keyName), "default"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.topology_key", keyName), "kubernetes.io/hostname"), @@ -215,6 +227,12 @@ func TestAccKubernetesPodV1_with_pod_anti_affinity_with_required_during_scheduli resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.label_selector.0.match_expressions.0.values.0", keyName), "bar"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.label_selector.0.match_expressions.0.values.1", keyName), "foo"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.label_selector.0.match_labels.%%", keyName), "0"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespace_selector.#", keyName), "1"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespace_selector.0.match_expressions.#", keyName), "1"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespace_selector.0.match_expressions.0.key", keyName), "environment"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespace_selector.0.match_expressions.0.operator", keyName), "In"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespace_selector.0.match_expressions.0.values.#", keyName), "1"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespace_selector.0.match_expressions.0.values.0", keyName), "production"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.namespaces.#", keyName), "0"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.topology_key", keyName), "kubernetes.io/hostname"), ), @@ -251,6 +269,12 @@ func TestAccKubernetesPodV1_with_pod_anti_affinity_with_preferred_during_schedul resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.label_selector.0.match_expressions.0.values.0", keyName), "bar"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.label_selector.0.match_expressions.0.values.1", keyName), "foo"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.label_selector.0.match_labels.%%", keyName), "0"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespace_selector.#", keyName), "1"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespace_selector.0.match_expressions.#", keyName), "1"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespace_selector.0.match_expressions.0.key", keyName), "environment"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespace_selector.0.match_expressions.0.operator", keyName), "In"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespace_selector.0.match_expressions.0.values.#", keyName), "1"), + resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespace_selector.0.match_expressions.0.values.0", keyName), "production"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.namespaces.#", keyName), "0"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.pod_affinity_term.0.topology_key", keyName), "kubernetes.io/hostname"), resource.TestCheckResourceAttr(resourceName, fmt.Sprintf("%s.0.weight", keyName), "100"), @@ -460,6 +484,9 @@ func testAccKubernetesPodV1ConfigWithPodAffinityWithRequiredDuringSchedulingIgno return fmt.Sprintf(`resource "kubernetes_namespace_v1" "test" { metadata { name = %[1]q + labels = { + environment = "production" + } } } @@ -482,6 +509,13 @@ resource "kubernetes_pod_v1" "test" { values = ["foo", "bar"] } } + namespace_selector { + match_expressions { + key = "environment" + operator = "In" + values = ["production"] + } + } topology_key = "kubernetes.io/hostname" } } @@ -507,6 +541,9 @@ func testAccKubernetesPodV1ConfigWithPodAffinityWithPreferredDuringSchedulingIgn return fmt.Sprintf(`resource "kubernetes_namespace_v1" "test" { metadata { name = %[1]q + labels = { + environment = "production" + } } } @@ -531,6 +568,13 @@ resource "kubernetes_pod_v1" "test" { values = ["foo", "bar"] } } + namespace_selector { + match_expressions { + key = "environment" + operator = "In" + values = ["production"] + } + } namespaces = ["default"] topology_key = "kubernetes.io/hostname" } @@ -558,6 +602,9 @@ func testAccKubernetesPodV1ConfigWithPodAntiAffinityWithRequiredDuringScheduling return fmt.Sprintf(`resource "kubernetes_namespace_v1" "test" { metadata { name = %[1]q + labels = { + environment = "production" + } } } @@ -580,6 +627,13 @@ resource "kubernetes_pod_v1" "test" { values = ["foo", "bar"] } } + namespace_selector { + match_expressions { + key = "environment" + operator = "In" + values = ["production"] + } + } topology_key = "kubernetes.io/hostname" } } @@ -605,6 +659,9 @@ func testAccKubernetesPodV1ConfigWithPodAntiAffinityWithPreferredDuringSchedulin return fmt.Sprintf(`resource "kubernetes_namespace_v1" "test" { metadata { name = %[1]q + labels = { + environment = "production" + } } } @@ -629,6 +686,13 @@ resource "kubernetes_pod_v1" "test" { values = ["foo", "bar"] } } + namespace_selector { + match_expressions { + key = "environment" + operator = "In" + values = ["production"] + } + } topology_key = "kubernetes.io/hostname" } } diff --git a/kubernetes/resource_kubernetes_pod_v1_test.go b/kubernetes/resource_kubernetes_pod_v1_test.go index 11ffe162d2..d1970deb96 100644 --- a/kubernetes/resource_kubernetes_pod_v1_test.go +++ b/kubernetes/resource_kubernetes_pod_v1_test.go @@ -10,12 +10,11 @@ import ( "regexp" "testing" - api "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + api "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestAccKubernetesPodV1_minimal(t *testing.T) { diff --git a/kubernetes/structure_label_selector.go b/kubernetes/structure_label_selector.go index 1e20bf825e..eaaeab9b24 100644 --- a/kubernetes/structure_label_selector.go +++ b/kubernetes/structure_label_selector.go @@ -65,7 +65,12 @@ func expandNamespaceSelector(n []interface{}) *metav1.LabelSelector { if len(n) == 0 || n[0] == nil { return &metav1.LabelSelector{} } - in := n[0].(map[string]interface{}) + + in, ok := n[0].(map[string]interface{}) + if !ok { + return &metav1.LabelSelector{} + } + obj := &metav1.LabelSelector{} if v, ok := in["match_labels"].(map[string]interface{}); ok && len(v) > 0 { obj.MatchLabels = expandStringMap(v) From 97d5286a95eddd9833aee6e611d5b9084f4a4b8a Mon Sep 17 00:00:00 2001 From: Jaylon McShan Date: Mon, 9 Sep 2024 13:54:01 -0700 Subject: [PATCH 3/4] Removing duplicate check, and adding changelog --- .changelog/2577.txt | 3 +++ kubernetes/structure_label_selector.go | 6 ++---- 2 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 .changelog/2577.txt diff --git a/.changelog/2577.txt b/.changelog/2577.txt new file mode 100644 index 0000000000..6220a04b64 --- /dev/null +++ b/.changelog/2577.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +Added support for `namespace_selector` field in `PodAffinityTerm` to enhance pod affinity and anti-affinity rules, allowing selection of namespaces based on label selectors. +``` \ No newline at end of file diff --git a/kubernetes/structure_label_selector.go b/kubernetes/structure_label_selector.go index eaaeab9b24..8dac60fc75 100644 --- a/kubernetes/structure_label_selector.go +++ b/kubernetes/structure_label_selector.go @@ -66,15 +66,13 @@ func expandNamespaceSelector(n []interface{}) *metav1.LabelSelector { return &metav1.LabelSelector{} } - in, ok := n[0].(map[string]interface{}) - if !ok { - return &metav1.LabelSelector{} - } + in := n[0].(map[string]interface{}) obj := &metav1.LabelSelector{} if v, ok := in["match_labels"].(map[string]interface{}); ok && len(v) > 0 { obj.MatchLabels = expandStringMap(v) } + //We are using labelSelector metav1, due to NamespaceSelector not existing as a type in metav1 if v, ok := in["match_expressions"].([]interface{}); ok && len(v) > 0 { obj.MatchExpressions = expandLabelSelectorRequirement(v) } From a06106d385e6010e3c28302dd13afd915a1d2032 Mon Sep 17 00:00:00 2001 From: Jaylon McShan Date: Mon, 9 Sep 2024 17:49:17 -0700 Subject: [PATCH 4/4] Fixing markdown, (Combining label selector and namespace selector into One nested schema header) --- docs/resources/deployment_v1.md | 16 ++++------------ docs/resources/stateful_set_v1.md | 16 ++++------------ 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/docs/resources/deployment_v1.md b/docs/resources/deployment_v1.md index bc8ff7f61b..5b8011dfbb 100644 --- a/docs/resources/deployment_v1.md +++ b/docs/resources/deployment_v1.md @@ -252,10 +252,8 @@ Optional: - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' -### Nested Schema for `spec.template.spec.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector` - -### Nested Schema for `spec.template.spec.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.namespace_selector` +### Nested Schema for `namespace_selector` and `label_selector` in `spec.template.spec.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term` Optional: @@ -289,10 +287,8 @@ Optional: - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' -### Nested Schema for `spec.template.spec.affinity.pod_affinity.required_during_scheduling_ignored_during_execution.label_selector` - -### Nested Schema for `spec.template.spec.affinity.pod_affinity.required_during_scheduling_ignored_during_execution.namespace_selector` +### Nested Schema for `namespace_selector` and `label_selector` in `spec.template.spec.affinity.pod_affinity.required_during_scheduling_ignored_during_execution` Optional: @@ -342,10 +338,8 @@ Optional: - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' -### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector` - -### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.namespace_selector` +### Nested Schema for `namespace_selector` and `label_selector` in `spec.template.spec.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term` Optional: @@ -379,10 +373,8 @@ Optional: - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' -### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.label_selector` - -### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.namespace_selector` +### Nested Schema for `namespace_selector` and `label_selector` in `spec.template.spec.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution` Optional: diff --git a/docs/resources/stateful_set_v1.md b/docs/resources/stateful_set_v1.md index 17d0d8d1eb..ae02088943 100644 --- a/docs/resources/stateful_set_v1.md +++ b/docs/resources/stateful_set_v1.md @@ -276,10 +276,8 @@ Optional: - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' -### Nested Schema for `spec.template.spec.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector` - -### Nested Schema for `spec.template.spec.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.namespace_selector` +### Nested Schema for `namespace_selector` and `label_selector` in `spec.template.spec.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term` Optional: @@ -313,10 +311,8 @@ Optional: - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' -### Nested Schema for `spec.template.spec.affinity.pod_affinity.required_during_scheduling_ignored_during_execution.label_selector` - -### Nested Schema for `spec.template.spec.affinity.pod_affinity.required_during_scheduling_ignored_during_execution.namespace_selector` +### Nested Schema for `namespace_selector` and `label_selector` in `spec.template.spec.affinity.pod_affinity.required_during_scheduling_ignored_during_execution` Optional: @@ -366,10 +362,8 @@ Optional: - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' -### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector` - -### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.namespace_selector` +### Nested Schema for `namespace_selector` and `label_selector` in `spec.template.spec.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term` Optional: @@ -403,10 +397,8 @@ Optional: - `namespaces` (Set of String) namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means 'this pod's namespace' -### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.label_selector` - -### Nested Schema for `spec.template.spec.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.namespace_selector` +### Nested Schema for `namespace_selector` and `label_selector` in `spec.template.spec.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution` Optional: