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)