Skip to content
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

Add additional_pod_ranges_config field #8622

Merged
merged 5 commits into from
Aug 22, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -1576,6 +1576,23 @@ func ResourceContainerCluster() *schema.Resource {
},
},
},
"additional_pod_ranges_config": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Description: `AdditionalPodRangesConfig is the configuration for additional pod secondary ranges supporting the ClusterUpdate message.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"pod_range_names": {
Type: schema.TypeSet,
MinItems: 1,
Required: true,
Elem: &schema.Schema{Type: schema.TypeString},
Description: `Name for pod secondary ipv4 range which has the actual range defined ahead.`,
},
},
},
},
},
},
},
Expand Down Expand Up @@ -2433,6 +2450,38 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
}
}

if names, ok := d.GetOk("ip_allocation_policy.0.additional_pod_ranges_config.0.pod_range_names"); ok {
name := containerClusterFullName(project, location, clusterName)
additionalPodRangesConfig := &container.AdditionalPodRangesConfig{
PodRangeNames: tpgresource.ConvertStringSet(names.(*schema.Set)),
}

req := &container.UpdateClusterRequest{
Update: &container.ClusterUpdate{
AdditionalPodRangesConfig: additionalPodRangesConfig,
},
}

err = transport_tpg.Retry(transport_tpg.RetryOptions{
RetryFunc: func() error {
clusterUpdateCall := config.NewContainerClient(userAgent).Projects.Locations.Clusters.Update(name, req)
if config.UserProjectOverride {
clusterUpdateCall.Header().Add("X-Goog-User-Project", project)
}
op, err = clusterUpdateCall.Do()
return err
},
})
if err != nil {
return errwrap.Wrapf("Error updating AdditionalPodRangesConfig: {{err}}", err)
}

err = ContainerOperationWait(config, op, project, location, "updating AdditionalPodRangesConfig", userAgent, d.Timeout(schema.TimeoutCreate))
if err != nil {
return errwrap.Wrapf("Error while waiting to update AdditionalPodRangesConfig: {{err}}", err)
}
}

if err := resourceContainerClusterRead(d, meta); err != nil {
return err
}
Expand Down Expand Up @@ -3355,6 +3404,51 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er

}

if d.HasChange("ip_allocation_policy.0.additional_pod_ranges_config") {
o, n := d.GetChange("ip_allocation_policy.0.additional_pod_ranges_config.0.pod_range_names")
old_names := o.(*schema.Set)
new_names := n.(*schema.Set)

// Filter unchanged names.
removed_names := old_names.Difference(new_names)
added_names := new_names.Difference(old_names)

var additional_config *container.AdditionalPodRangesConfig
var removed_config *container.AdditionalPodRangesConfig
if added_names.Len() > 0 {
var names []string
for _, name := range added_names.List() {
names = append(names, name.(string))
}
additional_config = &container.AdditionalPodRangesConfig{
PodRangeNames: names,
}
}
if removed_names.Len() > 0 {
var names []string
for _, name := range removed_names.List() {
names = append(names, name.(string))
}
removed_config = &container.AdditionalPodRangesConfig{
PodRangeNames: names,
}
}
req := &container.UpdateClusterRequest{
Update: &container.ClusterUpdate{
AdditionalPodRangesConfig: additional_config,
RemovedAdditionalPodRangesConfig: removed_config,
},
}

updateF := updateFunc(req, "updating AdditionalPodRangesConfig")
// Call update serially.
if err := transport_tpg.LockedCall(lockKey, updateF); err != nil {
return err
}

log.Printf("[INFO] GKE cluster %s's AdditionalPodRangesConfig has been updated", d.Id())
}

if n, ok := d.GetOk("node_pool.#"); ok {
for i := 0; i < n.(int); i++ {
nodePoolInfo, err := extractNodePoolInformationFromCluster(d, config, clusterName)
Expand Down Expand Up @@ -4649,6 +4743,25 @@ func flattenSecurityPostureConfig(spc *container.SecurityPostureConfig) []map[st
return []map[string]interface{}{result}
}

func flattenAdditionalPodRangesConfig(ipAllocationPolicy *container.IPAllocationPolicy) []map[string]interface{} {
if ipAllocationPolicy == nil {
return nil
}
result := make(map[string]interface{})

if aprc := ipAllocationPolicy.AdditionalPodRangesConfig; aprc != nil {
if len(aprc.PodRangeNames) > 0 {
result["pod_range_names"] = aprc.PodRangeNames
} else {
return nil
}
} else {
return nil
}

return []map[string]interface{}{result}
}

func expandNotificationConfig(configured interface{}) *container.NotificationConfig {
l := configured.([]interface{})
if len(l) == 0 || l[0] == nil {
Expand Down Expand Up @@ -5550,6 +5663,7 @@ func flattenIPAllocationPolicy(c *container.Cluster, d *schema.ResourceData, con
"services_secondary_range_name": p.ServicesSecondaryRangeName,
"stack_type": p.StackType,
"pod_cidr_overprovision_config": flattenPodCidrOverprovisionConfig(p.PodCidrOverprovisionConfig),
"additional_pod_ranges_config": flattenAdditionalPodRangesConfig(c.IpAllocationPolicy),
},
}, nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3924,6 +3924,80 @@ func TestAccContainerCluster_autopilot_net_admin(t *testing.T) {
})
}

func TestAccContainerCluster_additional_pod_ranges_config_on_create(t *testing.T) {
t.Parallel()

clusterName := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10))
acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccContainerCluster_additional_pod_ranges_config(clusterName, 1),
},
{
ResourceName: "google_container_cluster.primary",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccContainerCluster_additional_pod_ranges_config_on_update(t *testing.T) {
t.Parallel()

clusterName := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10))
acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccContainerCluster_additional_pod_ranges_config(clusterName, 0),
},
{
ResourceName: "google_container_cluster.primary",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccContainerCluster_additional_pod_ranges_config(clusterName, 2),
},
{
ResourceName: "google_container_cluster.primary",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccContainerCluster_additional_pod_ranges_config(clusterName, 0),
},
{
ResourceName: "google_container_cluster.primary",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccContainerCluster_additional_pod_ranges_config(clusterName, 1),
},
{
ResourceName: "google_container_cluster.primary",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccContainerCluster_additional_pod_ranges_config(clusterName, 0),
},
{
ResourceName: "google_container_cluster.primary",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccContainerCluster_masterAuthorizedNetworksDisabled(t *testing.T, resource_name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resource_name]
Expand Down Expand Up @@ -8061,3 +8135,83 @@ resource "google_container_cluster" "cluster" {
}
}`, policyName, cluster, np)
}

func testAccContainerCluster_additional_pod_ranges_config(name string, nameCount int) string {
var podRangeNamesStr string
names := []string{"\"gke-autopilot-pods-add\",", "\"gke-autopilot-pods-add-2\""}
for i := 0; i < nameCount; i++ {
podRangeNamesStr += names[i]
}
var aprc string
if len(podRangeNamesStr) > 0 {
aprc = fmt.Sprintf(`
additional_pod_ranges_config {
pod_range_names = [%s]
}
`, podRangeNamesStr)
}

return fmt.Sprintf(`
resource "google_compute_network" "main" {
name = "%s"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "main" {
ip_cidr_range = "10.10.0.0/16"
name = "%s"
network = google_compute_network.main.self_link
region = "us-central1"

secondary_ip_range {
range_name = "gke-autopilot-services"
ip_cidr_range = "10.11.0.0/20"
}

secondary_ip_range {
range_name = "gke-autopilot-pods"
ip_cidr_range = "10.12.0.0/16"
}

secondary_ip_range {
range_name = "gke-autopilot-pods-add"
ip_cidr_range = "10.100.0.0/16"
}
secondary_ip_range {
range_name = "gke-autopilot-pods-add-2"
ip_cidr_range = "100.0.0.0/16"
}
}
resource "google_container_cluster" "primary" {
name = "%s"
location = "us-central1"

enable_autopilot = true

release_channel {
channel = "REGULAR"
}

network = google_compute_network.main.name
subnetwork = google_compute_subnetwork.main.name

private_cluster_config {
enable_private_endpoint = false
enable_private_nodes = true
master_ipv4_cidr_block = "172.16.0.0/28"
}

# supresses permadiff
dns_config {
cluster_dns = "CLOUD_DNS"
cluster_dns_domain = "cluster.local"
cluster_dns_scope = "CLUSTER_SCOPE"
}

ip_allocation_policy {
cluster_secondary_range_name = "gke-autopilot-pods"
services_secondary_range_name = "gke-autopilot-services"
%s
}
}
`, name, name, name, aprc)
}
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,16 @@ pick a specific range to use.
Default value is `IPV4`.
Possible values are `IPV4` and `IPV4_IPV6`.

* `additional_pod_ranges_config` - (Optional) The configuration for additional pod secondary ranges at
the cluster level. Used for Autopilot clusters and Standard clusters with which control of the
secondary Pod IP address assignment to node pools isn't needed. Structure is [documented below](#nested_additional_pod_ranges_config).


<a name="nested_additional_pod_ranges_config"></a>The `additional_pod_ranges_config` block supports:

* `pod_range_names` - (Required) The names of the Pod ranges to add to the cluster.


<a name="nested_master_auth"></a>The `master_auth` block supports:

* `client_certificate_config` - (Required) Whether client certificate authorization is enabled for this cluster. For example:
Expand Down