mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-01 16:21:06 +00:00
changes to make it easier to autogen address (#1607)
This commit is contained in:
parent
877f8107f8
commit
c505255556
@ -2,11 +2,18 @@ package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
var (
|
||||
computeAddressIdTemplate = "projects/%s/regions/%s/addresses/%s"
|
||||
computeAddressLinkRegex = regexp.MustCompile("projects/(.+)/regions/(.+)/addresses/(.+)$")
|
||||
)
|
||||
|
||||
func dataSourceGoogleComputeAddress() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Read: dataSourceGoogleComputeAddressRead,
|
||||
@ -74,3 +81,63 @@ func dataSourceGoogleComputeAddressRead(d *schema.ResourceData, meta interface{}
|
||||
d.SetId(strconv.FormatUint(uint64(address.Id), 10))
|
||||
return nil
|
||||
}
|
||||
|
||||
type computeAddressId struct {
|
||||
Project string
|
||||
Region string
|
||||
Name string
|
||||
}
|
||||
|
||||
func (s computeAddressId) canonicalId() string {
|
||||
return fmt.Sprintf(computeAddressIdTemplate, s.Project, s.Region, s.Name)
|
||||
}
|
||||
|
||||
func parseComputeAddressId(id string, config *Config) (*computeAddressId, error) {
|
||||
var parts []string
|
||||
if computeAddressLinkRegex.MatchString(id) {
|
||||
parts = computeAddressLinkRegex.FindStringSubmatch(id)
|
||||
|
||||
return &computeAddressId{
|
||||
Project: parts[1],
|
||||
Region: parts[2],
|
||||
Name: parts[3],
|
||||
}, nil
|
||||
} else {
|
||||
parts = strings.Split(id, "/")
|
||||
}
|
||||
|
||||
if len(parts) == 3 {
|
||||
return &computeAddressId{
|
||||
Project: parts[0],
|
||||
Region: parts[1],
|
||||
Name: parts[2],
|
||||
}, nil
|
||||
} else if len(parts) == 2 {
|
||||
// Project is optional.
|
||||
if config.Project == "" {
|
||||
return nil, fmt.Errorf("The default project for the provider must be set when using the `{region}/{name}` id format.")
|
||||
}
|
||||
|
||||
return &computeAddressId{
|
||||
Project: config.Project,
|
||||
Region: parts[0],
|
||||
Name: parts[1],
|
||||
}, nil
|
||||
} else if len(parts) == 1 {
|
||||
// Project and region is optional
|
||||
if config.Project == "" {
|
||||
return nil, fmt.Errorf("The default project for the provider must be set when using the `{name}` id format.")
|
||||
}
|
||||
if config.Region == "" {
|
||||
return nil, fmt.Errorf("The default region for the provider must be set when using the `{name}` id format.")
|
||||
}
|
||||
|
||||
return &computeAddressId{
|
||||
Project: config.Project,
|
||||
Region: config.Region,
|
||||
Name: parts[0],
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Invalid compute address id. Expecting resource link, `{project}/{region}/{name}`, `{region}/{name}` or `{name}` format.")
|
||||
}
|
||||
|
@ -8,6 +8,66 @@ import (
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestComputeAddressIdParsing(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
ImportId string
|
||||
ExpectedError bool
|
||||
ExpectedCanonicalId string
|
||||
Config *Config
|
||||
}{
|
||||
"id is a full self link": {
|
||||
ImportId: "https://www.googleapis.com/compute/v1/projects/test-project/regions/us-central1/addresses/test-address",
|
||||
ExpectedError: false,
|
||||
ExpectedCanonicalId: "projects/test-project/regions/us-central1/addresses/test-address",
|
||||
},
|
||||
"id is a partial self link": {
|
||||
ImportId: "projects/test-project/regions/us-central1/addresses/test-address",
|
||||
ExpectedError: false,
|
||||
ExpectedCanonicalId: "projects/test-project/regions/us-central1/addresses/test-address",
|
||||
},
|
||||
"id is project/region/address": {
|
||||
ImportId: "test-project/us-central1/test-address",
|
||||
ExpectedError: false,
|
||||
ExpectedCanonicalId: "projects/test-project/regions/us-central1/addresses/test-address",
|
||||
},
|
||||
"id is region/address": {
|
||||
ImportId: "us-central1/test-address",
|
||||
ExpectedError: false,
|
||||
ExpectedCanonicalId: "projects/default-project/regions/us-central1/addresses/test-address",
|
||||
Config: &Config{Project: "default-project"},
|
||||
},
|
||||
"id is address": {
|
||||
ImportId: "test-address",
|
||||
ExpectedError: false,
|
||||
ExpectedCanonicalId: "projects/default-project/regions/us-east1/addresses/test-address",
|
||||
Config: &Config{Project: "default-project", Region: "us-east1"},
|
||||
},
|
||||
"id has invalid format": {
|
||||
ImportId: "i/n/v/a/l/i/d",
|
||||
ExpectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for tn, tc := range cases {
|
||||
addressId, err := parseComputeAddressId(tc.ImportId, tc.Config)
|
||||
|
||||
if tc.ExpectedError && err == nil {
|
||||
t.Fatalf("bad: %s, expected an error", tn)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if tc.ExpectedError {
|
||||
continue
|
||||
}
|
||||
t.Fatalf("bad: %s, err: %#v", tn, err)
|
||||
}
|
||||
|
||||
if addressId.canonicalId() != tc.ExpectedCanonicalId {
|
||||
t.Fatalf("bad: %s, expected canonical id to be `%s` but is `%s`", tn, tc.ExpectedCanonicalId, addressId.canonicalId())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccDataSourceComputeAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -3,8 +3,6 @@ package google
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"regexp"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/hashicorp/terraform/helper/validation"
|
||||
computeBeta "google.golang.org/api/compute/v0.beta"
|
||||
@ -15,11 +13,6 @@ const (
|
||||
addressTypeInternal = "INTERNAL"
|
||||
)
|
||||
|
||||
var (
|
||||
computeAddressIdTemplate = "projects/%s/regions/%s/addresses/%s"
|
||||
computeAddressLinkRegex = regexp.MustCompile("projects/(.+)/regions/(.+)/addresses/(.+)$")
|
||||
)
|
||||
|
||||
func resourceComputeAddress() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceComputeAddressCreate,
|
||||
@ -29,9 +22,6 @@ func resourceComputeAddress() *schema.Resource {
|
||||
State: resourceComputeAddressImportState,
|
||||
},
|
||||
|
||||
SchemaVersion: 1,
|
||||
MigrateState: resourceComputeAddressMigrateState,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
|
@ -1,109 +0,0 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func resourceComputeAddressMigrateState(v int, is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) {
|
||||
if is.Empty() {
|
||||
log.Println("[DEBUG] Empty InstanceState; nothing to migrate.")
|
||||
return is, nil
|
||||
}
|
||||
|
||||
switch v {
|
||||
case 0:
|
||||
log.Println("[INFO] Found Container Node Pool State v0; migrating to v1")
|
||||
return migrateComputeAddressV0toV1(is, meta)
|
||||
default:
|
||||
return is, fmt.Errorf("Unexpected schema version: %d", v)
|
||||
}
|
||||
}
|
||||
|
||||
func migrateComputeAddressV0toV1(is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) {
|
||||
log.Printf("[DEBUG] Attributes before migration: %#v", is.Attributes)
|
||||
log.Printf("[DEBUG] ID before migration: %s", is.ID)
|
||||
|
||||
config := meta.(*Config)
|
||||
|
||||
project, err := getProjectFromInstanceState(is, config)
|
||||
if err != nil {
|
||||
return is, err
|
||||
}
|
||||
|
||||
region, err := getRegionFromInstanceState(is, config)
|
||||
if err != nil {
|
||||
return is, err
|
||||
}
|
||||
|
||||
is.ID = computeAddressId{
|
||||
Project: project,
|
||||
Region: region,
|
||||
Name: is.Attributes["name"],
|
||||
}.canonicalId()
|
||||
|
||||
log.Printf("[DEBUG] ID after migration: %s", is.ID)
|
||||
return is, nil
|
||||
}
|
||||
|
||||
type computeAddressId struct {
|
||||
Project string
|
||||
Region string
|
||||
Name string
|
||||
}
|
||||
|
||||
func (s computeAddressId) canonicalId() string {
|
||||
return fmt.Sprintf(computeAddressIdTemplate, s.Project, s.Region, s.Name)
|
||||
}
|
||||
|
||||
func parseComputeAddressId(id string, config *Config) (*computeAddressId, error) {
|
||||
var parts []string
|
||||
if computeAddressLinkRegex.MatchString(id) {
|
||||
parts = computeAddressLinkRegex.FindStringSubmatch(id)
|
||||
|
||||
return &computeAddressId{
|
||||
Project: parts[1],
|
||||
Region: parts[2],
|
||||
Name: parts[3],
|
||||
}, nil
|
||||
} else {
|
||||
parts = strings.Split(id, "/")
|
||||
}
|
||||
|
||||
if len(parts) == 3 {
|
||||
return &computeAddressId{
|
||||
Project: parts[0],
|
||||
Region: parts[1],
|
||||
Name: parts[2],
|
||||
}, nil
|
||||
} else if len(parts) == 2 {
|
||||
// Project is optional.
|
||||
if config.Project == "" {
|
||||
return nil, fmt.Errorf("The default project for the provider must be set when using the `{region}/{name}` id format.")
|
||||
}
|
||||
|
||||
return &computeAddressId{
|
||||
Project: config.Project,
|
||||
Region: parts[0],
|
||||
Name: parts[1],
|
||||
}, nil
|
||||
} else if len(parts) == 1 {
|
||||
// Project and region is optional
|
||||
if config.Project == "" {
|
||||
return nil, fmt.Errorf("The default project for the provider must be set when using the `{name}` id format.")
|
||||
}
|
||||
if config.Region == "" {
|
||||
return nil, fmt.Errorf("The default region for the provider must be set when using the `{name}` id format.")
|
||||
}
|
||||
|
||||
return &computeAddressId{
|
||||
Project: config.Project,
|
||||
Region: config.Region,
|
||||
Name: parts[0],
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Invalid compute address id. Expecting resource link, `{project}/{region}/{name}`, `{region}/{name}` or `{name}` format.")
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestComputeAddressMigrateState(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
StateVersion int
|
||||
Attributes map[string]string
|
||||
ExpectedId string
|
||||
Meta interface{}
|
||||
}{
|
||||
"update id from name to region/name": {
|
||||
StateVersion: 0,
|
||||
Attributes: map[string]string{
|
||||
"name": "address-1",
|
||||
},
|
||||
ExpectedId: "projects/gcp-project/regions/us-central1/addresses/address-1",
|
||||
Meta: &Config{Region: "us-central1", Project: "gcp-project"},
|
||||
},
|
||||
}
|
||||
|
||||
for tn, tc := range cases {
|
||||
is := &terraform.InstanceState{
|
||||
ID: tc.Attributes["name"],
|
||||
Attributes: tc.Attributes,
|
||||
}
|
||||
|
||||
is, err := resourceComputeAddressMigrateState(tc.StateVersion, is, tc.Meta)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("bad: %s, err: %#v", tn, err)
|
||||
}
|
||||
|
||||
if is.ID != tc.ExpectedId {
|
||||
t.Fatalf("Id should be set to `%s` but is `%s`", tc.ExpectedId, is.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestComputeAddressMigrateState_empty(t *testing.T) {
|
||||
var is *terraform.InstanceState
|
||||
var meta *Config
|
||||
|
||||
// should handle nil
|
||||
is, err := resourceComputeAddressMigrateState(0, is, meta)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("err: %#v", err)
|
||||
}
|
||||
|
||||
if is != nil {
|
||||
t.Fatalf("expected nil instancestate, got: %#v", is)
|
||||
}
|
||||
|
||||
// should handle non-nil but empty
|
||||
is = &terraform.InstanceState{}
|
||||
is, err = resourceComputeAddressMigrateState(0, is, meta)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("err: %#v", err)
|
||||
}
|
||||
}
|
@ -11,70 +11,6 @@ import (
|
||||
"google.golang.org/api/compute/v1"
|
||||
)
|
||||
|
||||
// Unit tests
|
||||
|
||||
func TestComputeAddressIdParsing(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
ImportId string
|
||||
ExpectedError bool
|
||||
ExpectedCanonicalId string
|
||||
Config *Config
|
||||
}{
|
||||
"id is a full self link": {
|
||||
ImportId: "https://www.googleapis.com/compute/v1/projects/test-project/regions/us-central1/addresses/test-address",
|
||||
ExpectedError: false,
|
||||
ExpectedCanonicalId: "projects/test-project/regions/us-central1/addresses/test-address",
|
||||
},
|
||||
"id is a partial self link": {
|
||||
ImportId: "projects/test-project/regions/us-central1/addresses/test-address",
|
||||
ExpectedError: false,
|
||||
ExpectedCanonicalId: "projects/test-project/regions/us-central1/addresses/test-address",
|
||||
},
|
||||
"id is project/region/address": {
|
||||
ImportId: "test-project/us-central1/test-address",
|
||||
ExpectedError: false,
|
||||
ExpectedCanonicalId: "projects/test-project/regions/us-central1/addresses/test-address",
|
||||
},
|
||||
"id is region/address": {
|
||||
ImportId: "us-central1/test-address",
|
||||
ExpectedError: false,
|
||||
ExpectedCanonicalId: "projects/default-project/regions/us-central1/addresses/test-address",
|
||||
Config: &Config{Project: "default-project"},
|
||||
},
|
||||
"id is address": {
|
||||
ImportId: "test-address",
|
||||
ExpectedError: false,
|
||||
ExpectedCanonicalId: "projects/default-project/regions/us-east1/addresses/test-address",
|
||||
Config: &Config{Project: "default-project", Region: "us-east1"},
|
||||
},
|
||||
"id has invalid format": {
|
||||
ImportId: "i/n/v/a/l/i/d",
|
||||
ExpectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for tn, tc := range cases {
|
||||
addressId, err := parseComputeAddressId(tc.ImportId, tc.Config)
|
||||
|
||||
if tc.ExpectedError && err == nil {
|
||||
t.Fatalf("bad: %s, expected an error", tn)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if tc.ExpectedError {
|
||||
continue
|
||||
}
|
||||
t.Fatalf("bad: %s, err: %#v", tn, err)
|
||||
}
|
||||
|
||||
if addressId.canonicalId() != tc.ExpectedCanonicalId {
|
||||
t.Fatalf("bad: %s, expected canonical id to be `%s` but is `%s`", tn, tc.ExpectedCanonicalId, addressId.canonicalId())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Acceptance tests
|
||||
|
||||
func TestAccComputeAddress_basic(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user