diff --git a/resource_container_cluster.go b/resource_container_cluster.go index d9307511..8e22d4d4 100644 --- a/resource_container_cluster.go +++ b/resource_container_cluster.go @@ -243,6 +243,27 @@ func resourceContainerCluster() *schema.Resource { }, }, }, + + "service_account": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + + "metadata": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + ForceNew: true, + Elem: schema.TypeString, + }, + + "image_type": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, }, }, }, @@ -378,6 +399,22 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er cluster.NodeConfig.OauthScopes = scopes } + + if v, ok = nodeConfig["service_account"]; ok { + cluster.NodeConfig.ServiceAccount = v.(string) + } + + if v, ok = nodeConfig["metadata"]; ok { + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + cluster.NodeConfig.Metadata = m + } + + if v, ok = nodeConfig["image_type"]; ok { + cluster.NodeConfig.ImageType = v.(string) + } } req := &container.CreateClusterRequest{ @@ -559,8 +596,11 @@ func resourceContainerClusterDelete(d *schema.ResourceData, meta interface{}) er func flattenClusterNodeConfig(c *container.NodeConfig) []map[string]interface{} { config := []map[string]interface{}{ map[string]interface{}{ - "machine_type": c.MachineType, - "disk_size_gb": c.DiskSizeGb, + "machine_type": c.MachineType, + "disk_size_gb": c.DiskSizeGb, + "service_account": c.ServiceAccount, + "metadata": c.Metadata, + "image_type": c.ImageType, }, } diff --git a/resource_container_cluster_test.go b/resource_container_cluster_test.go index e772302f..f04756b6 100644 --- a/resource_container_cluster_test.go +++ b/resource_container_cluster_test.go @@ -192,6 +192,9 @@ func testAccCheckContainerCluster(n string) resource.TestCheckFunc { {"node_config.0.machine_type", cluster.NodeConfig.MachineType}, {"node_config.0.disk_size_gb", strconv.FormatInt(cluster.NodeConfig.DiskSizeGb, 10)}, {"node_config.0.oauth_scopes", cluster.NodeConfig.OauthScopes}, + {"node_config.0.service_account", cluster.NodeConfig.ServiceAccount}, + {"node_config.0.metadata", cluster.NodeConfig.Metadata}, + {"node_config.0.image_type", cluster.NodeConfig.ImageType}, {"node_version", cluster.CurrentNodeVersion}, } @@ -254,6 +257,9 @@ func checkMatch(attributes map[string]string, attr string, gcp interface{}) stri if gcpList, ok := gcp.([]string); ok { return checkListMatch(attributes, attr, gcpList) } + if gcpMap, ok := gcp.(map[string]string); ok { + return checkMapMatch(attributes, attr, gcpMap) + } tf := attributes[attr] if tf != gcp { return matchError(attr, tf, gcp) @@ -279,6 +285,24 @@ func checkListMatch(attributes map[string]string, attr string, gcpList []string) return "" } +func checkMapMatch(attributes map[string]string, attr string, gcpMap map[string]string) string { + num, err := strconv.Atoi(attributes[attr+".%"]) + if err != nil { + return fmt.Sprintf("Error in number conversion for attribute %s: %s", attr, err) + } + if num != len(gcpMap) { + return fmt.Sprintf("Cluster has mismatched %s size.\nTF Size: %d\nGCP Size: %d", attr, num, len(gcpMap)) + } + + for k, gcp := range gcpMap { + if tf := attributes[fmt.Sprintf("%s.%s", attr, k)]; tf != gcp { + return matchError(fmt.Sprintf("%s[%s]", attr, k), tf, gcp) + } + } + + return "" +} + func matchError(attr, tf string, gcp interface{}) string { return fmt.Sprintf("Cluster has mismatched %s.\nTF State: %+v\nGCP State: %+v", attr, tf, gcp) } @@ -345,6 +369,11 @@ resource "google_container_cluster" "with_node_config" { "https://www.googleapis.com/auth/logging.write", "https://www.googleapis.com/auth/monitoring" ] + service_account = "default" + metadata { + foo = "bar" + } + image_type = "CONTAINER_VM" } }`, acctest.RandString(10))