Add LabelFingerprint and Label to Address and GlobalAddress. (#1811)

This commit is contained in:
The Magician 2018-07-25 13:25:16 -07:00 committed by Nathan McKinley
parent 7da529f3c1
commit 0fdc262183
5 changed files with 296 additions and 5 deletions

View File

@ -29,6 +29,7 @@ func resourceComputeAddress() *schema.Resource {
return &schema.Resource{
Create: resourceComputeAddressCreate,
Read: resourceComputeAddressRead,
Update: resourceComputeAddressUpdate,
Delete: resourceComputeAddressDelete,
Importer: &schema.ResourceImporter{
@ -37,6 +38,7 @@ func resourceComputeAddress() *schema.Resource {
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(240 * time.Second),
Update: schema.DefaultTimeout(240 * time.Second),
Delete: schema.DefaultTimeout(240 * time.Second),
},
@ -79,6 +81,11 @@ func resourceComputeAddress() *schema.Resource {
ForceNew: true,
DiffSuppressFunc: compareSelfLinkOrResourceName,
},
"labels": {
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"region": {
Type: schema.TypeString,
Computed: true,
@ -90,6 +97,10 @@ func resourceComputeAddress() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"label_fingerprint": {
Type: schema.TypeString,
Computed: true,
},
"users": {
Type: schema.TypeList,
Computed: true,
@ -156,6 +167,12 @@ func resourceComputeAddressCreate(d *schema.ResourceData, meta interface{}) erro
} else if v, ok := d.GetOkExists("subnetwork"); !isEmptyValue(reflect.ValueOf(subnetworkProp)) && (ok || !reflect.DeepEqual(v, subnetworkProp)) {
obj["subnetwork"] = subnetworkProp
}
labelsProp, err := expandComputeAddressLabels(d.Get("labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
obj["labels"] = labelsProp
}
regionProp, err := expandComputeAddressRegion(d.Get("region"), d, config)
if err != nil {
return err
@ -199,6 +216,44 @@ func resourceComputeAddressCreate(d *schema.ResourceData, meta interface{}) erro
log.Printf("[DEBUG] Finished creating Address %q: %#v", d.Id(), res)
if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
// Labels cannot be set in a create. We'll have to set them here.
err = resourceComputeAddressRead(d, meta)
if err != nil {
return err
}
obj := make(map[string]interface{})
// d.Get("labels") will have been overridden by the Read call.
labelsProp, err := expandComputeAddressLabels(v, d, config)
obj["labels"] = labelsProp
labelFingerprintProp := d.Get("label_fingerprint")
obj["labelFingerprint"] = labelFingerprintProp
url, err = replaceVars(d, config, "https://www.googleapis.com/compute/beta/projects/{{project}}/regions/{{region}}/addresses/{{name}}/setLabels")
if err != nil {
return err
}
res, err = sendRequest(config, "POST", url, obj)
if err != nil {
return fmt.Errorf("Error adding labels to ComputeAddress %q: %s", d.Id(), err)
}
err = Convert(res, op)
if err != nil {
return err
}
err = computeOperationWaitTime(
config.clientCompute, op, project, "Updating ComputeAddress Labels",
int(d.Timeout(schema.TimeoutUpdate).Minutes()))
if err != nil {
return err
}
}
return resourceComputeAddressRead(d, meta)
}
@ -244,6 +299,12 @@ func resourceComputeAddressRead(d *schema.ResourceData, meta interface{}) error
if err := d.Set("users", flattenComputeAddressUsers(res["users"])); err != nil {
return fmt.Errorf("Error reading Address: %s", err)
}
if err := d.Set("labels", flattenComputeAddressLabels(res["labels"])); err != nil {
return fmt.Errorf("Error reading Address: %s", err)
}
if err := d.Set("label_fingerprint", flattenComputeAddressLabelFingerprint(res["labelFingerprint"])); err != nil {
return fmt.Errorf("Error reading Address: %s", err)
}
if err := d.Set("region", flattenComputeAddressRegion(res["region"])); err != nil {
return fmt.Errorf("Error reading Address: %s", err)
}
@ -257,6 +318,62 @@ func resourceComputeAddressRead(d *schema.ResourceData, meta interface{}) error
return nil
}
func resourceComputeAddressUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
project, err := getProject(d, config)
if err != nil {
return err
}
var url string
var res map[string]interface{}
op := &compute.Operation{}
d.Partial(true)
if d.HasChange("labels") || d.HasChange("label_fingerprint") {
obj := make(map[string]interface{})
labelsProp, err := expandComputeAddressLabels(d.Get("labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
obj["labels"] = labelsProp
}
labelFingerprintProp := d.Get("label_fingerprint")
obj["labelFingerprint"] = labelFingerprintProp
url, err = replaceVars(d, config, "https://www.googleapis.com/compute/beta/projects/{{project}}/regions/{{region}}/addresses/{{name}}/setLabels")
if err != nil {
return err
}
res, err = sendRequest(config, "POST", url, obj)
if err != nil {
return fmt.Errorf("Error updating Address %q: %s", d.Id(), err)
}
err = Convert(res, op)
if err != nil {
return err
}
err = computeOperationWaitTime(
config.clientCompute, op, project, "Updating Address",
int(d.Timeout(schema.TimeoutUpdate).Minutes()))
if err != nil {
return err
}
d.SetPartial("labels")
d.SetPartial("label_fingerprint")
}
d.Partial(false)
return resourceComputeAddressRead(d, meta)
}
func resourceComputeAddressDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
@ -346,6 +463,14 @@ func flattenComputeAddressUsers(v interface{}) interface{} {
return v
}
func flattenComputeAddressLabels(v interface{}) interface{} {
return v
}
func flattenComputeAddressLabelFingerprint(v interface{}) interface{} {
return v
}
func flattenComputeAddressRegion(v interface{}) interface{} {
if v == nil {
return v
@ -381,6 +506,17 @@ func expandComputeAddressSubnetwork(v interface{}, d *schema.ResourceData, confi
return f.RelativeLink(), nil
}
func expandComputeAddressLabels(v interface{}, d *schema.ResourceData, config *Config) (map[string]string, error) {
if v == nil {
return map[string]string{}, nil
}
m := make(map[string]string)
for k, val := range v.(map[string]interface{}) {
m[k] = val.(string)
}
return m, nil
}
func expandComputeAddressRegion(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
f, err := parseGlobalFieldValue("regions", v.(string), "project", d, config, true)
if err != nil {

View File

@ -323,6 +323,7 @@ func resourceComputeForwardingRuleCreate(d *schema.ResourceData, meta interface{
}
obj := make(map[string]interface{})
// d.Get("labels") will have been overridden by the Read call.
labelsProp, err := expandComputeForwardingRuleLabels(v, d, config)
obj["labels"] = labelsProp
labelFingerprintProp := d.Get("label_fingerprint")
@ -334,7 +335,7 @@ func resourceComputeForwardingRuleCreate(d *schema.ResourceData, meta interface{
}
res, err = sendRequest(config, "POST", url, obj)
if err != nil {
return fmt.Errorf("Error adding labels to ForwardingRule %q: %s", d.Id(), err)
return fmt.Errorf("Error adding labels to ComputeForwardingRule %q: %s", d.Id(), err)
}
err = Convert(res, op)
@ -343,7 +344,7 @@ func resourceComputeForwardingRuleCreate(d *schema.ResourceData, meta interface{
}
err = computeOperationWaitTime(
config.clientCompute, op, project, "Updating ForwardingRule",
config.clientCompute, op, project, "Updating ComputeForwardingRule Labels",
int(d.Timeout(schema.TimeoutUpdate).Minutes()))
if err != nil {

View File

@ -29,6 +29,7 @@ func resourceComputeGlobalAddress() *schema.Resource {
return &schema.Resource{
Create: resourceComputeGlobalAddressCreate,
Read: resourceComputeGlobalAddressRead,
Update: resourceComputeGlobalAddressUpdate,
Delete: resourceComputeGlobalAddressDelete,
Importer: &schema.ResourceImporter{
@ -37,6 +38,7 @@ func resourceComputeGlobalAddress() *schema.Resource {
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(240 * time.Second),
Update: schema.DefaultTimeout(240 * time.Second),
Delete: schema.DefaultTimeout(240 * time.Second),
},
@ -51,6 +53,11 @@ func resourceComputeGlobalAddress() *schema.Resource {
Optional: true,
ForceNew: true,
},
"labels": {
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"ip_version": {
Type: schema.TypeString,
Optional: true,
@ -66,6 +73,10 @@ func resourceComputeGlobalAddress() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"label_fingerprint": {
Type: schema.TypeString,
Computed: true,
},
"project": {
Type: schema.TypeString,
Optional: true,
@ -101,6 +112,12 @@ func resourceComputeGlobalAddressCreate(d *schema.ResourceData, meta interface{}
} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
obj["name"] = nameProp
}
labelsProp, err := expandComputeGlobalAddressLabels(d.Get("labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
obj["labels"] = labelsProp
}
ipVersionProp, err := expandComputeGlobalAddressIpVersion(d.Get("ip_version"), d, config)
if err != nil {
return err
@ -108,7 +125,7 @@ func resourceComputeGlobalAddressCreate(d *schema.ResourceData, meta interface{}
obj["ipVersion"] = ipVersionProp
}
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/global/addresses")
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/beta/projects/{{project}}/global/addresses")
if err != nil {
return err
}
@ -144,6 +161,44 @@ func resourceComputeGlobalAddressCreate(d *schema.ResourceData, meta interface{}
log.Printf("[DEBUG] Finished creating GlobalAddress %q: %#v", d.Id(), res)
if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
// Labels cannot be set in a create. We'll have to set them here.
err = resourceComputeGlobalAddressRead(d, meta)
if err != nil {
return err
}
obj := make(map[string]interface{})
// d.Get("labels") will have been overridden by the Read call.
labelsProp, err := expandComputeGlobalAddressLabels(v, d, config)
obj["labels"] = labelsProp
labelFingerprintProp := d.Get("label_fingerprint")
obj["labelFingerprint"] = labelFingerprintProp
url, err = replaceVars(d, config, "https://www.googleapis.com/compute/beta/projects/{{project}}/global/addresses/{{name}}/setLabels")
if err != nil {
return err
}
res, err = sendRequest(config, "POST", url, obj)
if err != nil {
return fmt.Errorf("Error adding labels to ComputeGlobalAddress %q: %s", d.Id(), err)
}
err = Convert(res, op)
if err != nil {
return err
}
err = computeOperationWaitTime(
config.clientCompute, op, project, "Updating ComputeGlobalAddress Labels",
int(d.Timeout(schema.TimeoutUpdate).Minutes()))
if err != nil {
return err
}
}
return resourceComputeGlobalAddressRead(d, meta)
}
@ -155,7 +210,7 @@ func resourceComputeGlobalAddressRead(d *schema.ResourceData, meta interface{})
return err
}
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/global/addresses/{{name}}")
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/beta/projects/{{project}}/global/addresses/{{name}}")
if err != nil {
return err
}
@ -177,6 +232,12 @@ func resourceComputeGlobalAddressRead(d *schema.ResourceData, meta interface{})
if err := d.Set("name", flattenComputeGlobalAddressName(res["name"])); err != nil {
return fmt.Errorf("Error reading GlobalAddress: %s", err)
}
if err := d.Set("labels", flattenComputeGlobalAddressLabels(res["labels"])); err != nil {
return fmt.Errorf("Error reading GlobalAddress: %s", err)
}
if err := d.Set("label_fingerprint", flattenComputeGlobalAddressLabelFingerprint(res["labelFingerprint"])); err != nil {
return fmt.Errorf("Error reading GlobalAddress: %s", err)
}
if err := d.Set("ip_version", flattenComputeGlobalAddressIpVersion(res["ipVersion"])); err != nil {
return fmt.Errorf("Error reading GlobalAddress: %s", err)
}
@ -190,6 +251,62 @@ func resourceComputeGlobalAddressRead(d *schema.ResourceData, meta interface{})
return nil
}
func resourceComputeGlobalAddressUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
project, err := getProject(d, config)
if err != nil {
return err
}
var url string
var res map[string]interface{}
op := &compute.Operation{}
d.Partial(true)
if d.HasChange("labels") || d.HasChange("label_fingerprint") {
obj := make(map[string]interface{})
labelsProp, err := expandComputeGlobalAddressLabels(d.Get("labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
obj["labels"] = labelsProp
}
labelFingerprintProp := d.Get("label_fingerprint")
obj["labelFingerprint"] = labelFingerprintProp
url, err = replaceVars(d, config, "https://www.googleapis.com/compute/beta/projects/{{project}}/global/addresses/{{name}}/setLabels")
if err != nil {
return err
}
res, err = sendRequest(config, "POST", url, obj)
if err != nil {
return fmt.Errorf("Error updating GlobalAddress %q: %s", d.Id(), err)
}
err = Convert(res, op)
if err != nil {
return err
}
err = computeOperationWaitTime(
config.clientCompute, op, project, "Updating GlobalAddress",
int(d.Timeout(schema.TimeoutUpdate).Minutes()))
if err != nil {
return err
}
d.SetPartial("labels")
d.SetPartial("label_fingerprint")
}
d.Partial(false)
return resourceComputeGlobalAddressRead(d, meta)
}
func resourceComputeGlobalAddressDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
@ -198,7 +315,7 @@ func resourceComputeGlobalAddressDelete(d *schema.ResourceData, meta interface{}
return err
}
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/global/addresses/{{name}}")
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/beta/projects/{{project}}/global/addresses/{{name}}")
if err != nil {
return err
}
@ -257,6 +374,14 @@ func flattenComputeGlobalAddressName(v interface{}) interface{} {
return v
}
func flattenComputeGlobalAddressLabels(v interface{}) interface{} {
return v
}
func flattenComputeGlobalAddressLabelFingerprint(v interface{}) interface{} {
return v
}
func flattenComputeGlobalAddressIpVersion(v interface{}) interface{} {
return v
}
@ -269,6 +394,17 @@ func expandComputeGlobalAddressName(v interface{}, d *schema.ResourceData, confi
return v, nil
}
func expandComputeGlobalAddressLabels(v interface{}, d *schema.ResourceData, config *Config) (map[string]string, error) {
if v == nil {
return map[string]string{}, nil
}
m := make(map[string]string)
for k, val := range v.(map[string]interface{}) {
m[k] = val.(string)
}
return m, nil
}
func expandComputeGlobalAddressIpVersion(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}

View File

@ -116,6 +116,10 @@ The following arguments are supported:
This field can only be used with INTERNAL type with
GCE_ENDPOINT/DNS_RESOLVER purposes.
* `labels` -
(Optional)
Labels to apply to this address. A list of key->value pairs.
* `region` -
(Optional)
The Region in which the created address should reside.
@ -134,6 +138,10 @@ In addition to the arguments listed above, the following computed attributes are
* `users` -
The URLs of the resources that are using this address.
* `label_fingerprint` -
The fingerprint used for optimistic locking of this resource. Used
internally during updates.
* `self_link` - The URI of the created resource.
@ -145,6 +153,7 @@ This resource provides the following
[Timeouts](/docs/configuration/resources.html#timeouts) configuration options:
- `create` - Default is 4 minutes.
- `update` - Default is 4 minutes.
- `delete` - Default is 4 minutes.
## Import

View File

@ -61,6 +61,10 @@ The following arguments are supported:
An optional description of this resource.
Provide this property when you create the resource.
* `labels` -
(Optional)
Labels to apply to this address. A list of key->value pairs.
* `ip_version` -
(Optional)
The IP Version that will be used by this address. Valid options are
@ -79,6 +83,10 @@ In addition to the arguments listed above, the following computed attributes are
* `creation_timestamp` -
Creation timestamp in RFC3339 text format.
* `label_fingerprint` -
The fingerprint used for optimistic locking of this resource. Used
internally during updates.
* `self_link` - The URI of the created resource.
@ -88,6 +96,7 @@ This resource provides the following
[Timeouts](/docs/configuration/resources.html#timeouts) configuration options:
- `create` - Default is 4 minutes.
- `update` - Default is 4 minutes.
- `delete` - Default is 4 minutes.
## Import