/
self_link_helpers.go
144 lines (119 loc) · 3.76 KB
/
self_link_helpers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package google
import (
"errors"
"fmt"
"net/url"
"regexp"
"strings"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
)
// Compare only the relative path of two self links.
func compareSelfLinkRelativePaths(_, old, new string, _ *schema.ResourceData) bool {
oldStripped, err := getRelativePath(old)
if err != nil {
return false
}
newStripped, err := getRelativePath(new)
if err != nil {
return false
}
if oldStripped == newStripped {
return true
}
return false
}
// compareSelfLinkOrResourceName checks if two resources are the same resource
//
// Use this method when the field accepts either a name or a self_link referencing a resource.
// The value we store (i.e. `old` in this method), must be a self_link.
func compareSelfLinkOrResourceName(_, old, new string, _ *schema.ResourceData) bool {
newParts := strings.Split(new, "/")
if len(newParts) == 1 {
// `new` is a name
// `old` is always a self_link
if GetResourceNameFromSelfLink(old) == newParts[0] {
return true
}
}
// The `new` string is a self_link
return compareSelfLinkRelativePaths("", old, new, nil)
}
// Hash the relative path of a self link.
func selfLinkRelativePathHash(selfLink interface{}) int {
path, _ := getRelativePath(selfLink.(string))
return hashcode.String(path)
}
func getRelativePath(selfLink string) (string, error) {
stringParts := strings.SplitAfterN(selfLink, "projects/", 2)
if len(stringParts) != 2 {
return "", fmt.Errorf("String was not a self link: %s", selfLink)
}
return "projects/" + stringParts[1], nil
}
// Hash the name path of a self link.
func selfLinkNameHash(selfLink interface{}) int {
name := GetResourceNameFromSelfLink(selfLink.(string))
return hashcode.String(name)
}
func ConvertSelfLinkToV1(link string) string {
reg := regexp.MustCompile("/compute/[a-zA-Z0-9]*/projects/")
return reg.ReplaceAllString(link, "/compute/v1/projects/")
}
func GetResourceNameFromSelfLink(link string) string {
parts := strings.Split(link, "/")
return parts[len(parts)-1]
}
func NameFromSelfLinkStateFunc(v interface{}) string {
return GetResourceNameFromSelfLink(v.(string))
}
func StoreResourceName(resourceLink interface{}) string {
return GetResourceNameFromSelfLink(resourceLink.(string))
}
type LocationType int
const (
Zonal LocationType = iota
Regional
Global
)
func GetZonalResourcePropertiesFromSelfLinkOrSchema(d *schema.ResourceData, config *Config) (string, string, string, error) {
return getResourcePropertiesFromSelfLinkOrSchema(d, config, Zonal)
}
func GetRegionalResourcePropertiesFromSelfLinkOrSchema(d *schema.ResourceData, config *Config) (string, string, string, error) {
return getResourcePropertiesFromSelfLinkOrSchema(d, config, Regional)
}
func getResourcePropertiesFromSelfLinkOrSchema(d *schema.ResourceData, config *Config, locationType LocationType) (string, string, string, error) {
if selfLink, ok := d.GetOk("self_link"); ok {
parsed, err := url.Parse(selfLink.(string))
if err != nil {
return "", "", "", err
}
s := strings.Split(parsed.Path, "/")
// https://www.googleapis.com/compute/beta/projects/project_name/regions/region_name/instanceGroups/foobarbaz
// => project_name, region_name, foobarbaz
return s[4], s[6], s[8], nil
} else {
project, err := getProject(d, config)
if err != nil {
return "", "", "", err
}
location := ""
if locationType == Regional {
location, err = getRegion(d, config)
if err != nil {
return "", "", "", err
}
} else if locationType == Zonal {
location, err = getZone(d, config)
if err != nil {
return "", "", "", err
}
}
n, ok := d.GetOk("name")
name := n.(string)
if !ok {
return "", "", "", errors.New("must provide either `self_link` or `name`")
}
return project, location, name, nil
}
}