Skip to content

Commit

Permalink
Add support for GKE release channel updates (#3509)
Browse files Browse the repository at this point in the history
  • Loading branch information
rileykarson authored May 13, 2020
1 parent 4807251 commit 2a7d76a
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ func dataSourceGoogleContainerEngineVersions() *schema.Resource {
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},

<% unless version == 'ga' -%>
"release_channel_default_version": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
<% end %>
},
}
}
Expand Down Expand Up @@ -110,6 +118,14 @@ func dataSourceGoogleContainerEngineVersionsRead(d *schema.ResourceData, meta in

d.Set("default_cluster_version", resp.DefaultClusterVersion)

<% unless version == 'ga' -%>
m := map[string]string{}
for _, v := range resp.Channels {
m[v.Channel] = v.DefaultVersion
}
d.Set("release_channel_default_version", m)
<% end %>

d.SetId(time.Now().UTC().String())
return nil
}
46 changes: 37 additions & 9 deletions third_party/terraform/resources/resource_container_cluster.go.erb
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,6 @@ func resourceContainerCluster() *schema.Resource {
<% unless version == 'ga' -%>
"release_channel": {
Type: schema.TypeList,
ForceNew: true,
Optional: true,
Computed: true,
MaxItems: 1,
Expand All @@ -890,7 +889,6 @@ func resourceContainerCluster() *schema.Resource {
"channel": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{"UNSPECIFIED", "RAPID", "REGULAR", "STABLE"}, false),
DiffSuppressFunc: emptyOrDefaultStringSuppress("UNSPECIFIED"),
},
Expand Down Expand Up @@ -1561,7 +1559,6 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
d.SetPartial("enable_shielded_nodes")
}
<% unless version == 'ga' -%>

if d.HasChange("enable_intranode_visibility") {
enabled := d.Get("enable_intranode_visibility").(bool)
req := &containerBeta.UpdateClusterRequest{
Expand Down Expand Up @@ -1596,7 +1593,37 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
d.SetPartial("enable_intranode_visibility")
}
<% end -%>
<% unless version == 'ga' -%>
if d.HasChange("release_channel") {
req := &containerBeta.UpdateClusterRequest{
Update: &containerBeta.ClusterUpdate{
DesiredReleaseChannel: expandReleaseChannel(d.Get("release_channel")),
},
}
updateF := func() error {
log.Println("[DEBUG] updating release_channel")
name := containerClusterFullName(project, location, clusterName)
op, err := config.clientContainerBeta.Projects.Locations.Clusters.Update(name, req).Do()
if err != nil {
return err
}

// Wait until it's updated
err = containerOperationWait(config, op, project, location, "updating Release Channel", d.Timeout(schema.TimeoutUpdate))
log.Println("[DEBUG] done updating release_channel")
return err
}

// Call update serially.
if err := lockedCall(lockKey, updateF); err != nil {
return err
}

log.Printf("[INFO] GKE cluster %s Release Channel has been updated to %#v", d.Id(), req.Update.DesiredReleaseChannel)

d.SetPartial("release_channel")
}
<% end -%>
if d.HasChange("maintenance_policy") {
req := &containerBeta.SetMaintenancePolicyRequest{
MaintenancePolicy: expandMaintenancePolicy(d, meta),
Expand Down Expand Up @@ -1781,13 +1808,14 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
}

// The master must be updated before the nodes
if d.HasChange("min_master_version") {
desiredMasterVersion := d.Get("min_master_version").(string)
currentMasterVersion := d.Get("master_version").(string)
des, err := version.NewVersion(desiredMasterVersion)
// If set to "", skip this step- any master version satisfies that minimum.
if ver := d.Get("min_master_version").(string); d.HasChange("min_master_version") && ver != "" {
des, err := version.NewVersion(ver)
if err != nil {
return err
}

currentMasterVersion := d.Get("master_version").(string)
cur, err := version.NewVersion(currentMasterVersion)
if err != nil {
return err
Expand All @@ -1797,7 +1825,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
if cur.LessThan(des) {
req := &containerBeta.UpdateClusterRequest{
Update: &containerBeta.ClusterUpdate{
DesiredMasterVersion: desiredMasterVersion,
DesiredMasterVersion: ver,
},
}

Expand All @@ -1806,7 +1834,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
if err := lockedCall(lockKey, updateF); err != nil {
return err
}
log.Printf("[INFO] GKE cluster %s: master has been updated to %s", d.Id(), desiredMasterVersion)
log.Printf("[INFO] GKE cluster %s: master has been updated to %s", d.Id(), ver)
}
d.SetPartial("min_master_version")
}
Expand Down
66 changes: 48 additions & 18 deletions third_party/terraform/tests/resource_container_cluster_test.go.erb
Original file line number Diff line number Diff line change
Expand Up @@ -351,37 +351,51 @@ func TestAccContainerCluster_withReleaseChannelEnabled(t *testing.T) {
Config: testAccContainerCluster_withReleaseChannelEnabled(clusterName, "STABLE"),
},
{
ResourceName: "google_container_cluster.with_release_channel",
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
ResourceName: "google_container_cluster.with_release_channel",
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"min_master_version"},
},
{
Config: testAccContainerCluster_withReleaseChannelEnabled(clusterName, "REGULAR"),
Config: testAccContainerCluster_withReleaseChannelEnabled(clusterName, "UNSPECIFIED"),
},
{
ResourceName: "google_container_cluster.with_release_channel",
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
ResourceName: "google_container_cluster.with_release_channel",
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"min_master_version"},
},
{
Config: testAccContainerCluster_withReleaseChannelEnabled(clusterName, "RAPID"),
Config: testAccContainerCluster_withReleaseChannelEnabledUpdateToChannelDefaultVersion(clusterName, "REGULAR"),
},
{
ResourceName: "google_container_cluster.with_release_channel",
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
ResourceName: "google_container_cluster.with_release_channel",
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"min_master_version"},
},
{
Config: testAccContainerCluster_withReleaseChannelEnabled(clusterName, "REGULAR"),
},
{
ResourceName: "google_container_cluster.with_release_channel",
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"min_master_version"},
},
{
Config: testAccContainerCluster_withReleaseChannelEnabled(clusterName, "UNSPECIFIED"),
},
{
ResourceName: "google_container_cluster.with_release_channel",
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
ResourceName: "google_container_cluster.with_release_channel",
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"min_master_version"},
},
},
})
Expand Down Expand Up @@ -2169,6 +2183,22 @@ resource "google_container_cluster" "with_release_channel" {
}
`, clusterName, channel)
}

func testAccContainerCluster_withReleaseChannelEnabledUpdateToChannelDefaultVersion(clusterName string, channel string) string {
return fmt.Sprintf(`

data "google_container_engine_versions" "central1a" {
location = "us-central1-a"
}

resource "google_container_cluster" "with_release_channel" {
name = "%s"
location = "us-central1-a"
initial_node_count = 1
min_master_version = data.google_container_engine_versions.central1a.release_channel_default_version["%s"]
}
`, clusterName, channel)
}
<% end -%>

func testAccContainerCluster_removeNetworkPolicy(clusterName string) string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ support the same version.

```hcl
data "google_container_engine_versions" "central1b" {
provider = "google-beta"
location = "us-central1-b"
version_prefix = "1.12."
}
Expand All @@ -36,6 +37,10 @@ resource "google_container_cluster" "foo" {
password = "adoy.rm"
}
}
output "stable_channel_version" {
value = data.google_container_engine_versions.central1b.release_channel_default_version["STABLE"]
}
```

## Argument Reference
Expand Down Expand Up @@ -66,3 +71,4 @@ The following attributes are exported:
* `latest_master_version` - The latest version available in the given zone for use with master instances.
* `latest_node_version` - The latest version available in the given zone for use with node instances.
* `default_cluster_version` - Version of Kubernetes the service deploys by default.
* `release_channel_default_version` ([Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) - A map from a release channel name to the channel's default version.
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,16 @@ clusters with private nodes. Structure is documented below.
* `project` - (Optional) The ID of the project in which the resource belongs. If it
is not provided, the provider project is used.

* `release_channel` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Configuration options for the
[Release channel](https://cloud.google.com/kubernetes-engine/docs/concepts/release-channels)
feature, which provide more control over automatic upgrades of your GKE clusters. Structure is documented below.
* `release_channel` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html))
Configuration options for the [Release channel](https://cloud.google.com/kubernetes-engine/docs/concepts/release-channels)
feature, which provide more control over automatic upgrades of your GKE clusters.
When updating this field, GKE imposes specific version requirements. See
[Migrating between release channels](https://cloud.google.com/kubernetes-engine/docs/concepts/release-channels#migrating_between_release_channels)
for more details; the `google_container_engine_versions` datasource can provide
the default version for a channel. Note that removing the `release_channel`
field from your config will cause Terraform to stop managing your cluster's
release channel, but will not unenroll it. Instead, use the `"UNSPECIFIED"`
channel. Structure is documented below.

* `remove_default_node_pool` - (Optional) If `true`, deletes the default node
pool upon cluster creation. If you're using `google_container_node_pool`
Expand Down

0 comments on commit 2a7d76a

Please sign in to comment.