diff --git a/data_source_google_container_versions.go b/data_source_google_container_versions.go new file mode 100644 index 00000000..9ae0f2a7 --- /dev/null +++ b/data_source_google_container_versions.go @@ -0,0 +1,67 @@ +package google + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceGoogleContainerVersions() *schema.Resource { + return &schema.Resource{ + Read: dataSourceGoogleContainerVersionsRead, + Schema: map[string]*schema.Schema{ + "project": { + Type: schema.TypeString, + Optional: true, + }, + "zone": { + Type: schema.TypeString, + Required: true, + }, + "latest_master_version": { + Type: schema.TypeString, + Computed: true, + }, + "latest_node_version": { + Type: schema.TypeString, + Computed: true, + }, + "valid_master_versions": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "valid_node_versions": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func dataSourceGoogleContainerVersionsRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + zone := d.Get("zone").(string) + + resp, err := config.clientContainer.Projects.Zones.GetServerconfig(project, zone).Do() + if err != nil { + return fmt.Errorf("Error retrieving available container cluster versions: %s", err.Error()) + } + + d.Set("valid_master_versions", resp.ValidMasterVersions) + d.Set("valid_node_versions", resp.ValidNodeVersions) + d.Set("latest_master_version", resp.ValidMasterVersions[0]) + d.Set("latest_node_version", resp.ValidNodeVersions[0]) + + d.SetId(time.Now().UTC().String()) + + return nil +} diff --git a/data_source_google_container_versions_test.go b/data_source_google_container_versions_test.go new file mode 100644 index 00000000..d4399a6b --- /dev/null +++ b/data_source_google_container_versions_test.go @@ -0,0 +1,97 @@ +package google + +import ( + "errors" + "fmt" + "strconv" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccGoogleContainerVersions_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckGoogleContainerVersionsConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckGoogleContainerVersionsMeta("data.google_container_versions.versions"), + ), + }, + }, + }) +} + +func testAccCheckGoogleContainerVersionsMeta(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Can't find versions data source: %s", n) + } + + if rs.Primary.ID == "" { + return errors.New("versions data source ID not set.") + } + + nodeCount, ok := rs.Primary.Attributes["valid_node_versions.#"] + if !ok { + return errors.New("can't find 'valid_node_versions' attribute") + } + + noOfNodes, err := strconv.Atoi(nodeCount) + if err != nil { + return errors.New("failed to read number of valid node versions") + } + if noOfNodes < 2 { + return fmt.Errorf("expected at least 2 valid node versions, received %d, this is most likely a bug", + noOfNodes) + } + + for i := 0; i < noOfNodes; i++ { + idx := "valid_node_versions." + strconv.Itoa(i) + v, ok := rs.Primary.Attributes[idx] + if !ok { + return fmt.Errorf("valid node versions list is corrupt (%q not found), this is definitely a bug", idx) + } + if len(v) < 1 { + return fmt.Errorf("Empty node version (%q), this is definitely a bug", idx) + } + } + + masterCount, ok := rs.Primary.Attributes["valid_master_versions.#"] + if !ok { + return errors.New("can't find 'valid_master_versions' attribute") + } + + noOfMasters, err := strconv.Atoi(masterCount) + if err != nil { + return errors.New("failed to read number of valid master versions") + } + if noOfMasters < 2 { + return fmt.Errorf("expected at least 2 valid master versions, received %d, this is most likely a bug", + noOfMasters) + } + + for i := 0; i < noOfMasters; i++ { + idx := "valid_master_versions." + strconv.Itoa(i) + v, ok := rs.Primary.Attributes[idx] + if !ok { + return fmt.Errorf("valid master versions list is corrupt (%q not found), this is definitely a bug", idx) + } + if len(v) < 1 { + return fmt.Errorf("Empty master version (%q), this is definitely a bug", idx) + } + } + + return nil + } +} + +var testAccCheckGoogleContainerVersionsConfig = ` +data "google_container_versions" "versions" { + zone = "us-central1-b" +} +` diff --git a/provider.go b/provider.go index 431a29f1..bb1bbedc 100644 --- a/provider.go +++ b/provider.go @@ -52,6 +52,7 @@ func Provider() terraform.ResourceProvider { "google_compute_network": dataSourceGoogleComputeNetwork(), "google_compute_subnetwork": dataSourceGoogleComputeSubnetwork(), "google_compute_zones": dataSourceGoogleComputeZones(), + "google_container_versions": dataSourceGoogleContainerVersions(), "google_iam_policy": dataSourceGoogleIamPolicy(), }, diff --git a/resource_container_cluster_test.go b/resource_container_cluster_test.go index 236785e4..e7f2a396 100644 --- a/resource_container_cluster_test.go +++ b/resource_container_cluster_test.go @@ -400,10 +400,14 @@ resource "google_container_cluster" "with_additional_zones" { }`, acctest.RandString(10)) var testAccContainerCluster_withVersion = fmt.Sprintf(` +data "google_container_versions" "central1a" { + zone = "us-central1-a" +} + resource "google_container_cluster" "with_version" { name = "cluster-test-%s" zone = "us-central1-a" - node_version = "1.6.1" + node_version = "${data.google_container_versions.central1a.latest_node_version}" initial_node_count = 1 master_auth {