Skip to content

Commit

Permalink
Add new TPUv2 product and VM resource in beta (#8899) (#15836)
Browse files Browse the repository at this point in the history
* Add new TPUv2 product and VM resource in beta

* Add TPUv2 vm full example

* Add async operation polling and update API version

* Update examples to pass tests

* Change example zone to avoid capacity issues during tests on those examples

* Hardcode version and accelerator type in to examples since github check values vary from local

* Change API version from v2alpha1 to v2, will override to v2alpha1 in the terraform-eap process

* Add update test for description

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician authored Sep 13, 2023
1 parent bc0615d commit 7025f11
Show file tree
Hide file tree
Showing 10 changed files with 582 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/8899.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
`google_tpu_v2_vm` (beta)
```
5 changes: 5 additions & 0 deletions .teamcity/components/generated/services.kt
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,11 @@ var services = mapOf(
"displayName" to "Tpu",
"path" to "./google/services/tpu"
),
"tpuv2" to mapOf(
"name" to "tpuv2",
"displayName" to "Tpuv2",
"path" to "./google/services/tpuv2"
),
"vertexai" to mapOf(
"name" to "vertexai",
"displayName" to "Vertexai",
Expand Down
95 changes: 95 additions & 0 deletions google/services/tpuv2/data_source_tpu_v2_accelerator_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package tpuv2

import (
"fmt"
"log"
"sort"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
)

func DataSourceTpuV2AcceleratorTypes() *schema.Resource {
return &schema.Resource{
Read: dataSourceTpuV2AcceleratorTypesRead,
Schema: map[string]*schema.Schema{
"project": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"zone": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"types": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}

func dataSourceTpuV2AcceleratorTypesRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}

project, err := tpgresource.GetProject(d, config)
if err != nil {
return err
}

zone, err := tpgresource.GetZone(d, config)
if err != nil {
return err
}

url, err := tpgresource.ReplaceVars(d, config, "{{TpuV2BasePath}}projects/{{project}}/locations/{{zone}}/acceleratorTypes")
if err != nil {
return err
}

typesRaw, err := tpgresource.PaginatedListRequest(project, url, userAgent, config, flattenTpuV2AcceleratorTypes)
if err != nil {
return fmt.Errorf("error listing TPU v2 accelerator types: %s", err)
}

types := make([]string, len(typesRaw))
for i, typeRaw := range typesRaw {
types[i] = typeRaw.(string)
}
sort.Strings(types)

log.Printf("[DEBUG] Received Google TPU v2 accelerator types: %q", types)

if err := d.Set("types", types); err != nil {
return fmt.Errorf("error setting types: %s", err)
}
if err := d.Set("zone", zone); err != nil {
return fmt.Errorf("error setting zone: %s", err)
}
if err := d.Set("project", project); err != nil {
return fmt.Errorf("error setting project: %s", err)
}
d.SetId(fmt.Sprintf("projects/%s/zones/%s", project, zone))

return nil
}

func flattenTpuV2AcceleratorTypes(resp map[string]interface{}) []interface{} {
typeObjList := resp["acceleratorTypes"].([]interface{})
types := make([]interface{}, len(typeObjList))
for i, typ := range typeObjList {
typeObj := typ.(map[string]interface{})
types[i] = typeObj["type"]
}
return types
}
70 changes: 70 additions & 0 deletions google/services/tpuv2/data_source_tpu_v2_accelerator_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package tpuv2_test

import (
"errors"
"fmt"
"strconv"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-google/google/acctest"
)

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

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccTpuV2AcceleratorTypesConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckTpuV2AcceleratorTypes("data.google_tpu_v2_accelerator_types.available"),
),
},
},
})
}

func testAccCheckTpuV2AcceleratorTypes(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("can't find TPU v2 accelerator types data source: %s", n)
}

if rs.Primary.ID == "" {
return errors.New("data source id not set")
}

count, ok := rs.Primary.Attributes["types.#"]
if !ok {
return errors.New("can't find 'types' attribute")
}

cnt, err := strconv.Atoi(count)
if err != nil {
return errors.New("failed to read number of types")
}
if cnt < 2 {
return fmt.Errorf("expected at least 2 types, received %d, this is most likely a bug", cnt)
}

for i := 0; i < cnt; i++ {
idx := fmt.Sprintf("types.%d", i)
_, ok := rs.Primary.Attributes[idx]
if !ok {
return fmt.Errorf("expected %q, type not found", idx)
}
}
return nil
}
}

const testAccTpuV2AcceleratorTypesConfig = `
data "google_tpu_v2_accelerator_types" "available" {}
`
95 changes: 95 additions & 0 deletions google/services/tpuv2/data_source_tpu_v2_runtime_versions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package tpuv2

import (
"fmt"
"log"
"sort"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
)

func DataSourceTpuV2RuntimeVersions() *schema.Resource {
return &schema.Resource{
Read: dataSourceTpuV2RuntimeVersionsRead,
Schema: map[string]*schema.Schema{
"project": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"zone": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"versions": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}

func dataSourceTpuV2RuntimeVersionsRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}

project, err := tpgresource.GetProject(d, config)
if err != nil {
return err
}

zone, err := tpgresource.GetZone(d, config)
if err != nil {
return err
}

url, err := tpgresource.ReplaceVars(d, config, "{{TpuV2BasePath}}projects/{{project}}/locations/{{zone}}/runtimeVersions")
if err != nil {
return err
}

versionsRaw, err := tpgresource.PaginatedListRequest(project, url, userAgent, config, flattenTpuV2RuntimeVersions)
if err != nil {
return fmt.Errorf("error listing TPU v2 runtime versions: %s", err)
}

versions := make([]string, len(versionsRaw))
for i, ver := range versionsRaw {
versions[i] = ver.(string)
}
sort.Strings(versions)

log.Printf("[DEBUG] Received Google TPU v2 runtime versions: %q", versions)

if err := d.Set("versions", versions); err != nil {
return fmt.Errorf("error setting versions: %s", err)
}
if err := d.Set("zone", zone); err != nil {
return fmt.Errorf("error setting zone: %s", err)
}
if err := d.Set("project", project); err != nil {
return fmt.Errorf("error setting project: %s", err)
}
d.SetId(fmt.Sprintf("projects/%s/zones/%s", project, zone))

return nil
}

func flattenTpuV2RuntimeVersions(resp map[string]interface{}) []interface{} {
verObjList := resp["runtimeVersions"].([]interface{})
versions := make([]interface{}, len(verObjList))
for i, v := range verObjList {
verObj := v.(map[string]interface{})
versions[i] = verObj["version"]
}
return versions
}
70 changes: 70 additions & 0 deletions google/services/tpuv2/data_source_tpu_v2_runtime_versions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package tpuv2_test

import (
"errors"
"fmt"
"strconv"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-google/google/acctest"
)

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

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccTpuV2RuntimeVersionsConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckTpuV2RuntimeVersions("data.google_tpu_v2_runtime_versions.available"),
),
},
},
})
}

func testAccCheckTpuV2RuntimeVersions(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("can't find TPU v2 runtime versions data source: %s", n)
}

if rs.Primary.ID == "" {
return errors.New("data source id not set")
}

count, ok := rs.Primary.Attributes["versions.#"]
if !ok {
return errors.New("can't find 'versions' attribute")
}

cnt, err := strconv.Atoi(count)
if err != nil {
return errors.New("failed to read number of versions")
}
if cnt < 2 {
return fmt.Errorf("expected at least 2 versions, received %d, this is most likely a bug", cnt)
}

for i := 0; i < cnt; i++ {
idx := fmt.Sprintf("versions.%d", i)
_, ok := rs.Primary.Attributes[idx]
if !ok {
return fmt.Errorf("expected %q, version not found", idx)
}
}
return nil
}
}

const testAccTpuV2RuntimeVersionsConfig = `
data "google_tpu_v2_runtime_versions" "available" {}
`
3 changes: 3 additions & 0 deletions google/services/tpuv2/resource_tpu_v2_vm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package tpuv2_test
Loading

0 comments on commit 7025f11

Please sign in to comment.