Skip to content

Commit 1677a91

Browse files
Add data source for Interconnect Location
1 parent 9f33eb2 commit 1677a91

File tree

3 files changed

+257
-0
lines changed

3 files changed

+257
-0
lines changed

mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ var handwrittenDatasources = map[string]*schema.Resource{
8989
"google_compute_instance_serial_port": compute.DataSourceGoogleComputeInstanceSerialPort(),
9090
"google_compute_instance_template": compute.DataSourceGoogleComputeInstanceTemplate(),
9191
"google_compute_instance_guest_attributes": compute.DataSourceGoogleComputeInstanceGuestAttributes(),
92+
"google_compute_interconnect_location": compute.DataSourceGoogleComputeInterconnectLocation(),
9293
"google_compute_lb_ip_ranges": compute.DataSourceGoogleComputeLbIpRanges(),
9394
"google_compute_machine_types": compute.DataSourceGoogleComputeMachineTypes(),
9495
"google_compute_network": compute.DataSourceGoogleComputeNetwork(),
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package compute
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"strings"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
10+
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
11+
)
12+
13+
var (
14+
computeInterconnectLocationIdTemplate = "projects/%s/global/interconnectlocations/%s"
15+
computeInterconnectLocationLinkRegex = regexp.MustCompile(`projects/(.+)/global/interconnectlocations/(.+)$`)
16+
)
17+
18+
type ComputeInterconnectLocationId struct {
19+
Project string
20+
Name string
21+
}
22+
23+
func (s ComputeInterconnectLocationId) CanonicalId() string {
24+
return fmt.Sprintf(computeInterconnectLocationIdTemplate, s.Project, s.Name)
25+
}
26+
27+
// ParseComputeInterconnectLocationId parses IDs of the form:
28+
// - projects/{project}/global/interconnectlocations/{name}
29+
// - {project}/{name}
30+
// - {name} (requires config.Project)
31+
func ParseComputeInterconnectLocationId(id string, config *transport_tpg.Config) (*ComputeInterconnectLocationId, error) {
32+
var parts []string
33+
if computeInterconnectLocationLinkRegex.MatchString(id) {
34+
parts = computeInterconnectLocationLinkRegex.FindStringSubmatch(id)
35+
return &ComputeInterconnectLocationId{
36+
Project: parts[1],
37+
Name: parts[2],
38+
}, nil
39+
} else {
40+
parts = strings.Split(id, "/")
41+
}
42+
if len(parts) == 2 {
43+
return &ComputeInterconnectLocationId{
44+
Project: parts[0],
45+
Name: parts[1],
46+
}, nil
47+
} else if len(parts) == 1 {
48+
if config.Project == "" {
49+
return nil, fmt.Errorf("The default project for the provider must be set when using the `{name}` id format.")
50+
}
51+
return &ComputeInterconnectLocationId{
52+
Project: config.Project,
53+
Name: parts[0],
54+
}, nil
55+
}
56+
return nil, fmt.Errorf("Invalid interconnect location id. Expecting resource link, `{project}/{name}` or `{name}` format.")
57+
}
58+
func DataSourceGoogleComputeInterconnectLocation() *schema.Resource {
59+
return &schema.Resource{
60+
Read: dataSourceGoogleComputeInterconnectLocationRead,
61+
Schema: map[string]*schema.Schema{
62+
"name": {
63+
Type: schema.TypeString,
64+
Required: true,
65+
},
66+
"project": {
67+
Type: schema.TypeString,
68+
Optional: true,
69+
Computed: true,
70+
},
71+
"self_link": {
72+
Type: schema.TypeString,
73+
Computed: true,
74+
},
75+
"description": {
76+
Type: schema.TypeString,
77+
Computed: true,
78+
},
79+
"peeringdb_facility_id": {
80+
Type: schema.TypeString,
81+
Computed: true,
82+
},
83+
"address": {
84+
Type: schema.TypeString,
85+
Computed: true,
86+
},
87+
"facility_provider": {
88+
Type: schema.TypeString,
89+
Computed: true,
90+
},
91+
"facility_provider_facility_id": {
92+
Type: schema.TypeString,
93+
Computed: true,
94+
},
95+
"continent": {
96+
Type: schema.TypeString,
97+
Computed: true,
98+
},
99+
"city": {
100+
Type: schema.TypeString,
101+
Computed: true,
102+
},
103+
"availability_zone": {
104+
Type: schema.TypeString,
105+
Computed: true,
106+
},
107+
"status": {
108+
Type: schema.TypeString,
109+
Computed: true,
110+
},
111+
},
112+
}
113+
}
114+
func dataSourceGoogleComputeInterconnectLocationRead(d *schema.ResourceData, meta interface{}) error {
115+
config := meta.(*transport_tpg.Config)
116+
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
117+
if err != nil {
118+
return err
119+
}
120+
project, err := tpgresource.GetProject(d, config)
121+
if err != nil {
122+
return err
123+
}
124+
name := d.Get("name").(string)
125+
id := fmt.Sprintf("projects/%s/global/interconnectlocations/%s", project, name)
126+
location, err := config.NewComputeClient(userAgent).InterconnectLocations.Get(project, name).Do()
127+
if err != nil {
128+
return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("InterconnectLocation Not Found : %s", name), id)
129+
}
130+
d.SetId(location.Name)
131+
if err := d.Set("project", project); err != nil {
132+
return fmt.Errorf("Error setting project: %s", err)
133+
}
134+
if err := d.Set("self_link", location.SelfLink); err != nil {
135+
return fmt.Errorf("Error setting self_link: %s", err)
136+
}
137+
if err := d.Set("description", location.Description); err != nil {
138+
return fmt.Errorf("Error setting description: %s", err)
139+
}
140+
if err := d.Set("peeringdb_facility_id", location.PeeringdbFacilityId); err != nil {
141+
return fmt.Errorf("Error setting peeringdb_facility_id: %s", err)
142+
}
143+
if err := d.Set("address", location.Address); err != nil {
144+
return fmt.Errorf("Error setting address: %s", err)
145+
}
146+
if err := d.Set("facility_provider", location.FacilityProvider); err != nil {
147+
return fmt.Errorf("Error setting facility_provider: %s", err)
148+
}
149+
if err := d.Set("facility_provider_facility_id", location.FacilityProviderFacilityId); err != nil {
150+
return fmt.Errorf("Error setting facility_provider_facility_id: %s", err)
151+
}
152+
if err := d.Set("continent", location.Continent); err != nil {
153+
return fmt.Errorf("Error setting continent: %s", err)
154+
}
155+
if err := d.Set("city", location.City); err != nil {
156+
return fmt.Errorf("Error setting city: %s", err)
157+
}
158+
if err := d.Set("availability_zone", location.AvailabilityZone); err != nil {
159+
return fmt.Errorf("Error setting availability_zone: %s", err)
160+
}
161+
if err := d.Set("status", location.Status); err != nil {
162+
return fmt.Errorf("Error setting status: %s", err)
163+
}
164+
d.SetId(id)
165+
return nil
166+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package compute_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-testing/terraform"
9+
"github.com/hashicorp/terraform-provider-google/google/acctest"
10+
"github.com/hashicorp/terraform-provider-google/google/services/compute"
11+
"github.com/hashicorp/terraform-provider-google/google/transport"
12+
)
13+
14+
var interconnectLoc = "z2z-us-west8-zone2-ncphxk-z"
15+
16+
func testAccDataSourceCheckInterconnectLocation() func(s *terraform.State) error {
17+
return func(s *terraform.State) error {
18+
data_source_name := "data.google_compute_interconnect_location.my_location"
19+
ds, ok := s.RootModule().Resources[data_source_name]
20+
if !ok {
21+
return fmt.Errorf("root module has no resource called %s", data_source_name)
22+
}
23+
ds_attr := ds.Primary.Attributes
24+
expected := map[string]string{
25+
"name": interconnectLoc,
26+
"description": "Zakim-to-Zakim location",
27+
"facility_provider": "Google",
28+
}
29+
for attr, expect_value := range expected {
30+
if ds_attr[attr] != expect_value {
31+
return fmt.Errorf("%s is %s; want %s", attr, ds_attr[attr], expect_value)
32+
}
33+
}
34+
if ds_attr["self_link"] == "" {
35+
return fmt.Errorf("self_link is not set")
36+
}
37+
return nil
38+
}
39+
}
40+
func TestAccDataSourceGoogleComputeInterconnectLocation_basic(t *testing.T) {
41+
acctest.VcrTest(t, resource.TestCase{
42+
PreCheck: func() { acctest.AccTestPreCheck(t) },
43+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
44+
Steps: []resource.TestStep{
45+
{
46+
Config: testAccDataSourceGoogleComputeInterconnectLocationConfig(interconnectLoc),
47+
Check: resource.ComposeTestCheckFunc(
48+
testAccDataSourceCheckInterconnectLocation(),
49+
),
50+
},
51+
},
52+
})
53+
}
54+
func testAccDataSourceGoogleComputeInterconnectLocationConfig(locationName string) string {
55+
return fmt.Sprintf(`
56+
data "google_compute_interconnect_location" "my_location" {
57+
name = "%s"
58+
}
59+
`, locationName)
60+
}
61+
func TestParseComputeInterconnectLocationId(t *testing.T) {
62+
config := &transport.Config{Project: "my-project"}
63+
cases := []struct {
64+
id string
65+
wantProj string
66+
wantName string
67+
wantErr bool
68+
}{
69+
{"projects/my-project/global/interconnectlocations/z2z-us-west8-zone2-ncphxk-z", "my-project", interconnectLoc, false},
70+
{"my-project/z2z-us-west8-zone2-ncphxk-z", "my-project", interconnectLoc, false},
71+
{interconnectLoc, "my-project", interconnectLoc, false},
72+
{"invalid/format/extra", "", "", true},
73+
}
74+
for _, tc := range cases {
75+
got, err := compute.ParseComputeInterconnectLocationId(tc.id, config)
76+
if tc.wantErr {
77+
if err == nil {
78+
t.Errorf("ParseComputeInterconnectLocationId(%q) expected error, got nil", tc.id)
79+
}
80+
continue
81+
}
82+
if err != nil {
83+
t.Errorf("ParseComputeInterconnectLocationId(%q) unexpected error: %v", tc.id, err)
84+
continue
85+
}
86+
if got.Project != tc.wantProj || got.Name != tc.wantName {
87+
t.Errorf("ParseComputeInterconnectLocationId(%q) = (%q, %q), want (%q, %q)", tc.id, got.Project, got.Name, tc.wantProj, tc.wantName)
88+
}
89+
}
90+
}

0 commit comments

Comments
 (0)