Skip to content

Commit 0233533

Browse files
Add support for flexible clusters - public/private clusters toggle (#6780) (#4921)
Signed-off-by: Modular Magician <[email protected]> Signed-off-by: Modular Magician <[email protected]>
1 parent 49f1d11 commit 0233533

File tree

7 files changed

+483
-49
lines changed

7 files changed

+483
-49
lines changed

.changelog/6780.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
```release-note:enhancement
2+
container: added field `gcp_public_cidrs_access_enabled` and `private_endpoint_subnetwork` to `google_container_cluster`
3+
```
4+
```release-note:enhancement
5+
container: added update support for `enable_private_endpoint` and `enable_private_nodes` in `google_container_cluster`
6+
```
7+
```release-note:enhancement
8+
container: promoted `network_config` in `google_container_node_pool` to GA.
9+
```
10+
```release-note:enhancement
11+
container: added field `enable_private_nodes` in `network_config` to `google_container_node_pool`
12+
```

google-beta/resource_container_cluster.go

Lines changed: 88 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,23 @@ import (
2222
var (
2323
instanceGroupManagerURL = regexp.MustCompile(fmt.Sprintf("projects/(%s)/zones/([a-z0-9-]*)/instanceGroupManagers/([^/]*)", ProjectRegex))
2424

25-
networkConfig = &schema.Resource{
25+
masterAuthorizedNetworksConfig = &schema.Resource{
2626
Schema: map[string]*schema.Schema{
2727
"cidr_blocks": {
2828
Type: schema.TypeSet,
29-
// Despite being the only entry in a nested block, this should be kept
30-
// Optional. Expressing the parent with no entries and omitting the
29+
// This should be kept Optional. Expressing the
30+
// parent with no entries and omitting the
3131
// parent entirely are semantically different.
3232
Optional: true,
3333
Elem: cidrBlockConfig,
3434
Description: `External networks that can access the Kubernetes cluster master through HTTPS.`,
3535
},
36+
"gcp_public_cidrs_access_enabled": {
37+
Type: schema.TypeBool,
38+
Optional: true,
39+
Computed: true,
40+
Description: `Whether master is accessbile via Google Compute Engine Public IP addresses.`,
41+
},
3642
},
3743
}
3844
cidrBlockConfig = &schema.Resource{
@@ -68,6 +74,14 @@ var (
6874
"addons_config.0.gke_backup_agent_config",
6975
}
7076

77+
privateClusterConfigKeys = []string{
78+
"private_cluster_config.0.enable_private_endpoint",
79+
"private_cluster_config.0.enable_private_nodes",
80+
"private_cluster_config.0.master_ipv4_cidr_block",
81+
"private_cluster_config.0.private_endpoint_subnetwork",
82+
"private_cluster_config.0.master_global_access_config",
83+
}
84+
7185
forceNewClusterNodeConfigFields = []string{
7286
"workload_metadata_config",
7387
}
@@ -1061,8 +1075,9 @@ func resourceContainerCluster() *schema.Resource {
10611075
"master_authorized_networks_config": {
10621076
Type: schema.TypeList,
10631077
Optional: true,
1078+
Computed: true,
10641079
MaxItems: 1,
1065-
Elem: networkConfig,
1080+
Elem: masterAuthorizedNetworksConfig,
10661081
Description: `The desired configuration options for master authorized networks. Omit the nested cidr_blocks attribute to disallow external access (except the cluster node IPs, which GKE automatically whitelists).`,
10671082
},
10681083

@@ -1303,17 +1318,23 @@ func resourceContainerCluster() *schema.Resource {
13031318
Description: `Configuration for private clusters, clusters with private nodes.`,
13041319
Elem: &schema.Resource{
13051320
Schema: map[string]*schema.Schema{
1321+
// enable_private_endpoint is orthogonal to private_endpoint_subnetwork.
1322+
// User can create a private_cluster_config block without including
1323+
// either one of those two fields. Both fields are optional.
1324+
// At the same time, we use 'AtLeastOneOf' to prevent an empty block
1325+
// like 'private_cluster_config{}'
13061326
"enable_private_endpoint": {
13071327
Type: schema.TypeBool,
1308-
Required: true,
1309-
ForceNew: true,
1328+
Optional: true,
1329+
AtLeastOneOf: privateClusterConfigKeys,
13101330
DiffSuppressFunc: containerClusterPrivateClusterConfigSuppress,
13111331
Description: `When true, the cluster's private endpoint is used as the cluster endpoint and access through the public endpoint is disabled. When false, either endpoint can be used. This field only applies to private clusters, when enable_private_nodes is true.`,
13121332
},
13131333
"enable_private_nodes": {
13141334
Type: schema.TypeBool,
13151335
Optional: true,
13161336
ForceNew: true,
1337+
AtLeastOneOf: privateClusterConfigKeys,
13171338
DiffSuppressFunc: containerClusterPrivateClusterConfigSuppress,
13181339
Description: `Enables the private cluster feature, creating a private endpoint on the cluster. In a private cluster, nodes only have RFC 1918 private addresses and communicate with the master's private endpoint via private networking.`,
13191340
},
@@ -1322,6 +1343,7 @@ func resourceContainerCluster() *schema.Resource {
13221343
Computed: true,
13231344
Optional: true,
13241345
ForceNew: true,
1346+
AtLeastOneOf: privateClusterConfigKeys,
13251347
ValidateFunc: orEmpty(validation.IsCIDRNetwork(28, 28)),
13261348
Description: `The IP range in CIDR notation to use for the hosted master network. This range will be used for assigning private IP addresses to the cluster master(s) and the ILB VIP. This range must not overlap with any other ranges in use within the cluster's network, and it must be a /28 subnet. See Private Cluster Limitations for more details. This field only applies to private clusters, when enable_private_nodes is true.`,
13271349
},
@@ -1335,17 +1357,26 @@ func resourceContainerCluster() *schema.Resource {
13351357
Computed: true,
13361358
Description: `The internal IP address of this cluster's master endpoint.`,
13371359
},
1360+
"private_endpoint_subnetwork": {
1361+
Type: schema.TypeString,
1362+
Optional: true,
1363+
ForceNew: true,
1364+
AtLeastOneOf: privateClusterConfigKeys,
1365+
DiffSuppressFunc: compareSelfLinkOrResourceName,
1366+
Description: `Subnetwork in cluster's network where master's endpoint will be provisioned.`,
1367+
},
13381368
"public_endpoint": {
13391369
Type: schema.TypeString,
13401370
Computed: true,
13411371
Description: `The external IP address of this cluster's master endpoint.`,
13421372
},
13431373
"master_global_access_config": {
1344-
Type: schema.TypeList,
1345-
MaxItems: 1,
1346-
Optional: true,
1347-
Computed: true,
1348-
Description: "Controls cluster master global access settings.",
1374+
Type: schema.TypeList,
1375+
MaxItems: 1,
1376+
Optional: true,
1377+
Computed: true,
1378+
AtLeastOneOf: privateClusterConfigKeys,
1379+
Description: "Controls cluster master global access settings.",
13491380
Elem: &schema.Resource{
13501381
Schema: map[string]*schema.Schema{
13511382
"enabled": {
@@ -1759,7 +1790,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
17591790
Name: clusterName,
17601791
InitialNodeCount: int64(d.Get("initial_node_count").(int)),
17611792
MaintenancePolicy: expandMaintenancePolicy(d, meta),
1762-
MasterAuthorizedNetworksConfig: expandMasterAuthorizedNetworksConfig(d.Get("master_authorized_networks_config")),
1793+
MasterAuthorizedNetworksConfig: expandMasterAuthorizedNetworksConfig(d.Get("master_authorized_networks_config"), d),
17631794
InitialClusterVersion: d.Get("min_master_version").(string),
17641795
ClusterIpv4Cidr: d.Get("cluster_ipv4_cidr").(string),
17651796
Description: d.Get("description").(string),
@@ -2353,7 +2384,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
23532384
c := d.Get("master_authorized_networks_config")
23542385
req := &container.UpdateClusterRequest{
23552386
Update: &container.ClusterUpdate{
2356-
DesiredMasterAuthorizedNetworksConfig: expandMasterAuthorizedNetworksConfig(c),
2387+
DesiredMasterAuthorizedNetworksConfig: expandMasterAuthorizedNetworksConfig(c, d),
23572388
},
23582389
}
23592390

@@ -2417,6 +2448,24 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
24172448
log.Printf("[INFO] GKE cluster %s's binary authorization has been updated to %v", d.Id(), enabled)
24182449
}
24192450

2451+
if d.HasChange("private_cluster_config.0.enable_private_endpoint") {
2452+
enabled := d.Get("private_cluster_config.0.enable_private_endpoint").(bool)
2453+
req := &container.UpdateClusterRequest{
2454+
Update: &container.ClusterUpdate{
2455+
DesiredEnablePrivateEndpoint: enabled,
2456+
ForceSendFields: []string{"DesiredEnablePrivateEndpoint"},
2457+
},
2458+
}
2459+
2460+
updateF := updateFunc(req, "updating enable private endpoint")
2461+
// Call update serially.
2462+
if err := lockedCall(lockKey, updateF); err != nil {
2463+
return err
2464+
}
2465+
2466+
log.Printf("[INFO] GKE cluster %s's enable private endpoint has been updated to %v", d.Id(), enabled)
2467+
}
2468+
24202469
if d.HasChange("binary_authorization") {
24212470
req := &container.UpdateClusterRequest{
24222471
Update: &container.ClusterUpdate{
@@ -3954,7 +4003,7 @@ func expandMasterAuth(configured interface{}) *container.MasterAuth {
39544003
return result
39554004
}
39564005

3957-
func expandMasterAuthorizedNetworksConfig(configured interface{}) *container.MasterAuthorizedNetworksConfig {
4006+
func expandMasterAuthorizedNetworksConfig(configured interface{}, d *schema.ResourceData) *container.MasterAuthorizedNetworksConfig {
39584007
l := configured.([]interface{})
39594008
if len(l) == 0 {
39604009
return &container.MasterAuthorizedNetworksConfig{
@@ -3976,6 +4025,10 @@ func expandMasterAuthorizedNetworksConfig(configured interface{}) *container.Mas
39764025
})
39774026
}
39784027
}
4028+
if v, ok := d.GetOkExists("master_authorized_networks_config.0.gcp_public_cidrs_access_enabled"); ok {
4029+
result.GcpPublicCidrsAccessEnabled = v.(bool)
4030+
result.ForceSendFields = []string{"GcpPublicCidrsAccessEnabled"}
4031+
}
39794032
}
39804033
return result
39814034
}
@@ -4003,11 +4056,12 @@ func expandPrivateClusterConfig(configured interface{}) *container.PrivateCluste
40034056
}
40044057
config := l[0].(map[string]interface{})
40054058
return &container.PrivateClusterConfig{
4006-
EnablePrivateEndpoint: config["enable_private_endpoint"].(bool),
4007-
EnablePrivateNodes: config["enable_private_nodes"].(bool),
4008-
MasterIpv4CidrBlock: config["master_ipv4_cidr_block"].(string),
4009-
MasterGlobalAccessConfig: expandPrivateClusterConfigMasterGlobalAccessConfig(config["master_global_access_config"]),
4010-
ForceSendFields: []string{"EnablePrivateEndpoint", "EnablePrivateNodes", "MasterIpv4CidrBlock", "MasterGlobalAccessConfig"},
4059+
EnablePrivateEndpoint: config["enable_private_endpoint"].(bool),
4060+
EnablePrivateNodes: config["enable_private_nodes"].(bool),
4061+
MasterIpv4CidrBlock: config["master_ipv4_cidr_block"].(string),
4062+
MasterGlobalAccessConfig: expandPrivateClusterConfigMasterGlobalAccessConfig(config["master_global_access_config"]),
4063+
PrivateEndpointSubnetwork: config["private_endpoint_subnetwork"].(string),
4064+
ForceSendFields: []string{"EnablePrivateEndpoint", "EnablePrivateNodes", "MasterIpv4CidrBlock", "MasterGlobalAccessConfig"},
40114065
}
40124066
}
40134067

@@ -4548,6 +4602,7 @@ func flattenPrivateClusterConfig(c *container.PrivateClusterConfig) []map[string
45484602
"master_global_access_config": flattenPrivateClusterConfigMasterGlobalAccessConfig(c.MasterGlobalAccessConfig),
45494603
"peering_name": c.PeeringName,
45504604
"private_endpoint": c.PrivateEndpoint,
4605+
"private_endpoint_subnetwork": c.PrivateEndpointSubnetwork,
45514606
"public_endpoint": c.PublicEndpoint,
45524607
},
45534608
}
@@ -4815,16 +4870,15 @@ func flattenMasterAuthorizedNetworksConfig(c *container.MasterAuthorizedNetworks
48154870
return nil
48164871
}
48174872
result := make(map[string]interface{})
4818-
if c.Enabled {
4819-
cidrBlocks := make([]interface{}, 0, len(c.CidrBlocks))
4820-
for _, v := range c.CidrBlocks {
4821-
cidrBlocks = append(cidrBlocks, map[string]interface{}{
4822-
"cidr_block": v.CidrBlock,
4823-
"display_name": v.DisplayName,
4824-
})
4825-
}
4826-
result["cidr_blocks"] = schema.NewSet(schema.HashResource(cidrBlockConfig), cidrBlocks)
4873+
cidrBlocks := make([]interface{}, 0, len(c.CidrBlocks))
4874+
for _, v := range c.CidrBlocks {
4875+
cidrBlocks = append(cidrBlocks, map[string]interface{}{
4876+
"cidr_block": v.CidrBlock,
4877+
"display_name": v.DisplayName,
4878+
})
48274879
}
4880+
result["cidr_blocks"] = schema.NewSet(schema.HashResource(cidrBlockConfig), cidrBlocks)
4881+
result["gcp_public_cidrs_access_enabled"] = c.GcpPublicCidrsAccessEnabled
48284882
return []map[string]interface{}{result}
48294883
}
48304884

@@ -5094,12 +5148,15 @@ func containerClusterPrivateClusterConfigSuppress(k, old, new string, d *schema.
50945148
o, n = d.GetChange("private_cluster_config.0.enable_private_nodes")
50955149
suppressNodes := !o.(bool) && !n.(bool)
50965150

5151+
// Do not suppress diffs when private_endpoint_subnetwork is configured
5152+
_, hasSubnet := d.GetOk("private_cluster_config.0.private_endpoint_subnetwork")
5153+
50975154
if k == "private_cluster_config.0.enable_private_endpoint" {
5098-
return suppressEndpoint
5155+
return suppressEndpoint && !hasSubnet
50995156
} else if k == "private_cluster_config.0.enable_private_nodes" {
5100-
return suppressNodes
5157+
return suppressNodes && !hasSubnet
51015158
} else if k == "private_cluster_config.#" {
5102-
return suppressEndpoint && suppressNodes
5159+
return suppressEndpoint && suppressNodes && !hasSubnet
51035160
}
51045161
return false
51055162
}

0 commit comments

Comments
 (0)