Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add properties field to apigee environment resource #9072

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/12752.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
apigee: added `properties` field to `google_apigee_environment` resource
```
144 changes: 144 additions & 0 deletions google-beta/services/apigee/resource_apigee_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,35 @@ all instances.`,
},
},
},
"properties": {
Type: schema.TypeList,
Optional: true,
Description: `Key-value pairs that may be used for customizing the environment.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"property": {
Type: schema.TypeList,
Optional: true,
Description: `List of all properties in the object.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
Description: `The property key.`,
},
"value": {
Type: schema.TypeString,
Optional: true,
Description: `The property value.`,
},
},
},
},
},
},
},
"type": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -203,6 +232,12 @@ func resourceApigeeEnvironmentCreate(d *schema.ResourceData, meta interface{}) e
} else if v, ok := d.GetOkExists("forward_proxy_uri"); !tpgresource.IsEmptyValue(reflect.ValueOf(forwardProxyUriProp)) && (ok || !reflect.DeepEqual(v, forwardProxyUriProp)) {
obj["forwardProxyUri"] = forwardProxyUriProp
}
propertiesProp, err := expandApigeeEnvironmentProperties(d.Get("properties"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("properties"); !tpgresource.IsEmptyValue(reflect.ValueOf(propertiesProp)) && (ok || !reflect.DeepEqual(v, propertiesProp)) {
obj["properties"] = propertiesProp
}

url, err := tpgresource.ReplaceVars(d, config, "{{ApigeeBasePath}}{{org_id}}/environments")
if err != nil {
Expand Down Expand Up @@ -324,6 +359,9 @@ func resourceApigeeEnvironmentRead(d *schema.ResourceData, meta interface{}) err
if err := d.Set("forward_proxy_uri", flattenApigeeEnvironmentForwardProxyUri(res["forwardProxyUri"], d, config)); err != nil {
return fmt.Errorf("Error reading Environment: %s", err)
}
if err := d.Set("properties", flattenApigeeEnvironmentProperties(res["properties"], d, config)); err != nil {
return fmt.Errorf("Error reading Environment: %s", err)
}

return nil
}
Expand Down Expand Up @@ -368,6 +406,12 @@ func resourceApigeeEnvironmentUpdate(d *schema.ResourceData, meta interface{}) e
} else if v, ok := d.GetOkExists("forward_proxy_uri"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, forwardProxyUriProp)) {
obj["forwardProxyUri"] = forwardProxyUriProp
}
propertiesProp, err := expandApigeeEnvironmentProperties(d.Get("properties"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("properties"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, propertiesProp)) {
obj["properties"] = propertiesProp
}

url, err := tpgresource.ReplaceVars(d, config, "{{ApigeeBasePath}}{{org_id}}/environments/{{name}}")
if err != nil {
Expand Down Expand Up @@ -397,6 +441,10 @@ func resourceApigeeEnvironmentUpdate(d *schema.ResourceData, meta interface{}) e
if d.HasChange("forward_proxy_uri") {
updateMask = append(updateMask, "forwardProxyUri")
}

if d.HasChange("properties") {
updateMask = append(updateMask, "properties")
}
// updateMask is a URL parameter but not present in the schema, so ReplaceVars
// won't set it
url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
Expand Down Expand Up @@ -585,6 +633,46 @@ func flattenApigeeEnvironmentForwardProxyUri(v interface{}, d *schema.ResourceDa
return v
}

func flattenApigeeEnvironmentProperties(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["property"] =
flattenApigeeEnvironmentPropertiesProperty(original["property"], d, config)
return []interface{}{transformed}
}
func flattenApigeeEnvironmentPropertiesProperty(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return v
}
l := v.([]interface{})
transformed := make([]interface{}, 0, len(l))
for _, raw := range l {
original := raw.(map[string]interface{})
if len(original) < 1 {
// Do not include empty json objects coming back from the api
continue
}
transformed = append(transformed, map[string]interface{}{
"name": flattenApigeeEnvironmentPropertiesPropertyName(original["name"], d, config),
"value": flattenApigeeEnvironmentPropertiesPropertyValue(original["value"], d, config),
})
}
return transformed
}
func flattenApigeeEnvironmentPropertiesPropertyName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenApigeeEnvironmentPropertiesPropertyValue(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func expandApigeeEnvironmentName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
Expand Down Expand Up @@ -657,3 +745,59 @@ func expandApigeeEnvironmentType(v interface{}, d tpgresource.TerraformResourceD
func expandApigeeEnvironmentForwardProxyUri(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandApigeeEnvironmentProperties(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedProperty, err := expandApigeeEnvironmentPropertiesProperty(original["property"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedProperty); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["property"] = transformedProperty
}

return transformed, nil
}

func expandApigeeEnvironmentPropertiesProperty(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
req := make([]interface{}, 0, len(l))
for _, raw := range l {
if raw == nil {
continue
}
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedName, err := expandApigeeEnvironmentPropertiesPropertyName(original["name"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedName); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["name"] = transformedName
}

transformedValue, err := expandApigeeEnvironmentPropertiesPropertyValue(original["value"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedValue); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["value"] = transformedValue
}

req = append(req, transformed)
}
return req, nil
}

func expandApigeeEnvironmentPropertiesPropertyName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandApigeeEnvironmentPropertiesPropertyValue(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,117 @@ resource "google_apigee_environment" "apigee_environment" {
`, context)
}

func TestAccApigeeEnvironment_apigeeEnvironmentBasicPropertiesTestExample(t *testing.T) {
acctest.SkipIfVcr(t)
t.Parallel()

context := map[string]interface{}{
"billing_account": envvar.GetTestBillingAccountFromEnv(t),
"org_id": envvar.GetTestOrgFromEnv(t),
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
ExternalProviders: map[string]resource.ExternalProvider{
"time": {},
},
CheckDestroy: testAccCheckApigeeEnvironmentDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccApigeeEnvironment_apigeeEnvironmentBasicPropertiesTestExample(context),
},
{
ResourceName: "google_apigee_environment.apigee_environment",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"org_id"},
},
},
})
}

func testAccApigeeEnvironment_apigeeEnvironmentBasicPropertiesTestExample(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_project" "project" {
project_id = "tf-test%{random_suffix}"
name = "tf-test%{random_suffix}"
org_id = "%{org_id}"
billing_account = "%{billing_account}"
deletion_policy = "DELETE"
}

resource "time_sleep" "wait_60_seconds" {
create_duration = "60s"
depends_on = [google_project.project]
}

resource "google_project_service" "apigee" {
project = google_project.project.project_id
service = "apigee.googleapis.com"
depends_on = [time_sleep.wait_60_seconds]
}

resource "google_project_service" "servicenetworking" {
project = google_project.project.project_id
service = "servicenetworking.googleapis.com"
depends_on = [google_project_service.apigee]
}

resource "google_project_service" "compute" {
project = google_project.project.project_id
service = "compute.googleapis.com"
depends_on = [google_project_service.servicenetworking]
}

resource "google_compute_network" "apigee_network" {
name = "apigee-network"
project = google_project.project.project_id
depends_on = [google_project_service.compute]
}

resource "google_compute_global_address" "apigee_range" {
name = "apigee-range"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = google_compute_network.apigee_network.id
project = google_project.project.project_id
}

resource "google_service_networking_connection" "apigee_vpc_connection" {
network = google_compute_network.apigee_network.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.apigee_range.name]
depends_on = [google_project_service.servicenetworking]
}

resource "google_apigee_organization" "apigee_org" {
analytics_region = "us-central1"
project_id = google_project.project.project_id
authorized_network = google_compute_network.apigee_network.id
depends_on = [
google_service_networking_connection.apigee_vpc_connection,
google_project_service.apigee,
]
}

resource "google_apigee_environment" "apigee_environment" {
org_id = google_apigee_organization.apigee_org.id
name = "tf-test%{random_suffix}"
description = "Apigee Environment"
display_name = "environment-1"
properties {
property {
name = "property-1-key"
value = "property-1-value"
}
}
}
`, context)
}

func TestAccApigeeEnvironment_apigeeEnvironmentPatchUpdateTestExample(t *testing.T) {
acctest.SkipIfVcr(t)
t.Parallel()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ resource "google_apigee_environment" "apigee_environment" {
name = "tf-test%{random_suffix}"
description = "Updated Apigee Environment Description"
display_name = "environment-1-updated"
properties {
property {
name = "property-1-key"
value = "property-1-value"
}
}
}
`, context)
}
23 changes: 23 additions & 0 deletions website/docs/r/apigee_environment.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ The following arguments are supported:
(Optional)
Optional. URI of the forward proxy to be applied to the runtime instances in this environment. Must be in the format of {scheme}://{hostname}:{port}. Note that the scheme must be one of "http" or "https", and the port must be supplied.

* `properties` -
(Optional)
Key-value pairs that may be used for customizing the environment.
Structure is [documented below](#nested_properties).


<a name="nested_node_config"></a>The `node_config` block supports:

Expand All @@ -147,6 +152,24 @@ The following arguments are supported:
The current total number of gateway nodes that each environment currently has across
all instances.

<a name="nested_properties"></a>The `properties` block supports:

* `property` -
(Optional)
List of all properties in the object.
Structure is [documented below](#nested_properties_property).


<a name="nested_properties_property"></a>The `property` block supports:

* `name` -
(Optional)
The property key.

* `value` -
(Optional)
The property value.

## Attributes Reference

In addition to the arguments listed above, the following computed attributes are exported:
Expand Down
Loading