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

New datasource: google_container_cluster #740

Merged
merged 4 commits into from
Dec 20, 2017
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
29 changes: 29 additions & 0 deletions google/data_source_google_container_cluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package google

import (
"github.com/hashicorp/terraform/helper/schema"
)

func dataSourceGoogleContainerCluster() *schema.Resource {
// Generate datasource schema from resource
dsSchema := datasourceSchemaFromResourceSchema(resourceContainerCluster().Schema)

// Set 'Required' schema elements
addRequiredFieldsToSchema(dsSchema, "name", "zone")

// Set 'Optional' schema elements
addOptionalFieldsToSchema(dsSchema, "project")

return &schema.Resource{
Read: datasourceContainerClusterRead,
Schema: dsSchema,
}
}

func datasourceContainerClusterRead(d *schema.ResourceData, meta interface{}) error {
clusterName := d.Get("name").(string)

d.SetId(clusterName)

return resourceContainerClusterRead(d, meta)
}
106 changes: 106 additions & 0 deletions google/data_source_google_container_cluster_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package google

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

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

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccContainerClusterDatasourceConfig,
Check: resource.ComposeTestCheckFunc(
testAccDataSourceGoogleContainerClusterCheck("data.google_container_cluster.kubes", "google_container_cluster.kubes"),
),
},
},
})
}

func testAccDataSourceGoogleContainerClusterCheck(dataSourceName string, resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
ds, ok := s.RootModule().Resources[dataSourceName]
if !ok {
return fmt.Errorf("root module has no resource called %s", dataSourceName)
}

rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("can't find %s in state", resourceName)
}

dsAttr := ds.Primary.Attributes
rsAttr := rs.Primary.Attributes

clusterAttrToCheck := []string{
"name",
"zone",
"additional_zones",
"addons_config",
"cluster_ipv4_cidr",
"description",
"enable_kubernetes_alpha",
"enable_legacy_abac",
"endpoint",
"enable_legacy_abac",
"instance_group_urls",
"ip_allocation_policy",
"logging_service",
"maintenance_policy",
"master_auth",
"master_auth.0.password",
"master_auth.0.username",
"master_auth.0.client_certificate",
"master_auth.0.client_key",
"master_auth.0.cluster_ca_certificate",
"master_authorized_networks_config",
"master_version",
"min_master_version",
"monitoring_service",
"network",
"network_policy",
"node_version",
"subnetwork",
}

for _, attr := range clusterAttrToCheck {
if dsAttr[attr] != rsAttr[attr] {
return fmt.Errorf(
"%s is %s; want %s",
attr,
dsAttr[attr],
rsAttr[attr],
)
}
}

return nil
}
}

var testAccContainerClusterDatasourceConfig = fmt.Sprintf(`
resource "google_container_cluster" "kubes" {
name = "cluster-test-%s"
zone = "us-central1-a"
initial_node_count = 1

master_auth {
username = "mr.yoda"
password = "adoy.rm"
}
}

data "google_container_cluster" "kubes" {
name = "${google_container_cluster.kubes.name}"
zone = "${google_container_cluster.kubes.zone}"
}
`, acctest.RandString(10))
77 changes: 77 additions & 0 deletions google/datasource_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package google

import (
"log"

"github.com/hashicorp/terraform/helper/schema"
)

// datasourceSchemaFromResourceSchema is a recursive func that
// converts an existing Resource schema to a Datasource schema.
// All schema elements are copied, but certain attributes are ignored or changed:
// - all attributes have Computed = true
// - all attributes have ForceNew, Required = false
// - Validation funcs and attributes (e.g. MaxItems) are not copied
func datasourceSchemaFromResourceSchema(rs map[string]*schema.Schema) map[string]*schema.Schema {
ds := make(map[string]*schema.Schema, len(rs))
for k, v := range rs {
log.Printf("[DEBUG] datasourceSchemaFromResourceSchema: %s", k)

dv := &schema.Schema{
Computed: true,
ForceNew: false,
Required: false,
Description: v.Description,
Type: v.Type,
}

switch v.Type {
case schema.TypeSet:
dv.Set = v.Set
fallthrough
case schema.TypeList:
// List & Set types are generally used for 2 cases:
// - a list/set of simple primitive values (e.g. list of strings)
// - a sub resource
if elem, ok := v.Elem.(*schema.Resource); ok {
// handle the case where the Element is a sub-resource
dv.Elem = &schema.Resource{
Schema: datasourceSchemaFromResourceSchema(elem.Schema),
}
} else {
// handle simple primitive case
dv.Elem = v.Elem
}

default:
// Elem of all other types are copied as-is
dv.Elem = v.Elem

}
ds[k] = dv

}
return ds
}

// fixDatasourceSchemaFlags is a convenience func that toggles the Computed,
// Optional + Required flags on a schema element. This is useful when the schema
// has been generated (using `datasourceSchemaFromResourceSchema` above for
// example) and therefore the attribute flags were not set appropriately when
// first added to the schema definition. Currently only supports top-level
// schema elements.
func fixDatasourceSchemaFlags(schema map[string]*schema.Schema, required bool, keys ...string) {
for _, v := range keys {
schema[v].Computed = false
schema[v].Optional = !required
schema[v].Required = required
}
}

func addRequiredFieldsToSchema(schema map[string]*schema.Schema, keys ...string) {
fixDatasourceSchemaFlags(schema, true, keys...)
}

func addOptionalFieldsToSchema(schema map[string]*schema.Schema, keys ...string) {
fixDatasourceSchemaFlags(schema, false, keys...)
}
1 change: 1 addition & 0 deletions google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ func Provider() terraform.ResourceProvider {
"google_compute_zones": dataSourceGoogleComputeZones(),
"google_compute_instance_group": dataSourceGoogleComputeInstanceGroup(),
"google_compute_region_instance_group": dataSourceGoogleComputeRegionInstanceGroup(),
"google_container_cluster": dataSourceGoogleContainerCluster(),
"google_container_engine_versions": dataSourceGoogleContainerEngineVersions(),
"google_active_folder": dataSourceGoogleActiveFolder(),
"google_iam_policy": dataSourceGoogleIamPolicy(),
Expand Down
Loading