From fd5c40b02cd6a2dc71e879b808ead6fd66fba294 Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Fri, 2 Dec 2022 05:09:45 +0000 Subject: [PATCH 01/41] added sharedflows mmv1 with error --- mmv1/products/apigee/api.yaml | 85 ++++++++++++++++++++++++++++- mmv1/products/apigee/terraform.yaml | 3 + 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/mmv1/products/apigee/api.yaml b/mmv1/products/apigee/api.yaml index 79b42678d63a..b67e2752afca 100644 --- a/mmv1/products/apigee/api.yaml +++ b/mmv1/products/apigee/api.yaml @@ -659,4 +659,87 @@ objects: guides: 'Provisioning NAT IPs': 'https://cloud.google.com/apigee/docs/api-platform/security/nat-provisioning' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances.natAddresses' + api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances.natAddresses' + - !ruby/object:Api::Resource + name: 'SharedFlow' + base_url: 'organizations/{{org_id}}/sharedflows/{{name}}' + create_url: 'organizations/{{org_id}}/sharedflows?name={{name}}&action=import' + delete_url: 'organizations/{{org_id}}/sharedflows/{{name}}' + self_link: 'organizations/{{org_id}}/sharedflows/{{name}}' + async: !ruby/object:Api::OpAsync + operation: !ruby/object:Api::OpAsync::Operation + path: 'name' + base_url: '{{op_id}}' + wait_ms: 1000 + result: !ruby/object:Api::OpAsync::Result + path: 'response' + resource_inside_response: true + status: !ruby/object:Api::OpAsync::Status + path: 'done' + complete: True + allowed: + - True + - False + error: !ruby/object:Api::OpAsync::Error + path: 'error' + message: 'message' + input: true + description: | + You can combine policies and resources into a shared flow that you can consume from multiple API proxies, and even from other shared flows. Although it's like a proxy, a shared flow has no endpoint. It can be used only from an API proxy or shared flow that's in the same organization as the shared flow itself. + parameters: + - !ruby/object:Api::Type::String + name: 'orgId' + description: | + The Apigee Organization associated with the Apigee instance, + in the format `organizations/{{org_name}}`. + required: true + input: true + url_param_only: true + # - !ruby/object:Api::Type::String + # name: 'sharedFlowName' + # description: | + # ID of the shared flow. + # required: true + # input: true + # url_param_only: true + properties: + - !ruby/object:Api::Type::NestedObject + name: 'metaData' + description: | + Metadata describing the shared flow. + output: true + properties: + - !ruby/object:Api::Type::String + name: 'createdAt' + description: | + Time at which the API proxy was created, in milliseconds since epoch. + - !ruby/object:Api::Type::String + name: 'lastModifiedAt' + description: | + Time at which the API proxy was most recently modified, in milliseconds since epoch. + - !ruby/object:Api::Type::String + name: 'subType' + description: | + The type of entity described + - !ruby/object:Api::Type::String + name: 'name' + description: | + The ID of the shared flow. + required: true + - !ruby/object:Api::Type::Array + name: 'revision' + description: | + A list of revisions of this shared flow. + output: true + required: true + item_type: Api::Type::String + - !ruby/object:Api::Type::String + name: 'latestRevisionId' + description: | + The id of the most recently created revision for this shared flow. + output: true + references: !ruby/object:Api::Resource::ReferenceLinks + guides: + 'Sharedflows': + 'https://cloud.google.com/apigee/docs/resources' + api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.sharedflows' diff --git a/mmv1/products/apigee/terraform.yaml b/mmv1/products/apigee/terraform.yaml index b9086dd2bc0a..012b41674bd0 100644 --- a/mmv1/products/apigee/terraform.yaml +++ b/mmv1/products/apigee/terraform.yaml @@ -327,6 +327,9 @@ overrides: !ruby/object:Overrides::ResourceOverrides delete_minutes: 30 custom_code: !ruby/object:Provider::Terraform::CustomCode custom_import: templates/terraform/custom_import/apigee_nat_address.go.erb + SharedFlow: !ruby/object:Overrides::Terraform::ResourceOverride + autogen_async: true + # import_format: ["{{org_id}}/sharedflows/{{name}}", "{{org_id}}/{{name}}"] files: !ruby/object:Provider::Config::Files # These files have templating (ERB) code that will be run. # This is usually to add licensing info, autogeneration notices, etc. From 5c687f3bf34464df3215b4deda9d7edd7984b6c3 Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Fri, 2 Dec 2022 06:38:06 +0000 Subject: [PATCH 02/41] fix indentation issue for sharedflow --- mmv1/products/apigee/api.yaml | 48 +++++++++++++++-------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/mmv1/products/apigee/api.yaml b/mmv1/products/apigee/api.yaml index b67e2752afca..c088fbaa6a71 100644 --- a/mmv1/products/apigee/api.yaml +++ b/mmv1/products/apigee/api.yaml @@ -659,7 +659,7 @@ objects: guides: 'Provisioning NAT IPs': 'https://cloud.google.com/apigee/docs/api-platform/security/nat-provisioning' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances.natAddresses' + api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances.natAddresses' - !ruby/object:Api::Resource name: 'SharedFlow' base_url: 'organizations/{{org_id}}/sharedflows/{{name}}' @@ -695,32 +695,25 @@ objects: required: true input: true url_param_only: true - # - !ruby/object:Api::Type::String - # name: 'sharedFlowName' - # description: | - # ID of the shared flow. - # required: true - # input: true - # url_param_only: true properties: - - !ruby/object:Api::Type::NestedObject - name: 'metaData' - description: | - Metadata describing the shared flow. - output: true - properties: - - !ruby/object:Api::Type::String - name: 'createdAt' - description: | - Time at which the API proxy was created, in milliseconds since epoch. - - !ruby/object:Api::Type::String - name: 'lastModifiedAt' - description: | - Time at which the API proxy was most recently modified, in milliseconds since epoch. - - !ruby/object:Api::Type::String - name: 'subType' - description: | - The type of entity described + - !ruby/object:Api::Type::NestedObject + name: 'metaData' + description: | + Metadata describing the shared flow. + output: true + properties: + - !ruby/object:Api::Type::String + name: 'createdAt' + description: | + Time at which the API proxy was created, in milliseconds since epoch. + - !ruby/object:Api::Type::String + name: 'lastModifiedAt' + description: | + Time at which the API proxy was most recently modified, in milliseconds since epoch. + - !ruby/object:Api::Type::String + name: 'subType' + description: | + The type of entity described - !ruby/object:Api::Type::String name: 'name' description: | @@ -731,7 +724,6 @@ objects: description: | A list of revisions of this shared flow. output: true - required: true item_type: Api::Type::String - !ruby/object:Api::Type::String name: 'latestRevisionId' @@ -742,4 +734,4 @@ objects: guides: 'Sharedflows': 'https://cloud.google.com/apigee/docs/resources' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.sharedflows' + api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.sharedflows' \ No newline at end of file From 2a963f078a628e62a4edcfb70ae361adbbe24299 Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Mon, 5 Dec 2022 23:23:27 +0000 Subject: [PATCH 03/41] add semi auto generated resourceApigeeSharedFlow --- .../resources/resource_apigee_shared_flow.go | 390 ++++++++++++++++++ 1 file changed, 390 insertions(+) create mode 100644 mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go diff --git a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go b/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go new file mode 100644 index 000000000000..1a6793361fd3 --- /dev/null +++ b/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go @@ -0,0 +1,390 @@ + +// ---------------------------------------------------------------------------- +// +// This file is partially automatically generated by Magic Modules and with manual +// changes to resourceApigeeSharedFlowCreate +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "os" + "reflect" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "google.golang.org/api/googleapi" +) + +func resourceApigeeSharedFlow() *schema.Resource { + return &schema.Resource{ + Create: resourceApigeeSharedFlowCreate, + Read: resourceApigeeSharedFlowRead, + Delete: resourceApigeeSharedFlowDelete, + + Importer: &schema.ResourceImporter{ + State: resourceApigeeSharedFlowImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The ID of the shared flow.`, + }, + "org_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The Apigee Organization associated with the Apigee instance, +in the format 'organizations/{{org_name}}'.`, + }, + "latest_revision_id": { + Type: schema.TypeString, + Computed: true, + Description: `The id of the most recently created revision for this shared flow.`, + }, + "meta_data": { + Type: schema.TypeList, + Computed: true, + Description: `Metadata describing the shared flow.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "created_at": { + Type: schema.TypeString, + Optional: true, + Description: `Time at which the API proxy was created, in milliseconds since epoch.`, + }, + "last_modified_at": { + Type: schema.TypeString, + Optional: true, + Description: `Time at which the API proxy was most recently modified, in milliseconds since epoch.`, + }, + "sub_type": { + Type: schema.TypeString, + Optional: true, + Description: `The type of entity described`, + }, + }, + }, + }, + "revision": { + Type: schema.TypeList, + Computed: true, + Description: `A list of revisions of this shared flow.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "config_bundle": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `A path to the config bundle zip you want to upload. Must be defined if content is not.`, + }, + }, + UseJSONNumber: true, + } +} + +func resourceApigeeSharedFlowCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + var file *os.File + if configBundlePath, ok := d.GetOk("config_bundle"); ok { + var err error + file, err = os.Open(configBundlePath.(string)) + if err != nil { + return err + } + } else { + return fmt.Errorf("Error, \"config_bundle\" must be specified") + } + + obj := make(map[string]interface{}) + nameProp, err := expandApigeeSharedFlowName(d.Get("name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) { + obj["name"] = nameProp + } + + url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows?name={{name}}&action=import") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new SharedFlow: %#v", obj) + billingProject := "" + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestRawBodyWithTimeout(config, "POST", billingProject, url, userAgent, file, d.Timeout(schema.TimeoutCreate)) + // res, err := sendRequestWithTimeout(config, "POST", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutCreate)) + _ = obj + if err != nil { + return fmt.Errorf("Error creating SharedFlow: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "organizations/{{org_id}}/sharedflows/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + // Use the resource in the operation response to populate + // identity fields and d.Id() before read + var opRes map[string]interface{} + err = apigeeOperationWaitTimeWithResponse( + config, res, &opRes, "Creating SharedFlow", userAgent, + d.Timeout(schema.TimeoutCreate)) + if err != nil { + // The resource didn't actually create + d.SetId("") + + return fmt.Errorf("Error waiting to create SharedFlow: %s", err) + } + + if err := d.Set("name", flattenApigeeSharedFlowName(opRes["name"], d, config)); err != nil { + return err + } + + // This may have caused the ID to update - update it if so. + id, err = replaceVars(d, config, "organizations/{{org_id}}/sharedflows/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating SharedFlow %q: %#v", d.Id(), res) + + return resourceApigeeSharedFlowRead(d, meta) +} + +func resourceApigeeSharedFlowRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequest(config, "GET", billingProject, url, userAgent, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("ApigeeSharedFlow %q", d.Id())) + } + + if err := d.Set("meta_data", flattenApigeeSharedFlowMetaData(res["metaData"], d, config)); err != nil { + return fmt.Errorf("Error reading SharedFlow: %s", err) + } + if err := d.Set("name", flattenApigeeSharedFlowName(res["name"], d, config)); err != nil { + return fmt.Errorf("Error reading SharedFlow: %s", err) + } + if err := d.Set("revision", flattenApigeeSharedFlowRevision(res["revision"], d, config)); err != nil { + return fmt.Errorf("Error reading SharedFlow: %s", err) + } + if err := d.Set("latest_revision_id", flattenApigeeSharedFlowLatestRevisionId(res["latestRevisionId"], d, config)); err != nil { + return fmt.Errorf("Error reading SharedFlow: %s", err) + } + + return nil +} + +func resourceApigeeSharedFlowDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + billingProject := "" + + url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows/{{name}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting SharedFlow %q", d.Id()) + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "SharedFlow") + } + + err = apigeeOperationWaitTime( + config, res, "Deleting SharedFlow", userAgent, + d.Timeout(schema.TimeoutDelete)) + + if err != nil { + return err + } + + log.Printf("[DEBUG] Finished deleting SharedFlow %q: %#v", d.Id(), res) + return nil +} + +func resourceApigeeSharedFlowImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{ + "organizations/(?P[^/]+)/sharedflows/(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "organizations/{{org_id}}/sharedflows/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenApigeeSharedFlowMetaData(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["created_at"] = + flattenApigeeSharedFlowMetaDataCreatedAt(original["createdAt"], d, config) + transformed["last_modified_at"] = + flattenApigeeSharedFlowMetaDataLastModifiedAt(original["lastModifiedAt"], d, config) + transformed["sub_type"] = + flattenApigeeSharedFlowMetaDataSubType(original["subType"], d, config) + return []interface{}{transformed} +} +func flattenApigeeSharedFlowMetaDataCreatedAt(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenApigeeSharedFlowMetaDataLastModifiedAt(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenApigeeSharedFlowMetaDataSubType(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenApigeeSharedFlowName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenApigeeSharedFlowRevision(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenApigeeSharedFlowLatestRevisionId(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func expandApigeeSharedFlowName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +//sendRequestRawBodyWithTimeout is derived from sendRequestWithTimeout with direct pass throught of request body +func sendRequestRawBodyWithTimeout(config *Config, method, project, rawurl, userAgent string, body io.Reader, timeout time.Duration, errorRetryPredicates ...RetryErrorPredicateFunc) (map[string]interface{}, error) { + reqHeaders := make(http.Header) + reqHeaders.Set("User-Agent", userAgent) + reqHeaders.Set("Content-Type", "application/json") + + if config.UserProjectOverride && project != "" { + // Pass the project into this fn instead of parsing it from the URL because + // both project names and URLs can have colons in them. + reqHeaders.Set("X-Goog-User-Project", project) + } + + if timeout == 0 { + timeout = time.Duration(1) * time.Minute + } + + var res *http.Response + err := retryTimeDuration( + func() error { + req, err := http.NewRequest(method, rawurl, body) + if err != nil { + return err + } + + req.Header = reqHeaders + res, err = config.client.Do(req) + if err != nil { + return err + } + + if err := googleapi.CheckResponse(res); err != nil { + googleapi.CloseBody(res) + return err + } + + return nil + }, + timeout, + errorRetryPredicates..., + ) + if err != nil { + return nil, err + } + + if res == nil { + return nil, fmt.Errorf("Unable to parse server response. This is most likely a terraform problem, please file a bug at https://github.com/hashicorp/terraform-provider-google/issues.") + } + + // The defer call must be made outside of the retryFunc otherwise it's closed too soon. + defer googleapi.CloseBody(res) + + // 204 responses will have no body, so we're going to error with "EOF" if we + // try to parse it. Instead, we can just return nil. + if res.StatusCode == 204 { + return nil, nil + } + result := make(map[string]interface{}) + if err := json.NewDecoder(res.Body).Decode(&result); err != nil { + return nil, err + } + + return result, nil +} From 730431f958402c88539b0847b926f8fcef92a64c Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Fri, 16 Dec 2022 22:03:48 +0000 Subject: [PATCH 04/41] remove sharedflow mmv1 and add sharedflow manual provider --- mmv1/products/apigee/api.yaml | 150 ++++++++++++++-------------- mmv1/products/apigee/terraform.yaml | 4 +- 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/mmv1/products/apigee/api.yaml b/mmv1/products/apigee/api.yaml index c088fbaa6a71..86a0bc029f7d 100644 --- a/mmv1/products/apigee/api.yaml +++ b/mmv1/products/apigee/api.yaml @@ -660,78 +660,78 @@ objects: 'Provisioning NAT IPs': 'https://cloud.google.com/apigee/docs/api-platform/security/nat-provisioning' api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances.natAddresses' - - !ruby/object:Api::Resource - name: 'SharedFlow' - base_url: 'organizations/{{org_id}}/sharedflows/{{name}}' - create_url: 'organizations/{{org_id}}/sharedflows?name={{name}}&action=import' - delete_url: 'organizations/{{org_id}}/sharedflows/{{name}}' - self_link: 'organizations/{{org_id}}/sharedflows/{{name}}' - async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: True - allowed: - - True - - False - error: !ruby/object:Api::OpAsync::Error - path: 'error' - message: 'message' - input: true - description: | - You can combine policies and resources into a shared flow that you can consume from multiple API proxies, and even from other shared flows. Although it's like a proxy, a shared flow has no endpoint. It can be used only from an API proxy or shared flow that's in the same organization as the shared flow itself. - parameters: - - !ruby/object:Api::Type::String - name: 'orgId' - description: | - The Apigee Organization associated with the Apigee instance, - in the format `organizations/{{org_name}}`. - required: true - input: true - url_param_only: true - properties: - - !ruby/object:Api::Type::NestedObject - name: 'metaData' - description: | - Metadata describing the shared flow. - output: true - properties: - - !ruby/object:Api::Type::String - name: 'createdAt' - description: | - Time at which the API proxy was created, in milliseconds since epoch. - - !ruby/object:Api::Type::String - name: 'lastModifiedAt' - description: | - Time at which the API proxy was most recently modified, in milliseconds since epoch. - - !ruby/object:Api::Type::String - name: 'subType' - description: | - The type of entity described - - !ruby/object:Api::Type::String - name: 'name' - description: | - The ID of the shared flow. - required: true - - !ruby/object:Api::Type::Array - name: 'revision' - description: | - A list of revisions of this shared flow. - output: true - item_type: Api::Type::String - - !ruby/object:Api::Type::String - name: 'latestRevisionId' - description: | - The id of the most recently created revision for this shared flow. - output: true - references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Sharedflows': - 'https://cloud.google.com/apigee/docs/resources' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.sharedflows' \ No newline at end of file + # - !ruby/object:Api::Resource + # name: 'SharedFlow' + # base_url: 'organizations/{{org_id}}/sharedflows/{{name}}' + # create_url: 'organizations/{{org_id}}/sharedflows?name={{name}}&action=import' + # delete_url: 'organizations/{{org_id}}/sharedflows/{{name}}' + # self_link: 'organizations/{{org_id}}/sharedflows/{{name}}' + # async: !ruby/object:Api::OpAsync + # operation: !ruby/object:Api::OpAsync::Operation + # path: 'name' + # base_url: '{{op_id}}' + # wait_ms: 1000 + # result: !ruby/object:Api::OpAsync::Result + # path: 'response' + # resource_inside_response: true + # status: !ruby/object:Api::OpAsync::Status + # path: 'done' + # complete: True + # allowed: + # - True + # - False + # error: !ruby/object:Api::OpAsync::Error + # path: 'error' + # message: 'message' + # input: true + # description: | + # You can combine policies and resources into a shared flow that you can consume from multiple API proxies, and even from other shared flows. Although it's like a proxy, a shared flow has no endpoint. It can be used only from an API proxy or shared flow that's in the same organization as the shared flow itself. + # parameters: + # - !ruby/object:Api::Type::String + # name: 'orgId' + # description: | + # The Apigee Organization associated with the Apigee instance, + # in the format `organizations/{{org_name}}`. + # required: true + # input: true + # url_param_only: true + # properties: + # - !ruby/object:Api::Type::NestedObject + # name: 'metaData' + # description: | + # Metadata describing the shared flow. + # output: true + # properties: + # - !ruby/object:Api::Type::String + # name: 'createdAt' + # description: | + # Time at which the API proxy was created, in milliseconds since epoch. + # - !ruby/object:Api::Type::String + # name: 'lastModifiedAt' + # description: | + # Time at which the API proxy was most recently modified, in milliseconds since epoch. + # - !ruby/object:Api::Type::String + # name: 'subType' + # description: | + # The type of entity described + # - !ruby/object:Api::Type::String + # name: 'name' + # description: | + # The ID of the shared flow. + # required: true + # - !ruby/object:Api::Type::Array + # name: 'revision' + # description: | + # A list of revisions of this shared flow. + # output: true + # item_type: Api::Type::String + # - !ruby/object:Api::Type::String + # name: 'latestRevisionId' + # description: | + # The id of the most recently created revision for this shared flow. + # output: true + # references: !ruby/object:Api::Resource::ReferenceLinks + # guides: + # 'Sharedflows': + # 'https://cloud.google.com/apigee/docs/resources' + # api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.sharedflows' \ No newline at end of file diff --git a/mmv1/products/apigee/terraform.yaml b/mmv1/products/apigee/terraform.yaml index 012b41674bd0..34c54c691d63 100644 --- a/mmv1/products/apigee/terraform.yaml +++ b/mmv1/products/apigee/terraform.yaml @@ -327,8 +327,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides delete_minutes: 30 custom_code: !ruby/object:Provider::Terraform::CustomCode custom_import: templates/terraform/custom_import/apigee_nat_address.go.erb - SharedFlow: !ruby/object:Overrides::Terraform::ResourceOverride - autogen_async: true + # SharedFlow: !ruby/object:Overrides::Terraform::ResourceOverride + # autogen_async: true # import_format: ["{{org_id}}/sharedflows/{{name}}", "{{org_id}}/{{name}}"] files: !ruby/object:Provider::Config::Files # These files have templating (ERB) code that will be run. From e0576c6c578173952268d29f13fa8ee51c2cdb76 Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Tue, 31 Jan 2023 08:12:11 +0000 Subject: [PATCH 05/41] adding files for debugging review, test have issue --- mmv1/products/apigee/api.yaml | 20 +-- mmv1/products/apigee/terraform.yaml | 16 +- .../examples/apigee_sharedflow_test.tf.erb | 69 ++++++++ .../resources/resource_apigee_shared_flow.go | 164 +++++++++++------- ...ource_apigee_shared_flow_generated_test.go | 162 +++++++++++++++++ ...esource_apigee_shared_flow_sweeper_test.go | 128 ++++++++++++++ .../terraform/utils/provider.go.erb | 1 + .../apigee/apigee_sharedflow_bundle.zip | Bin 0 -> 1016 bytes 8 files changed, 482 insertions(+), 78 deletions(-) create mode 100644 mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb create mode 100644 mmv1/third_party/terraform/tests/resource_apigee_shared_flow_generated_test.go create mode 100644 mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go create mode 100644 mmv1/third_party/terraform/utils/test-fixtures/apigee/apigee_sharedflow_bundle.zip diff --git a/mmv1/products/apigee/api.yaml b/mmv1/products/apigee/api.yaml index 86a0bc029f7d..6bcc3c454261 100644 --- a/mmv1/products/apigee/api.yaml +++ b/mmv1/products/apigee/api.yaml @@ -660,29 +660,15 @@ objects: 'Provisioning NAT IPs': 'https://cloud.google.com/apigee/docs/api-platform/security/nat-provisioning' api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances.natAddresses' + + + # - !ruby/object:Api::Resource # name: 'SharedFlow' # base_url: 'organizations/{{org_id}}/sharedflows/{{name}}' # create_url: 'organizations/{{org_id}}/sharedflows?name={{name}}&action=import' # delete_url: 'organizations/{{org_id}}/sharedflows/{{name}}' # self_link: 'organizations/{{org_id}}/sharedflows/{{name}}' - # async: !ruby/object:Api::OpAsync - # operation: !ruby/object:Api::OpAsync::Operation - # path: 'name' - # base_url: '{{op_id}}' - # wait_ms: 1000 - # result: !ruby/object:Api::OpAsync::Result - # path: 'response' - # resource_inside_response: true - # status: !ruby/object:Api::OpAsync::Status - # path: 'done' - # complete: True - # allowed: - # - True - # - False - # error: !ruby/object:Api::OpAsync::Error - # path: 'error' - # message: 'message' # input: true # description: | # You can combine policies and resources into a shared flow that you can consume from multiple API proxies, and even from other shared flows. Although it's like a proxy, a shared flow has no endpoint. It can be used only from an API proxy or shared flow that's in the same organization as the shared flow itself. diff --git a/mmv1/products/apigee/terraform.yaml b/mmv1/products/apigee/terraform.yaml index 34c54c691d63..3a68a81da01b 100644 --- a/mmv1/products/apigee/terraform.yaml +++ b/mmv1/products/apigee/terraform.yaml @@ -327,9 +327,19 @@ overrides: !ruby/object:Overrides::ResourceOverrides delete_minutes: 30 custom_code: !ruby/object:Provider::Terraform::CustomCode custom_import: templates/terraform/custom_import/apigee_nat_address.go.erb - # SharedFlow: !ruby/object:Overrides::Terraform::ResourceOverride - # autogen_async: true - # import_format: ["{{org_id}}/sharedflows/{{name}}", "{{org_id}}/{{name}}"] + SharedFlow: !ruby/object:Overrides::Terraform::ResourceOverride + import_format: ["{{org_id}}/sharedflows/{{name}}", "{{org_id}}/{{name}}"] + examples: + - !ruby/object:Provider::Terraform::Examples + name: "apigee_sharedflow_test" + primary_resource_id: "org" + test_env_vars: + org_id: :ORG_ID + billing_account: :BILLING_ACCT + skip_docs: true + # Resource creation race + skip_vcr: true + files: !ruby/object:Provider::Config::Files # These files have templating (ERB) code that will be run. # This is usually to add licensing info, autogeneration notices, etc. diff --git a/mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb b/mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb new file mode 100644 index 000000000000..e2bd92e53c9f --- /dev/null +++ b/mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb @@ -0,0 +1,69 @@ +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "<%= ctx[:test_env_vars]['org_id'] %>" + billing_account = "<%= ctx[:test_env_vars]['billing_account'] %>" +} + +resource "google_project_service" "apigee" { + project = google_project.project.project_id + service = "apigee.googleapis.com" +} + +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" "<%= ctx[:primary_resource_id] %>" { + org_id = google_apigee_organization.apigee_org.id + name = "tf-test%{random_suffix}" + description = "Apigee Environment" + display_name = "environment-1" +} + +resource "google_apigee_sharedflow" "test_apigee_sharedflow" { + name = "test-apigee-sharedflow" + org_id = google_apigee_organization.apigee_org.id + config_bundle = "./test-fixtures/apigee/apigee_sharedflow_bundle.zip" + depends_on = [google_apigee_organization.apigee_org] +} \ No newline at end of file diff --git a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go b/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go index 1a6793361fd3..37ccfc316655 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go @@ -1,4 +1,3 @@ - // ---------------------------------------------------------------------------- // // This file is partially automatically generated by Magic Modules and with manual @@ -9,15 +8,16 @@ package google import ( + "context" "encoding/json" "fmt" "io" "log" "net/http" "os" - "reflect" "time" + "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "google.golang.org/api/googleapi" ) @@ -26,6 +26,7 @@ func resourceApigeeSharedFlow() *schema.Resource { return &schema.Resource{ Create: resourceApigeeSharedFlowCreate, Read: resourceApigeeSharedFlowRead, + Update: resourceApigeeSharedFlowUpdate, Delete: resourceApigeeSharedFlowDelete, Importer: &schema.ResourceImporter{ @@ -64,17 +65,17 @@ in the format 'organizations/{{org_name}}'.`, Schema: map[string]*schema.Schema{ "created_at": { Type: schema.TypeString, - Optional: true, + Computed: true, Description: `Time at which the API proxy was created, in milliseconds since epoch.`, }, "last_modified_at": { Type: schema.TypeString, - Optional: true, + Computed: true, Description: `Time at which the API proxy was most recently modified, in milliseconds since epoch.`, }, "sub_type": { Type: schema.TypeString, - Optional: true, + Computed: true, Description: `The type of entity described`, }, }, @@ -88,19 +89,59 @@ in the format 'organizations/{{org_name}}'.`, Type: schema.TypeString, }, }, - "config_bundle": { Type: schema.TypeString, - Optional: true, - ForceNew: true, + Required: true, Description: `A path to the config bundle zip you want to upload. Must be defined if content is not.`, }, + "md5hash": { + Type: schema.TypeString, + Computed: true, + Description: `Base 64 MD5 hash of the uploaded config bundle.`, + }, + "detect_md5hash": { + Type: schema.TypeString, + Optional: true, + Default: "Different Hash", + Description: `A hash of local config bundle in string, user needs to use a Terraform Hash function of their choice. A change in hash will trigger an update.`, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + localMd5Hash := "" + if config_bundle, ok := d.GetOkExists("config_bundle"); ok { + localMd5Hash = getFileMd5Hash(config_bundle.(string)) + } + if localMd5Hash == "" { + return false + } + + // `old` is the md5 hash we speculated from server responses, + // when apply responded with succeed, hash is set to the hash of uploaded bundle + if old != localMd5Hash { + return false + } + + return true + }, + }, }, UseJSONNumber: true, } } func resourceApigeeSharedFlowCreate(d *schema.ResourceData, meta interface{}) error { + ctx := context.TODO() + tflog.Info(ctx, "resourceApigeeSharedFlowCreate") + log.Printf("[DEBUG] resourceApigeeSharedFlowCreate") + + //print debug info====== + tmpName, _ := d.GetOk("name") + tmpOrgId, _ := d.GetOk("org_id") + tmpBundle, _ := d.GetOk("config_bundle") + + fmt.Printf("[DEBUG] resourceApigeeSharedFlowCreate, name= %s", tmpName) + fmt.Printf("[DEBUG] resourceApigeeSharedFlowCreate, org_id=, %s", tmpOrgId) + fmt.Printf("[DEBUG] resourceApigeeSharedFlowCreate, config_bundle=, %s", tmpBundle) + //debug================= + config := meta.(*Config) userAgent, err := generateUserAgentString(d, config.userAgent) if err != nil { @@ -108,30 +149,22 @@ func resourceApigeeSharedFlowCreate(d *schema.ResourceData, meta interface{}) er } var file *os.File + var localMd5Hash string if configBundlePath, ok := d.GetOk("config_bundle"); ok { var err error file, err = os.Open(configBundlePath.(string)) if err != nil { return err } + localMd5Hash = getFileMd5Hash(configBundlePath.(string)) } else { return fmt.Errorf("Error, \"config_bundle\" must be specified") } - obj := make(map[string]interface{}) - nameProp, err := expandApigeeSharedFlowName(d.Get("name"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) { - obj["name"] = nameProp - } - url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows?name={{name}}&action=import") if err != nil { return err } - - log.Printf("[DEBUG] Creating new SharedFlow: %#v", obj) billingProject := "" // err == nil indicates that the billing_project value was found @@ -139,9 +172,10 @@ func resourceApigeeSharedFlowCreate(d *schema.ResourceData, meta interface{}) er billingProject = bp } - res, err := sendRequestRawBodyWithTimeout(config, "POST", billingProject, url, userAgent, file, d.Timeout(schema.TimeoutCreate)) - // res, err := sendRequestWithTimeout(config, "POST", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutCreate)) - _ = obj + fmt.Printf("[DEBUG] resourceApigeeSharedFlowCreate, url=, %s", url) + res, err := sendRequestRawBodyWithTimeout(config, "POST", billingProject, url, userAgent, file, "application/octet-stream", d.Timeout(schema.TimeoutCreate)) + + log.Printf("[DEBUG] sendRequestRawBodyWithTimeout Done") if err != nil { return fmt.Errorf("Error creating SharedFlow: %s", err) } @@ -152,34 +186,21 @@ func resourceApigeeSharedFlowCreate(d *schema.ResourceData, meta interface{}) er return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) + log.Printf("[DEBUG] create d.SetId done, id = %s", id) - // Use the resource in the operation response to populate - // identity fields and d.Id() before read - var opRes map[string]interface{} - err = apigeeOperationWaitTimeWithResponse( - config, res, &opRes, "Creating SharedFlow", userAgent, - d.Timeout(schema.TimeoutCreate)) - if err != nil { - // The resource didn't actually create - d.SetId("") - - return fmt.Errorf("Error waiting to create SharedFlow: %s", err) - } + log.Printf("[DEBUG] Finished creating SharedFlow %q: %#v", d.Id(), res) - if err := d.Set("name", flattenApigeeSharedFlowName(opRes["name"], d, config)); err != nil { - return err + if resourceApigeeSharedFlowRead(d, meta) != nil { + return fmt.Errorf("Error reading SharedFlow at end of Create: %s", err) } + d.Set("md5hash", localMd5Hash) + d.Set("detect_md5hash", localMd5Hash) + return nil +} - // This may have caused the ID to update - update it if so. - id, err = replaceVars(d, config, "organizations/{{org_id}}/sharedflows/{{name}}") - if err != nil { - return fmt.Errorf("Error constructing id: %s", err) - } - d.SetId(id) - - log.Printf("[DEBUG] Finished creating SharedFlow %q: %#v", d.Id(), res) - - return resourceApigeeSharedFlowRead(d, meta) +func resourceApigeeSharedFlowUpdate(d *schema.ResourceData, meta interface{}) error { + //For how sharedflow api is implemented, just treat an update as create, when the name is same, it will create a new revision + return resourceApigeeSharedFlowCreate(d, meta) } func resourceApigeeSharedFlowRead(d *schema.ResourceData, meta interface{}) error { @@ -193,6 +214,7 @@ func resourceApigeeSharedFlowRead(d *schema.ResourceData, meta interface{}) erro if err != nil { return err } + log.Printf("[DEBUG] sharedflow read url is: %s", url) billingProject := "" @@ -200,15 +222,18 @@ func resourceApigeeSharedFlowRead(d *schema.ResourceData, meta interface{}) erro if bp, err := getBillingProject(d, config); err == nil { billingProject = bp } - + log.Printf("[DEBUG] resourceApigeeSharedFlowRead sendRequest") + fmt.Printf("[DEBUG] resourceApigeeSharedFlowRead, url=, %s", url) res, err := sendRequest(config, "GET", billingProject, url, userAgent, nil) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("ApigeeSharedFlow %q", d.Id())) } - + log.Printf("[DEBUG] resourceApigeeSharedFlowRead sendRequest completed") + previousLastModifiedAt := getApigeeSharedFlowLastModifiedAt(d) if err := d.Set("meta_data", flattenApigeeSharedFlowMetaData(res["metaData"], d, config)); err != nil { return fmt.Errorf("Error reading SharedFlow: %s", err) } + currentLastModifiedAt := getApigeeSharedFlowLastModifiedAt(d) if err := d.Set("name", flattenApigeeSharedFlowName(res["name"], d, config)); err != nil { return fmt.Errorf("Error reading SharedFlow: %s", err) } @@ -219,10 +244,35 @@ func resourceApigeeSharedFlowRead(d *schema.ResourceData, meta interface{}) erro return fmt.Errorf("Error reading SharedFlow: %s", err) } + //setting hash to suggest update + if previousLastModifiedAt != currentLastModifiedAt { + log.Printf("yoyo LastModifiedAt previous: %s, current: %s", previousLastModifiedAt, currentLastModifiedAt) + d.Set("md5hash", "UNKNOWN") + d.Set("detect_md5hash", "UNKNOWN") + } return nil } +func getApigeeSharedFlowLastModifiedAt(d *schema.ResourceData) string { + + metaDataRaw := d.Get("meta_data").([]interface{}) + if len(metaDataRaw) != 1 { + //in Terraform Schema, a nest in object is implemented as an array of length one, even if it's technically an object + return "UNKNOWN" + } + metaData := metaDataRaw[0].(map[string]interface{}) + if metaData == nil { + return "UNKNOWN" + } + lastModifiedAt := metaData["last_modified_at"].(string) + if lastModifiedAt == "" { + return "UNKNOWN" + } + return lastModifiedAt +} + func resourceApigeeSharedFlowDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[DEBUG] resourceApigeeSharedFlowDelete") config := meta.(*Config) userAgent, err := generateUserAgentString(d, config.userAgent) if err != nil { @@ -249,14 +299,6 @@ func resourceApigeeSharedFlowDelete(d *schema.ResourceData, meta interface{}) er return handleNotFoundError(err, d, "SharedFlow") } - err = apigeeOperationWaitTime( - config, res, "Deleting SharedFlow", userAgent, - d.Timeout(schema.TimeoutDelete)) - - if err != nil { - return err - } - log.Printf("[DEBUG] Finished deleting SharedFlow %q: %#v", d.Id(), res) return nil } @@ -272,10 +314,12 @@ func resourceApigeeSharedFlowImport(d *schema.ResourceData, meta interface{}) ([ // Replace import id for the resource id id, err := replaceVars(d, config, "organizations/{{org_id}}/sharedflows/{{name}}") + if err != nil { return nil, fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) + fmt.Printf("[DEBUG] resourceApigeeSharedFlowImport, id= %s", id) return []*schema.ResourceData{d}, nil } @@ -326,10 +370,11 @@ func expandApigeeSharedFlowName(v interface{}, d TerraformResourceData, config * } //sendRequestRawBodyWithTimeout is derived from sendRequestWithTimeout with direct pass throught of request body -func sendRequestRawBodyWithTimeout(config *Config, method, project, rawurl, userAgent string, body io.Reader, timeout time.Duration, errorRetryPredicates ...RetryErrorPredicateFunc) (map[string]interface{}, error) { +func sendRequestRawBodyWithTimeout(config *Config, method, project, rawurl, userAgent string, body io.Reader, contentType string, timeout time.Duration, errorRetryPredicates ...RetryErrorPredicateFunc) (map[string]interface{}, error) { + log.Printf("[DEBUG] sendRequestRawBodyWithTimeout start") reqHeaders := make(http.Header) reqHeaders.Set("User-Agent", userAgent) - reqHeaders.Set("Content-Type", "application/json") + reqHeaders.Set("Content-Type", contentType) if config.UserProjectOverride && project != "" { // Pass the project into this fn instead of parsing it from the URL because @@ -342,6 +387,9 @@ func sendRequestRawBodyWithTimeout(config *Config, method, project, rawurl, user } var res *http.Response + + log.Printf("[DEBUG] sendRequestRawBodyWithTimeout sending request") + err := retryTimeDuration( func() error { req, err := http.NewRequest(method, rawurl, body) @@ -385,6 +433,6 @@ func sendRequestRawBodyWithTimeout(config *Config, method, project, rawurl, user if err := json.NewDecoder(res.Body).Decode(&result); err != nil { return nil, err } - + log.Printf("[DEBUG] sendRequestRawBodyWithTimeout returning") return result, nil } diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_generated_test.go b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_generated_test.go new file mode 100644 index 000000000000..52c76b4a8582 --- /dev/null +++ b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_generated_test.go @@ -0,0 +1,162 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccApigeeSharedFlow_apigeeSharedflowTestExample(t *testing.T) { + skipIfVcr(t) + t.Parallel() + + fmt.Printf("from t: org_id %s", getTestOrgFromEnv(t)) + + context := map[string]interface{}{ + "org_id": getTestOrgFromEnv(t), + "billing_account": getTestBillingAccountFromEnv(t), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckApigeeSharedFlowDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccApigeeSharedFlow_apigeeSharedflowTestExample(context), + }, + { + ResourceName: "google_apigee_shared_flow.test_apigee_sharedflow", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"org_id"}, + }, + }, + }) +} + +func testAccApigeeSharedFlow_apigeeSharedflowTestExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_account}" +} + +resource "google_project_service" "apigee" { + project = google_project.project.project_id + service = "apigee.googleapis.com" +} + +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" "org" { + org_id = google_apigee_organization.apigee_org.id + name = "tf-test%{random_suffix}" + description = "Apigee Environment" + display_name = "environment-1" +} + +resource "google_apigee_shared_flow" "test_apigee_sharedflow" { + name = "test-apigee-sharedflow" + org_id = google_project.project.project_id + config_bundle = "./test-fixtures/apigee/apigee_sharedflow_bundle.zip" + depends_on = [google_apigee_organization.apigee_org] +} +`, context) +} + +func testAccCheckApigeeSharedFlowDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_apigee_shared_flow" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := googleProviderConfig(t) + + // url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows/{{name}}") + url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows/test-apigee-sharedflow") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + fmt.Printf("testAccCheckApigeeSharedFlowDestroyProducer, url %s", url) + _, err = sendRequest(config, "GET", billingProject, url, config.userAgent, nil) + if err == nil { + return fmt.Errorf("ApigeeSharedFlow still exists at %s", url) + } + } + + return nil + } +} diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go new file mode 100644 index 000000000000..f95d8af7df0c --- /dev/null +++ b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go @@ -0,0 +1,128 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "context" + "log" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func init() { + resource.AddTestSweepers("ApigeeSharedFlow", &resource.Sweeper{ + Name: "ApigeeSharedFlow", + F: testSweepApigeeSharedFlow, + }) +} + +// At the time of writing, the CI only passes us-central1 as the region +func testSweepApigeeSharedFlow(region string) error { + resourceName := "ApigeeSharedFlow" + log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) + + config, err := sharedConfigForRegion(region) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) + return err + } + + err = config.LoadAndValidate(context.Background()) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) + return err + } + + t := &testing.T{} + billingId := getTestBillingAccountFromEnv(t) + + // Setup variables to replace in list template + d := &ResourceDataMock{ + FieldsInSchema: map[string]interface{}{ + "project": config.Project, + "region": region, + "location": region, + "zone": "-", + "billing_account": billingId, + }, + } + + listTemplate := strings.Split("https://apigee.googleapis.com/v1/organizations/{{org_id}}/sharedflows/{{name}}", "?")[0] + listUrl, err := replaceVars(d, config, listTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err) + return nil + } + + res, err := sendRequest(config, "GET", config.Project, listUrl, config.userAgent, nil) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) + return nil + } + + resourceList, ok := res["sharedFlows"] + if !ok { + log.Printf("[INFO][SWEEPER_LOG] Nothing found in response.") + return nil + } + + rl := resourceList.([]interface{}) + + log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName) + // Keep count of items that aren't sweepable for logging. + nonPrefixCount := 0 + for _, ri := range rl { + obj := ri.(map[string]interface{}) + var name string + // Id detected in the delete URL, attempt to use id. + if obj["id"] != nil { + name = GetResourceNameFromSelfLink(obj["id"].(string)) + } else if obj["name"] != nil { + name = GetResourceNameFromSelfLink(obj["name"].(string)) + } else { + log.Printf("[INFO][SWEEPER_LOG] %s resource name and id were nil", resourceName) + return nil + } + // Skip resources that shouldn't be sweeped + if !isSweepableTestResource(name) { + nonPrefixCount++ + continue + } + + deleteTemplate := "https://apigee.googleapis.com/v1/organizations/{{org_id}}/sharedflows/{{name}}" + deleteUrl, err := replaceVars(d, config, deleteTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err) + return nil + } + deleteUrl = deleteUrl + name + + // Don't wait on operations as we may have a lot to delete + _, err = sendRequest(config, "DELETE", config.Project, deleteUrl, config.userAgent, nil) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) + } else { + log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name) + } + } + + if nonPrefixCount > 0 { + log.Printf("[INFO][SWEEPER_LOG] %d items were non-sweepable and skipped.", nonPrefixCount) + } + + return nil +} diff --git a/mmv1/third_party/terraform/utils/provider.go.erb b/mmv1/third_party/terraform/utils/provider.go.erb index feb90fbb8b5d..ff6290a690d7 100644 --- a/mmv1/third_party/terraform/utils/provider.go.erb +++ b/mmv1/third_party/terraform/utils/provider.go.erb @@ -472,6 +472,7 @@ end # products.each do "google_storage_default_object_acl": resourceStorageDefaultObjectAcl(), "google_storage_notification": resourceStorageNotification(), "google_storage_transfer_job": resourceStorageTransferJob(), + "google_apigee_sharedflow": resourceApigeeSharedFlow(), // ####### END handwritten resources ########### }, map[string]*schema.Resource{ diff --git a/mmv1/third_party/terraform/utils/test-fixtures/apigee/apigee_sharedflow_bundle.zip b/mmv1/third_party/terraform/utils/test-fixtures/apigee/apigee_sharedflow_bundle.zip new file mode 100644 index 0000000000000000000000000000000000000000..52f1c94091bbce546f48e15e9f0c10e692bb8843 GIT binary patch literal 1016 zcmb_b%}&BV5MB^H^rXS7rr8+dr4*0=CZ)umaKWD@g7<}Pu}LXScR{)O1jYyP5qtD$i3#>%t;0sL$+~+rhO;70c8e&rI8$bntM{Q`%T& zoVX@&W-jgEC1tp)OWJ+FrUz^;0yeTw7j~2c%PyHh?AnP~mtCx?uGgBadh4v-uAbH#O-+qAM51fL_zh6C?7Y~_t^mZOnK(G*(M@WR zxx+OzjtbZ%z5|rT=A*&Vqk0^tsVkq9gol;UrL<5fo(_%yw2=~u}RDi=4TN(f=}w|4}x1WyAfyaN`YZ+*NAA^-pY literal 0 HcmV?d00001 From 4c58df852b32f447f6c202432de334046ac20ab4 Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Tue, 31 Jan 2023 08:16:43 +0000 Subject: [PATCH 06/41] adding files for debugging review, test have issue --- mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb | 2 +- mmv1/third_party/terraform/utils/provider.go.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb b/mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb index e2bd92e53c9f..8c27d7947bcd 100644 --- a/mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb +++ b/mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb @@ -61,7 +61,7 @@ resource "google_apigee_environment" "<%= ctx[:primary_resource_id] %>" { display_name = "environment-1" } -resource "google_apigee_sharedflow" "test_apigee_sharedflow" { +resource "google_apigee_shared_flow" "test_apigee_sharedflow" { name = "test-apigee-sharedflow" org_id = google_apigee_organization.apigee_org.id config_bundle = "./test-fixtures/apigee/apigee_sharedflow_bundle.zip" diff --git a/mmv1/third_party/terraform/utils/provider.go.erb b/mmv1/third_party/terraform/utils/provider.go.erb index ff6290a690d7..73ffc369a0f6 100644 --- a/mmv1/third_party/terraform/utils/provider.go.erb +++ b/mmv1/third_party/terraform/utils/provider.go.erb @@ -472,7 +472,7 @@ end # products.each do "google_storage_default_object_acl": resourceStorageDefaultObjectAcl(), "google_storage_notification": resourceStorageNotification(), "google_storage_transfer_job": resourceStorageTransferJob(), - "google_apigee_sharedflow": resourceApigeeSharedFlow(), + "google_apigee_shared_flow": resourceApigeeSharedFlow(), // ####### END handwritten resources ########### }, map[string]*schema.Resource{ From 1217528b22141c75838047df14c8aaa66dc7e3d7 Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Wed, 1 Feb 2023 23:41:16 +0000 Subject: [PATCH 07/41] update test, doc, provider for apigee --- mmv1/products/apigee/api.yaml | 63 +---------- mmv1/products/apigee/terraform.yaml | 13 --- .../examples/apigee_sharedflow_test.tf.erb | 69 ------------ .../resources/resource_apigee_shared_flow.go | 1 + ...ource_apigee_shared_flow_generated_test.go | 100 +++++++++++++++--- ...esource_apigee_shared_flow_sweeper_test.go | 14 --- .../apigee/apigee_sharedflow_bundle2.zip | Bin 0 -> 2645 bytes .../docs/r/apigee_shared_flow.html.markdown | 88 +++++++++++++++ 8 files changed, 175 insertions(+), 173 deletions(-) delete mode 100644 mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb create mode 100644 mmv1/third_party/terraform/utils/test-fixtures/apigee/apigee_sharedflow_bundle2.zip create mode 100644 mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown diff --git a/mmv1/products/apigee/api.yaml b/mmv1/products/apigee/api.yaml index 6bcc3c454261..0d912477dce4 100644 --- a/mmv1/products/apigee/api.yaml +++ b/mmv1/products/apigee/api.yaml @@ -659,65 +659,4 @@ objects: guides: 'Provisioning NAT IPs': 'https://cloud.google.com/apigee/docs/api-platform/security/nat-provisioning' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances.natAddresses' - - - - # - !ruby/object:Api::Resource - # name: 'SharedFlow' - # base_url: 'organizations/{{org_id}}/sharedflows/{{name}}' - # create_url: 'organizations/{{org_id}}/sharedflows?name={{name}}&action=import' - # delete_url: 'organizations/{{org_id}}/sharedflows/{{name}}' - # self_link: 'organizations/{{org_id}}/sharedflows/{{name}}' - # input: true - # description: | - # You can combine policies and resources into a shared flow that you can consume from multiple API proxies, and even from other shared flows. Although it's like a proxy, a shared flow has no endpoint. It can be used only from an API proxy or shared flow that's in the same organization as the shared flow itself. - # parameters: - # - !ruby/object:Api::Type::String - # name: 'orgId' - # description: | - # The Apigee Organization associated with the Apigee instance, - # in the format `organizations/{{org_name}}`. - # required: true - # input: true - # url_param_only: true - # properties: - # - !ruby/object:Api::Type::NestedObject - # name: 'metaData' - # description: | - # Metadata describing the shared flow. - # output: true - # properties: - # - !ruby/object:Api::Type::String - # name: 'createdAt' - # description: | - # Time at which the API proxy was created, in milliseconds since epoch. - # - !ruby/object:Api::Type::String - # name: 'lastModifiedAt' - # description: | - # Time at which the API proxy was most recently modified, in milliseconds since epoch. - # - !ruby/object:Api::Type::String - # name: 'subType' - # description: | - # The type of entity described - # - !ruby/object:Api::Type::String - # name: 'name' - # description: | - # The ID of the shared flow. - # required: true - # - !ruby/object:Api::Type::Array - # name: 'revision' - # description: | - # A list of revisions of this shared flow. - # output: true - # item_type: Api::Type::String - # - !ruby/object:Api::Type::String - # name: 'latestRevisionId' - # description: | - # The id of the most recently created revision for this shared flow. - # output: true - # references: !ruby/object:Api::Resource::ReferenceLinks - # guides: - # 'Sharedflows': - # 'https://cloud.google.com/apigee/docs/resources' - # api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.sharedflows' \ No newline at end of file + api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances.natAddresses' \ No newline at end of file diff --git a/mmv1/products/apigee/terraform.yaml b/mmv1/products/apigee/terraform.yaml index 3a68a81da01b..b9086dd2bc0a 100644 --- a/mmv1/products/apigee/terraform.yaml +++ b/mmv1/products/apigee/terraform.yaml @@ -327,19 +327,6 @@ overrides: !ruby/object:Overrides::ResourceOverrides delete_minutes: 30 custom_code: !ruby/object:Provider::Terraform::CustomCode custom_import: templates/terraform/custom_import/apigee_nat_address.go.erb - SharedFlow: !ruby/object:Overrides::Terraform::ResourceOverride - import_format: ["{{org_id}}/sharedflows/{{name}}", "{{org_id}}/{{name}}"] - examples: - - !ruby/object:Provider::Terraform::Examples - name: "apigee_sharedflow_test" - primary_resource_id: "org" - test_env_vars: - org_id: :ORG_ID - billing_account: :BILLING_ACCT - skip_docs: true - # Resource creation race - skip_vcr: true - files: !ruby/object:Provider::Config::Files # These files have templating (ERB) code that will be run. # This is usually to add licensing info, autogeneration notices, etc. diff --git a/mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb b/mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb deleted file mode 100644 index 8c27d7947bcd..000000000000 --- a/mmv1/templates/terraform/examples/apigee_sharedflow_test.tf.erb +++ /dev/null @@ -1,69 +0,0 @@ -resource "google_project" "project" { - project_id = "tf-test%{random_suffix}" - name = "tf-test%{random_suffix}" - org_id = "<%= ctx[:test_env_vars]['org_id'] %>" - billing_account = "<%= ctx[:test_env_vars]['billing_account'] %>" -} - -resource "google_project_service" "apigee" { - project = google_project.project.project_id - service = "apigee.googleapis.com" -} - -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" "<%= ctx[:primary_resource_id] %>" { - org_id = google_apigee_organization.apigee_org.id - name = "tf-test%{random_suffix}" - description = "Apigee Environment" - display_name = "environment-1" -} - -resource "google_apigee_shared_flow" "test_apigee_sharedflow" { - name = "test-apigee-sharedflow" - org_id = google_apigee_organization.apigee_org.id - config_bundle = "./test-fixtures/apigee/apigee_sharedflow_bundle.zip" - depends_on = [google_apigee_organization.apigee_org] -} \ No newline at end of file diff --git a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go b/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go index 37ccfc316655..8fc9f6e1da75 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go @@ -35,6 +35,7 @@ func resourceApigeeSharedFlow() *schema.Resource { Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(20 * time.Minute), + Update: schema.DefaultTimeout(20 * time.Minute), Delete: schema.DefaultTimeout(20 * time.Minute), }, diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_generated_test.go b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_generated_test.go index 52c76b4a8582..97bbe3d8c823 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_generated_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_generated_test.go @@ -1,17 +1,3 @@ -// ---------------------------------------------------------------------------- -// -// *** AUTO GENERATED CODE *** Type: MMv1 *** -// -// ---------------------------------------------------------------------------- -// -// This file is automatically generated by Magic Modules and manual -// changes will be clobbered when the file is regenerated. -// -// Please read more about how to change this file in -// .github/CONTRIBUTING.md. -// -// ---------------------------------------------------------------------------- - package google import ( @@ -47,7 +33,16 @@ func TestAccApigeeSharedFlow_apigeeSharedflowTestExample(t *testing.T) { ResourceName: "google_apigee_shared_flow.test_apigee_sharedflow", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"org_id"}, + ImportStateVerifyIgnore: []string{"config_bundle", "detect_md5hash", "md5hash"}, + }, + { + Config: testAccApigeeSharedFlow_apigeeSharedflowTestExampleUpdate(context), + }, + { + ResourceName: "google_apigee_shared_flow.test_apigee_sharedflow", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"config_bundle", "detect_md5hash", "md5hash"}, }, }, }) @@ -160,3 +155,78 @@ func testAccCheckApigeeSharedFlowDestroyProducer(t *testing.T) func(s *terraform return nil } } + + +func testAccApigeeSharedFlow_apigeeSharedflowTestExampleUpdate(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_account}" +} + +resource "google_project_service" "apigee" { + project = google_project.project.project_id + service = "apigee.googleapis.com" +} + +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" "org" { + org_id = google_apigee_organization.apigee_org.id + name = "tf-test%{random_suffix}" + description = "Apigee Environment" + display_name = "environment-1" +} + +resource "google_apigee_shared_flow" "test_apigee_sharedflow" { + name = "test-apigee-sharedflow" + org_id = google_project.project.project_id + config_bundle = "./test-fixtures/apigee/apigee_sharedflow_bundle2.zip" + depends_on = [google_apigee_organization.apigee_org] +} +`, context) +} \ No newline at end of file diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go index f95d8af7df0c..9209c0e077e9 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go @@ -1,17 +1,3 @@ -// ---------------------------------------------------------------------------- -// -// *** AUTO GENERATED CODE *** Type: MMv1 *** -// -// ---------------------------------------------------------------------------- -// -// This file is automatically generated by Magic Modules and manual -// changes will be clobbered when the file is regenerated. -// -// Please read more about how to change this file in -// .github/CONTRIBUTING.md. -// -// ---------------------------------------------------------------------------- - package google import ( diff --git a/mmv1/third_party/terraform/utils/test-fixtures/apigee/apigee_sharedflow_bundle2.zip b/mmv1/third_party/terraform/utils/test-fixtures/apigee/apigee_sharedflow_bundle2.zip new file mode 100644 index 0000000000000000000000000000000000000000..6e15c11140339b09aeff8b62ba4c29eaa24b964d GIT binary patch literal 2645 zcma);3p`Zm8^@3PV6;?I>z-__%eWImVpt@T)RbFm44ILPyFt0%#j-VJqN$k@`Adu# zw-_eZ$t4<>kd`8(6&iBi{$u_7mu|c7`JDHh_dVzNexA?g{GRiBY^->ARR9140# zCjidiUY|Ha4A>3?oObcYxM6WV!LE33HylQd3lQCS`pL`#*ldCnPPeU8aRIHnwM4X?&;g1Jw|Ag$YF`vf#xe1? zgIf-{_Ag$zHES&7|19HbT#K0g+n%7wEdhZ*NG(sdvRZ|mZ~1e(rDEZ@$lB4!r+t!9 z=?hKasab`u&0VV)7t1v7$Szf$CL(To>=Rkp^H*d-`5p6d#)}RjltdqhQpdqnZE*+{ z{mvb6G^P$UG)3Qvd|4`{D`z^cF`N-|t(?kcL#BtD>MU0y7a>8ERLzm{xfS7sDGZ)b~YRW?-MFC14 z(PD}&=%p`Tyrq?aw1nl`7DKkeCv_YfT_4==V$Qn+w^j7H+apa;i(a$FZ{fHhmljI- zD!)2djo;m&5es=z`bIT#PnDB+Mtg_7imiM{sS{!n#a82uk8> zTJZJ3d7SdV1pF&y2?_`%OY;Cg9X|l5e3xeGg2VaX162_lQu~(9QjZV){$ihKM2E9R zJ5m{5Jkacw{7a>mnv$!SVDSCimY+<0)B6gi826|Yf z&S#|=9vv-=wnvr=HIU{)VVxR6$~EH<$eycY9Z>52tR2UN6}qK$y^|7{Jz})#5uyWi z(ay|L`}(6S1!Wsq%M!Gga;R_&ei12^?WRadFlpAhdZ_H?yR3U!MmM28aorV=2B$KM zyG9!APF3w~lQJc9wNtT?(Q;eq)c(r!ySLLtcf_l7BMy^NH5b}FYraKeifh|y zzHY-2(b`nV`H}ZBN2Ej>FM2BKCr|jvp9P;vrj~{ohJpoK1Q!6w{r&-#=lCXX(7B$3 zV=UBvPLuBqX|QEgj~xor_nOGxbj^;c9-{&>EZg2gDh@b53S8%k3s>%zI zo7SGOixIk~)x32r1-i;Fp#}|Kda{O>j4r9VrH%ys#9KVJK@;%=)F$Q$H?rLpsm#zz)i>Rb%OLflQm^f8KDk#Sgm&f=na$nR9L^w(A}&pzu#XHw@MVj|==(9b+!SeV(d==hF8fl5KQ(p=4 zuw>D%(4C9kh%T|9s#MXwJOV9OD7KI(M~mxjAy7|Z6P!n@H6>a@qN`GN-OtJDaOQi2 zHCF5B+>4%RfLyjHsNkX#-FPmWdz^c!m}gb@9}@$7Wls_x${W(AcyNam@nqWMf+mwu z)a7AX;<=un1X0~m-0_7IgSs*Hh_ zNh`U=4ASF2VL~JCyQjq6Kkua|HFnp*$L&d`T!TTE_Tbrc1l2Cwe~qzFTjx2u)5eO6 z^SQTwqv80ZsrdW$qon@VetaIjxz*SR=SYe(%sA&4;hP(e&tdCfAH8aQ^The `meta_data` block contains: + +* `created_at` - + (Optional) + Time at which the API proxy was created, in milliseconds since epoch. + +* `last_modified_at` - + (Optional) + Time at which the API proxy was most recently modified, in milliseconds since epoch. + +* `sub_type` - + (Optional) + The type of entity described + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 20 minutes. +- `update` - Default is 20 minutes. +- `delete` - Default is 20 minutes. + +## Import + + +SharedFlow can be imported using any of these accepted formats: + +``` +$ terraform import google_apigee_shared_flow.default {{org_id}}/sharedflows/{{name}} +``` From 7b9b5692ec0b2e9c69822a68b34caf6ebfa44234 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 8 Feb 2023 12:09:37 -0800 Subject: [PATCH 08/41] Update api.yaml remove empty new line From 97dde6cecc50fe77554d7615e3e4568a243ffce7 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 8 Feb 2023 12:10:14 -0800 Subject: [PATCH 09/41] Update api.yaml From 6d50fc02642ac5c1d04805bbde742e6a85a4dcca Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 8 Feb 2023 12:11:06 -0800 Subject: [PATCH 10/41] Rename resource_apigee_shared_flow_generated_test.go to resource_apigee_shared_flow_test.go --- ...ow_generated_test.go => resource_apigee_shared_flow_test.go} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename mmv1/third_party/terraform/tests/{resource_apigee_shared_flow_generated_test.go => resource_apigee_shared_flow_test.go} (99%) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_generated_test.go b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go similarity index 99% rename from mmv1/third_party/terraform/tests/resource_apigee_shared_flow_generated_test.go rename to mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go index 97bbe3d8c823..23bad8f3ab06 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_generated_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go @@ -229,4 +229,4 @@ resource "google_apigee_shared_flow" "test_apigee_sharedflow" { depends_on = [google_apigee_organization.apigee_org] } `, context) -} \ No newline at end of file +} From 1d526c01c3ce3744949c955801371356775a8d74 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 8 Feb 2023 12:16:01 -0800 Subject: [PATCH 11/41] Update resource_apigee_shared_flow.go update import regex, change debug messages to log.Printf --- .../resources/resource_apigee_shared_flow.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go b/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go index 8fc9f6e1da75..09b14377e1b8 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go @@ -138,9 +138,9 @@ func resourceApigeeSharedFlowCreate(d *schema.ResourceData, meta interface{}) er tmpOrgId, _ := d.GetOk("org_id") tmpBundle, _ := d.GetOk("config_bundle") - fmt.Printf("[DEBUG] resourceApigeeSharedFlowCreate, name= %s", tmpName) - fmt.Printf("[DEBUG] resourceApigeeSharedFlowCreate, org_id=, %s", tmpOrgId) - fmt.Printf("[DEBUG] resourceApigeeSharedFlowCreate, config_bundle=, %s", tmpBundle) + log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, name= %s", tmpName) + log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, org_id=, %s", tmpOrgId) + log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, config_bundle=, %s", tmpBundle) //debug================= config := meta.(*Config) @@ -173,7 +173,7 @@ func resourceApigeeSharedFlowCreate(d *schema.ResourceData, meta interface{}) er billingProject = bp } - fmt.Printf("[DEBUG] resourceApigeeSharedFlowCreate, url=, %s", url) + log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, url=, %s", url) res, err := sendRequestRawBodyWithTimeout(config, "POST", billingProject, url, userAgent, file, "application/octet-stream", d.Timeout(schema.TimeoutCreate)) log.Printf("[DEBUG] sendRequestRawBodyWithTimeout Done") @@ -224,7 +224,7 @@ func resourceApigeeSharedFlowRead(d *schema.ResourceData, meta interface{}) erro billingProject = bp } log.Printf("[DEBUG] resourceApigeeSharedFlowRead sendRequest") - fmt.Printf("[DEBUG] resourceApigeeSharedFlowRead, url=, %s", url) + log.Printf("[DEBUG] resourceApigeeSharedFlowRead, url=, %s", url) res, err := sendRequest(config, "GET", billingProject, url, userAgent, nil) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("ApigeeSharedFlow %q", d.Id())) @@ -307,8 +307,8 @@ func resourceApigeeSharedFlowDelete(d *schema.ResourceData, meta interface{}) er func resourceApigeeSharedFlowImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { config := meta.(*Config) if err := parseImportId([]string{ - "organizations/(?P[^/]+)/sharedflows/(?P[^/]+)/(?P[^/]+)", - "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + "organizations/(?P[^/]+)/sharedflows/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)", }, d, config); err != nil { return nil, err } @@ -320,7 +320,7 @@ func resourceApigeeSharedFlowImport(d *schema.ResourceData, meta interface{}) ([ return nil, fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - fmt.Printf("[DEBUG] resourceApigeeSharedFlowImport, id= %s", id) + log.Printf("[DEBUG] resourceApigeeSharedFlowImport, id= %s", id) return []*schema.ResourceData{d}, nil } From f49215aa9c24a861be910e8756b1158030cf7107 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 10 Feb 2023 10:25:57 -0800 Subject: [PATCH 12/41] Update mmv1/third_party/terraform/utils/provider.go.erb Co-authored-by: megan07 --- mmv1/third_party/terraform/utils/provider.go.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/third_party/terraform/utils/provider.go.erb b/mmv1/third_party/terraform/utils/provider.go.erb index 9e2fe30b1292..df67f596c887 100644 --- a/mmv1/third_party/terraform/utils/provider.go.erb +++ b/mmv1/third_party/terraform/utils/provider.go.erb @@ -450,7 +450,7 @@ end # products.each do "google_storage_default_object_acl": resourceStorageDefaultObjectAcl(), "google_storage_notification": resourceStorageNotification(), "google_storage_transfer_job": resourceStorageTransferJob(), - "google_apigee_shared_flow": resourceApigeeSharedFlow(), + "google_apigee_shared_flow": resourceApigeeSharedFlow(), "google_tags_location_tag_binding": resourceTagsLocationTagBinding(), // ####### END handwritten resources ########### }, From 993f8517fbf459c3e13e7bb42dd15f8fb9ee5c31 Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Wed, 15 Feb 2023 07:56:32 +0000 Subject: [PATCH 13/41] update PR to address comments --- .../resources/resource_apigee_shared_flow.go | 12 ++++-------- .../tests/resource_apigee_shared_flow_test.go | 4 ++-- .../website/docs/r/apigee_shared_flow.html.markdown | 8 +++++++- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go b/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go index 09b14377e1b8..e6c7b3c51f9f 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go @@ -133,14 +133,10 @@ func resourceApigeeSharedFlowCreate(d *schema.ResourceData, meta interface{}) er tflog.Info(ctx, "resourceApigeeSharedFlowCreate") log.Printf("[DEBUG] resourceApigeeSharedFlowCreate") - //print debug info====== - tmpName, _ := d.GetOk("name") - tmpOrgId, _ := d.GetOk("org_id") - tmpBundle, _ := d.GetOk("config_bundle") - - log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, name= %s", tmpName) - log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, org_id=, %s", tmpOrgId) - log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, config_bundle=, %s", tmpBundle) + //print debug info====== + log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, name= %s", d.Get("name").(string)) + log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, org_id=, %s", d.Get("org_id").(string)) + log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, config_bundle=, %s", d.Get("config_bundle").(string)) //debug================= config := meta.(*Config) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go index 23bad8f3ab06..833058740800 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go @@ -114,7 +114,7 @@ resource "google_apigee_environment" "org" { } resource "google_apigee_shared_flow" "test_apigee_sharedflow" { - name = "test-apigee-sharedflow" + name = "tf-test-apigee-sharedflow" org_id = google_project.project.project_id config_bundle = "./test-fixtures/apigee/apigee_sharedflow_bundle.zip" depends_on = [google_apigee_organization.apigee_org] @@ -223,7 +223,7 @@ resource "google_apigee_environment" "org" { } resource "google_apigee_shared_flow" "test_apigee_sharedflow" { - name = "test-apigee-sharedflow" + name = "tf-test-apigee-sharedflow" org_id = google_project.project.project_id config_bundle = "./test-fixtures/apigee/apigee_sharedflow_bundle2.zip" depends_on = [google_apigee_organization.apigee_org] diff --git a/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown b/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown index 53feeae45e84..cc71c10e6dfd 100644 --- a/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown @@ -51,9 +51,15 @@ In addition to the arguments listed above, the following computed attributes are * `revision` - A list of revisions of this shared flow. -* `latest_revision_id` - +* `latest_revision_id` - The id of the most recently created revision for this shared flow. +* `md5hash` - + (Computed) Base 64 MD5 hash of the uploaded data. It is speculative as remote does not return hash of the bundle. Remote changes are detected using returned last_modified timestamp. + +* `detect_md5hash` - + (Optional) Detect changes to local config bundle file or changes made outside of Terraform. MD5 hash of the data, encoded using base64. Hash is automatically computed without need for user input. + The `meta_data` block contains: From 4353e36aa40042758cb5dcf80e0acf5beecc42b3 Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Thu, 16 Feb 2023 04:44:42 +0000 Subject: [PATCH 14/41] update test --- .../terraform/tests/resource_apigee_shared_flow_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go index 833058740800..d44863b94f4b 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go @@ -134,8 +134,7 @@ func testAccCheckApigeeSharedFlowDestroyProducer(t *testing.T) func(s *terraform config := googleProviderConfig(t) - // url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows/{{name}}") - url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows/test-apigee-sharedflow") + url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows/{{name}}") if err != nil { return err } From a2b94534139856ea5120e6a71e1e580c4639e381 Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Tue, 28 Feb 2023 00:33:07 +0000 Subject: [PATCH 15/41] fix sharedflow attribute update issue, add sharedflow deployment --- .../resources/resource_apigee_shared_flow.go | 28 +++ .../resource_apigee_sharedflow_deployment.go | 198 ++++++++++++++++++ ...urce_apigee_shared_flow_deployment_test.go | 154 ++++++++++++++ ...esource_apigee_shared_flow_sweeper_test.go | 14 ++ .../tests/resource_apigee_shared_flow_test.go | 24 +-- .../terraform/utils/provider.go.erb | 3 +- .../docs/r/apigee_shared_flow.html.markdown | 23 +- ...pigee_shared_flow_deployment.html.markdown | 85 ++++++++ 8 files changed, 503 insertions(+), 26 deletions(-) create mode 100644 mmv1/third_party/terraform/resources/resource_apigee_sharedflow_deployment.go create mode 100644 mmv1/third_party/terraform/tests/resource_apigee_shared_flow_deployment_test.go create mode 100644 mmv1/third_party/terraform/website/docs/r/apigee_shared_flow_deployment.html.markdown diff --git a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go b/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go index e6c7b3c51f9f..98016cc11e2d 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go @@ -18,6 +18,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "google.golang.org/api/googleapi" ) @@ -33,6 +34,18 @@ func resourceApigeeSharedFlow() *schema.Resource { State: resourceApigeeSharedFlowImport, }, + CustomizeDiff: customdiff.All( + /* + If any of the config_bundle, detect_md5hash or md5hash is changed, + then an update is expected, so we tell Terraform core to expect update on meta_data, + latest_revision_id and revision + */ + + customdiff.ComputedIf("meta_data", apigeeSharedflowDetectBundleUpdate), + customdiff.ComputedIf("latest_revision_id", apigeeSharedflowDetectBundleUpdate), + customdiff.ComputedIf("revision", apigeeSharedflowDetectBundleUpdate), + ), + Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(20 * time.Minute), Update: schema.DefaultTimeout(20 * time.Minute), @@ -433,3 +446,18 @@ func sendRequestRawBodyWithTimeout(config *Config, method, project, rawurl, user log.Printf("[DEBUG] sendRequestRawBodyWithTimeout returning") return result, nil } + +func apigeeSharedflowDetectBundleUpdate(_ context.Context, diff *schema.ResourceDiff, v interface{}) bool { + tmp, _ := diff.GetChange("detect_md5hash") + oldBundleHash := tmp.(string) + currentBundleHash := "" + if config_bundle, ok := diff.GetOkExists("config_bundle"); ok { + currentBundleHash = getFileMd5Hash(config_bundle.(string)) + } + log.Printf("[DEBUG] apigeeSharedflowDetectUpdate detect_md5hash: %s -> %s", oldBundleHash, currentBundleHash) + + if oldBundleHash != currentBundleHash { + return true + } + return diff.HasChange("config_bundle") || diff.HasChange("md5hash") +} \ No newline at end of file diff --git a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow_deployment.go b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow_deployment.go new file mode 100644 index 000000000000..9018445067fe --- /dev/null +++ b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow_deployment.go @@ -0,0 +1,198 @@ +package google + +import ( + "fmt" + "log" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceApigeeSharedFlowDeployment() *schema.Resource { + return &schema.Resource{ + Create: resourceApigeeSharedflowDeploymentCreate, + Read: resourceApigeeSharedflowDeploymentRead, + Delete: resourceApigeeSharedflowDeploymentDelete, + + Importer: &schema.ResourceImporter{ + State: resourceApigeeSharedflowDeploymentImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + Update: schema.DefaultTimeout(20 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "environment": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The resource ID of the environment.`, + }, + "org_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The Apigee Organization associated with the Apigee instance`, + }, + "revision": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Revision of the Sharedflow to be deployed.`, + }, + "service_account": { + Type: schema.TypeString, + ForceNew: true, + Optional: true, + Description: `The service account represents the identity of the deployed proxy, and determines what permissions it has. The format must be {ACCOUNT_ID}@{PROJECT}.iam.gserviceaccount.com.`, + }, + "sharedflow_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Id of the Sharedflow to be deployed.`, + }, + }, + UseJSONNumber: true, + } +} + +func resourceApigeeSharedflowDeploymentCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/sharedflows/{{sharedflow_id}}/revisions/{{revision}}/deployments?override=true&serviceAccount={{service_account}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new SharedflowDeployment at %s", url) + billingProject := "" + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestWithTimeout(config, "POST", billingProject, url, userAgent, nil, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating SharedflowDeployment: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "organizations/{{org_id}}/environments/{{environment}}/sharedflows/{{sharedflow_id}}/revisions/{{revision}}/deployments") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating SharedflowDeployment %q: %#v", d.Id(), res) + + return resourceApigeeSharedflowDeploymentRead(d, meta) +} + +func resourceApigeeSharedflowDeploymentRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/sharedflows/{{sharedflow_id}}/revisions/{{revision}}/deployments") + if err != nil { + return err + } + + billingProject := "" + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + log.Printf("[DEBUG] Reading SharedflowDeployment at %s", url) + + res, err := sendRequest(config, "GET", billingProject, url, userAgent, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("ApigeeSharedflowDeployment %q", d.Id())) + } + log.Printf("[DEBUG] ApigeeSharedflowDeployment deployStartTime %s", res["deployStartTime"]) + + return nil +} + +func resourceApigeeSharedflowDeploymentDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + billingProject := "" + + url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/sharedflows/{{sharedflow_id}}/revisions/{{revision}}/deployments") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting SharedflowDeployment %q", d.Id()) + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "SharedflowDeployment") + } + + log.Printf("[DEBUG] Finished deleting SharedflowDeployment %q: %#v", d.Id(), res) + return nil +} + +func resourceApigeeSharedflowDeploymentImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{ + "organizations/(?P[^/]+)/environments/(?P[^/]+)/sharedflows/(?P[^/]+)/revisions/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "organizations/{{org_id}}/environments/{{environment}}/sharedflows/{{sharedflow_id}}/revisions/{{revision}}/deployments") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenApigeeSharedflowDeploymentOrgId(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenApigeeSharedflowDeploymentEnvironment(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenApigeeSharedflowDeploymentSharedflowId(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenApigeeSharedflowDeploymentRevision(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenApigeeSharedflowDeploymentServiceAccount(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_deployment_test.go b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_deployment_test.go new file mode 100644 index 000000000000..19f481f16a73 --- /dev/null +++ b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_deployment_test.go @@ -0,0 +1,154 @@ +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccApigeeSharedflowDeployment_apigeeSharedflowDeploymentTestExample(t *testing.T) { + skipIfVcr(t) + t.Parallel() + + fmt.Printf("from t: org_id %s", getTestOrgFromEnv(t)) + + context := map[string]interface{}{ + "org_id": getTestOrgFromEnv(t), + "billing_account": getTestBillingAccountFromEnv(t), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckApigeeSharedflowDeploymentDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccApigeeSharedflowDeployment_apigeeSharedflowDeploymentTestExample(context), + }, + { + ResourceName: "google_apigee_sharedflow_deployment.sharedflow_deployment_test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +func testAccApigeeSharedflowDeployment_apigeeSharedflowDeploymentTestExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_account}" +} + +resource "google_project_service" "apigee" { + project = google_project.project.project_id + service = "apigee.googleapis.com" +} + +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" +} + +resource "google_apigee_sharedflow" "test_apigee_sharedflow" { + name = "tf-test-apigee-sharedflow" + org_id = google_project.project.project_id + config_bundle = "./test-fixtures/apigee/apigee_sharedflow_bundle.zip" + depends_on = [google_apigee_organization.apigee_org] +} + +resource "google_apigee_sharedflow_deployment" "sharedflow_deployment_test" { + environment = google_apigee_environment.apigee_environment.name + org_id = google_apigee_sharedflow.test_apigee_sharedflow.org_id + revision = google_apigee_sharedflow.test_apigee_sharedflow.revision[length(google_apigee_sharedflow.test_apigee_sharedflow.revision)-1] + sharedflow_id = google_apigee_sharedflow.test_apigee_sharedflow.name +} +`, context) +} + +func testAccCheckApigeeSharedflowDeploymentDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_apigee_sharedflow_deployment" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := googleProviderConfig(t) + + url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/sharedflows/{{sharedflow_id}}/revisions/{{revision}}/deployments") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + fmt.Printf("testAccCheckApigeeSharedflowDeploymentDestroyProducer, url %s", url) + _, err = sendRequest(config, "GET", billingProject, url, config.userAgent, nil) + if err == nil { + return fmt.Errorf("ApigeeSharedFlow still exists at %s", url) + } + } + + return nil + } +} diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go index 9209c0e077e9..f95d8af7df0c 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go @@ -1,3 +1,17 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + package google import ( diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go index d44863b94f4b..fb5b123e4bb6 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go @@ -30,7 +30,7 @@ func TestAccApigeeSharedFlow_apigeeSharedflowTestExample(t *testing.T) { Config: testAccApigeeSharedFlow_apigeeSharedflowTestExample(context), }, { - ResourceName: "google_apigee_shared_flow.test_apigee_sharedflow", + ResourceName: "google_apigee_sharedflow.test_apigee_sharedflow", ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"config_bundle", "detect_md5hash", "md5hash"}, @@ -39,7 +39,7 @@ func TestAccApigeeSharedFlow_apigeeSharedflowTestExample(t *testing.T) { Config: testAccApigeeSharedFlow_apigeeSharedflowTestExampleUpdate(context), }, { - ResourceName: "google_apigee_shared_flow.test_apigee_sharedflow", + ResourceName: "google_apigee_sharedflow.test_apigee_sharedflow", ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"config_bundle", "detect_md5hash", "md5hash"}, @@ -106,14 +106,7 @@ resource "google_apigee_organization" "apigee_org" { ] } -resource "google_apigee_environment" "org" { - org_id = google_apigee_organization.apigee_org.id - name = "tf-test%{random_suffix}" - description = "Apigee Environment" - display_name = "environment-1" -} - -resource "google_apigee_shared_flow" "test_apigee_sharedflow" { +resource "google_apigee_sharedflow" "test_apigee_sharedflow" { name = "tf-test-apigee-sharedflow" org_id = google_project.project.project_id config_bundle = "./test-fixtures/apigee/apigee_sharedflow_bundle.zip" @@ -135,6 +128,7 @@ func testAccCheckApigeeSharedFlowDestroyProducer(t *testing.T) func(s *terraform config := googleProviderConfig(t) url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows/{{name}}") + // url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows/test-apigee-sharedflow") if err != nil { return err } @@ -155,7 +149,6 @@ func testAccCheckApigeeSharedFlowDestroyProducer(t *testing.T) func(s *terraform } } - func testAccApigeeSharedFlow_apigeeSharedflowTestExampleUpdate(context map[string]interface{}) string { return Nprintf(` resource "google_project" "project" { @@ -214,14 +207,7 @@ resource "google_apigee_organization" "apigee_org" { ] } -resource "google_apigee_environment" "org" { - org_id = google_apigee_organization.apigee_org.id - name = "tf-test%{random_suffix}" - description = "Apigee Environment" - display_name = "environment-1" -} - -resource "google_apigee_shared_flow" "test_apigee_sharedflow" { +resource "google_apigee_sharedflow" "test_apigee_sharedflow" { name = "tf-test-apigee-sharedflow" org_id = google_project.project.project_id config_bundle = "./test-fixtures/apigee/apigee_sharedflow_bundle2.zip" diff --git a/mmv1/third_party/terraform/utils/provider.go.erb b/mmv1/third_party/terraform/utils/provider.go.erb index 73e610340fba..9a69caf742c8 100644 --- a/mmv1/third_party/terraform/utils/provider.go.erb +++ b/mmv1/third_party/terraform/utils/provider.go.erb @@ -492,7 +492,8 @@ end # products.each do "google_storage_default_object_acl": resourceStorageDefaultObjectAcl(), "google_storage_notification": resourceStorageNotification(), "google_storage_transfer_job": resourceStorageTransferJob(), - "google_apigee_shared_flow": resourceApigeeSharedFlow(), + "google_apigee_sharedflow": resourceApigeeSharedFlow(), + "google_apigee_sharedflow_deployment": resourceApigeeSharedFlowDeployment(), "google_tags_location_tag_binding": resourceTagsLocationTagBinding(), // ####### END handwritten resources ########### }, diff --git a/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown b/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown index cc71c10e6dfd..be5cb7b12b3c 100644 --- a/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown @@ -1,3 +1,17 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- subcategory: "Apigee" page_title: "Google: google_apigee_shared_flow" description: |- @@ -30,9 +44,6 @@ The following arguments are supported: The Apigee Organization associated with the Apigee instance, in the format `organizations/{{org_name}}`. -* `config_bundle` - - (Required) - The configuration bundle zip file path. - - - @@ -51,10 +62,10 @@ In addition to the arguments listed above, the following computed attributes are * `revision` - A list of revisions of this shared flow. -* `latest_revision_id` - +* `latest_revision_id` - The id of the most recently created revision for this shared flow. -* `md5hash` - +* `md5hash` - (Computed) Base 64 MD5 hash of the uploaded data. It is speculative as remote does not return hash of the bundle. Remote changes are detected using returned last_modified timestamp. * `detect_md5hash` - @@ -81,7 +92,6 @@ This resource provides the following [Timeouts](/docs/configuration/resources.html#timeouts) configuration options: - `create` - Default is 20 minutes. -- `update` - Default is 20 minutes. - `delete` - Default is 20 minutes. ## Import @@ -91,4 +101,5 @@ SharedFlow can be imported using any of these accepted formats: ``` $ terraform import google_apigee_shared_flow.default {{org_id}}/sharedflows/{{name}} +$ terraform import google_apigee_shared_flow.default {{org_id}}/{{name}} ``` diff --git a/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow_deployment.html.markdown b/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow_deployment.html.markdown new file mode 100644 index 000000000000..e86895f20f25 --- /dev/null +++ b/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow_deployment.html.markdown @@ -0,0 +1,85 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Apigee" +description: |- + Deploys a revision of a sharedflow. +--- + +# google\_apigee\_sharedflow\_deployment + +Deploys a revision of a sharedflow. + + +To get more information about SharedflowDeployment, see: + +* [API documentation](https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.environments.sharedflows.revisions.deployments) +* How-to Guides + * [sharedflows.revisions.deployments](https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.environments.sharedflows.revisions.deployments) + +## Argument Reference + +The following arguments are supported: + + +* `org_id` - + (Required) + The Apigee Organization associated with the Apigee instance + +* `environment` - + (Required) + The resource ID of the environment. + +* `sharedflow_id` - + (Required) + Id of the Sharedflow to be deployed. + +* `revision` - + (Required) + Revision of the Sharedflow to be deployed. + + +- - - + + +* `service_account` - + (Optional) + The service account represents the identity of the deployed proxy, and determines what permissions it has. The format must be {ACCOUNT_ID}@{PROJECT}.iam.gserviceaccount.com. + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `organizations/{{org_id}}/environments/{{environment}}/sharedflows/{{sharedflow_id}}/revisions/{{revision}}/deployments` + + +## Timeouts + +This resource provides the following +[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: + +- `create` - Default is 20 minutes. +- `update` - Default is 20 minutes. +- `delete` - Default is 20 minutes. + +## Import + + +SharedflowDeployment can be imported using any of these accepted formats: + +``` +$ terraform import google_apigee_sharedflow_deployment.default organizations/{{org_id}}/environments/{{environment}}/sharedflows/{{sharedflow_id}}/revisions/{{revision}}/deployments/{{name}} +$ terraform import google_apigee_sharedflow_deployment.default {{org_id}}/{{environment}}/{{sharedflow_id}}/{{revision}}/{{name}} +``` From fdb4e171ec189edc7aea137c66931a0a5fb7f45f Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 11:57:44 -0800 Subject: [PATCH 16/41] Update apigee_shared_flow_deployment.html.markdown minor doc fix --- .../website/docs/r/apigee_shared_flow_deployment.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow_deployment.html.markdown b/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow_deployment.html.markdown index e86895f20f25..db00fac58d83 100644 --- a/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow_deployment.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow_deployment.html.markdown @@ -35,7 +35,7 @@ The following arguments are supported: * `org_id` - (Required) - The Apigee Organization associated with the Apigee instance + The Apigee Organization associated with the Sharedflow * `environment` - (Required) From a84b32d6a7de1491969831703d358e30f783d175 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 13:06:50 -0800 Subject: [PATCH 17/41] Update mmv1/third_party/terraform/utils/provider.go.erb Co-authored-by: megan07 --- mmv1/third_party/terraform/utils/provider.go.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/third_party/terraform/utils/provider.go.erb b/mmv1/third_party/terraform/utils/provider.go.erb index f650c075dc66..fe856b5f9c47 100644 --- a/mmv1/third_party/terraform/utils/provider.go.erb +++ b/mmv1/third_party/terraform/utils/provider.go.erb @@ -493,7 +493,7 @@ end # products.each do "google_storage_default_object_acl": resourceStorageDefaultObjectAcl(), "google_storage_notification": resourceStorageNotification(), "google_storage_transfer_job": resourceStorageTransferJob(), - "google_apigee_sharedflow": resourceApigeeSharedFlow(), + "google_apigee_sharedflow": resourceApigeeSharedFlow(), "google_apigee_sharedflow_deployment": resourceApigeeSharedFlowDeployment(), "google_tags_location_tag_binding": resourceTagsLocationTagBinding(), From 7921f9f9dc006930319e32ef9f9550555e134896 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 13:07:13 -0800 Subject: [PATCH 18/41] Update mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown Co-authored-by: megan07 --- .../terraform/website/docs/r/apigee_shared_flow.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown b/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown index be5cb7b12b3c..9da48d0f89ed 100644 --- a/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown @@ -101,5 +101,5 @@ SharedFlow can be imported using any of these accepted formats: ``` $ terraform import google_apigee_shared_flow.default {{org_id}}/sharedflows/{{name}} -$ terraform import google_apigee_shared_flow.default {{org_id}}/{{name}} +$ terraform import google_apigee_sharedflow.default {{org_id}}/{{name}} ``` From 378fa0ae55066e99908fc9c992c78ff1acc67d83 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 13:08:58 -0800 Subject: [PATCH 19/41] Update resource_apigee_shared_flow_test.go remove commented out (unused) line of code --- .../terraform/tests/resource_apigee_shared_flow_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go index fb5b123e4bb6..9c36f78a7cb0 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go @@ -128,7 +128,6 @@ func testAccCheckApigeeSharedFlowDestroyProducer(t *testing.T) func(s *terraform config := googleProviderConfig(t) url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows/{{name}}") - // url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows/test-apigee-sharedflow") if err != nil { return err } From 724c350da6518eb0f7d8d6a50a6cf63ae2424e7d Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 13:10:52 -0800 Subject: [PATCH 20/41] Delete api.yaml remove api.yaml as it is not needed for handwritten resource. Current repo structure no longer uses aggregated api.yaml --- mmv1/products/apigee/api.yaml | 794 ---------------------------------- 1 file changed, 794 deletions(-) delete mode 100644 mmv1/products/apigee/api.yaml diff --git a/mmv1/products/apigee/api.yaml b/mmv1/products/apigee/api.yaml deleted file mode 100644 index 474e5cf07768..000000000000 --- a/mmv1/products/apigee/api.yaml +++ /dev/null @@ -1,794 +0,0 @@ -# Copyright 2020 Google Inc. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - ---- !ruby/object:Api::Product -name: Apigee -display_name: Apigee -versions: - - !ruby/object:Api::Product::Version - name: ga - base_url: https://apigee.googleapis.com/v1/ - # Apigee has no beta API, but running the full Terraform - # acceptance tests depends on a beta-only resource and a bug in MM - # will generate beta tests against the GA provider in this case, so - # we fake a beta API with the same endpoint as the GA API. - - !ruby/object:Api::Product::Version - name: beta - base_url: https://apigee.googleapis.com/v1/ -scopes: - - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Apigee API - url: https://console.cloud.google.com/apis/library/apigee.googleapis.com/ -objects: - - !ruby/object:Api::Resource - name: 'Organization' - base_url: 'organizations' - create_url: 'organizations?parent=projects/{{project_id}}' - delete_url: 'organizations/{{name}}?retention={{retention}}' - self_link: 'organizations/{{name}}' - async: !ruby/object:Api::OpAsync - actions: ['create', 'update'] - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: True - allowed: - - True - - False - error: !ruby/object:Api::OpAsync::Error - path: 'error' - message: 'message' - description: | - An `Organization` is the top-level container in Apigee. - parameters: - - !ruby/object:Api::Type::String - name: 'projectId' - description: | - The project ID associated with the Apigee organization. - required: true - input: true - url_param_only: true - - !ruby/object:Api::Type::Enum - name: 'retention' - description: | - Optional. This setting is applicable only for organizations that are soft-deleted (i.e., BillingType - is not EVALUATION). It controls how long Organization data will be retained after the initial delete - operation completes. During this period, the Organization may be restored to its last known state. - After this period, the Organization will no longer be able to be restored. - values: - - "DELETION_RETENTION_UNSPECIFIED" - - "MINIMUM" - default_value: :DELETION_RETENTION_UNSPECIFIED - required: false - url_param_only: true - properties: - - !ruby/object:Api::Type::String - name: 'name' - description: | - Output only. Name of the Apigee organization. - output: true - - !ruby/object:Api::Type::String - name: 'displayName' - description: | - The display name of the Apigee organization. - - !ruby/object:Api::Type::String - name: 'description' - description: | - Description of the Apigee organization. - - !ruby/object:Api::Type::String - name: 'analyticsRegion' - description: | - Primary GCP region for analytics data storage. For valid values, see [Create an Apigee organization](https://cloud.google.com/apigee/docs/api-platform/get-started/create-org). - input: true - - !ruby/object:Api::Type::String - name: 'authorizedNetwork' - description: | - Compute Engine network used for Service Networking to be peered with Apigee runtime instances. - See [Getting started with the Service Networking API](https://cloud.google.com/service-infrastructure/docs/service-networking/getting-started). - Valid only when `RuntimeType` is set to CLOUD. The value can be updated only when there are no runtime instances. For example: "default". - - !ruby/object:Api::Type::Enum - name: 'runtimeType' - description: | - Runtime type of the Apigee organization based on the Apigee subscription purchased. - values: - - "CLOUD" - - "HYBRID" - default_value: :CLOUD - input: true - - !ruby/object:Api::Type::String - name: 'subscriptionType' - description: | - Output only. Subscription type of the Apigee organization. - Valid values include trial (free, limited, and for evaluation purposes only) or paid (full subscription has been purchased). - output: true - - !ruby/object:Api::Type::String - name: 'billingType' - description: | - Billing type of the Apigee organization. See [Apigee pricing](https://cloud.google.com/apigee/pricing). - input: true - - !ruby/object:Api::Type::String - name: 'caCertificate' - description: | - Output only. Base64-encoded public certificate for the root CA of the Apigee organization. - Valid only when `RuntimeType` is CLOUD. A base64-encoded string. - output: true - - !ruby/object:Api::Type::String - name: 'runtimeDatabaseEncryptionKeyName' - description: | - Cloud KMS key name used for encrypting the data that is stored and replicated across runtime instances. - Update is not allowed after the organization is created. - If not specified, a Google-Managed encryption key will be used. - Valid only when `RuntimeType` is CLOUD. For example: `projects/foo/locations/us/keyRings/bar/cryptoKeys/baz`. - input: true - - !ruby/object:Api::Type::NestedObject - name: 'properties' - description: Properties defined in the Apigee organization profile. - properties: - - !ruby/object:Api::Type::Array - name: 'property' - description: List of all properties in the object. - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::String - name: 'name' - description: Name of the property. - - !ruby/object:Api::Type::String - name: 'value' - description: Value of the property. - references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Creating an API organization': - 'https://cloud.google.com/apigee/docs/api-platform/get-started/create-org' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations' - - !ruby/object:Api::Resource - name: 'Instance' - base_url: 'instances' - create_url: '{{org_id}}/instances' - self_link: '{{org_id}}/instances/{{name}}' - async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: True - allowed: - - True - - False - error: !ruby/object:Api::OpAsync::Error - path: 'error' - message: 'message' - input: true - description: | - An `Instance` is the runtime dataplane in Apigee. - parameters: - - !ruby/object:Api::Type::String - name: 'orgId' - description: | - The Apigee Organization associated with the Apigee instance, - in the format `organizations/{{org_name}}`. - required: true - input: true - url_param_only: true - properties: - - !ruby/object:Api::Type::String - name: 'name' - description: | - Resource ID of the instance. - required: true - - !ruby/object:Api::Type::String - name: 'location' - description: | - Required. Compute Engine location where the instance resides. - required: true - - !ruby/object:Api::Type::String - name: 'peeringCidrRange' - description: | - The size of the CIDR block range that will be reserved by the instance. For valid values, - see [CidrRange](https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances#CidrRange) on the documentation. - - !ruby/object:Api::Type::String - name: 'ipRange' - description: | - IP range represents the customer-provided CIDR block of length 22 that will be used for - the Apigee instance creation. This optional range, if provided, should be freely - available as part of larger named range the customer has allocated to the Service - Networking peering. If this is not provided, Apigee will automatically request for any - available /22 CIDR block from Service Networking. The customer should use this CIDR block - for configuring their firewall needs to allow traffic from Apigee. - Input format: "a.b.c.d/22" - - !ruby/object:Api::Type::String - name: 'description' - description: | - Description of the instance. - - !ruby/object:Api::Type::String - name: 'displayName' - description: | - Display name of the instance. - - !ruby/object:Api::Type::String - name: 'diskEncryptionKeyName' - description: | - Customer Managed Encryption Key (CMEK) used for disk and volume encryption. Required for Apigee paid subscriptions only. - Use the following format: `projects/([^/]+)/locations/([^/]+)/keyRings/([^/]+)/cryptoKeys/([^/]+)` - input: true - - !ruby/object:Api::Type::String - name: 'host' - description: | - Output only. Hostname or IP address of the exposed Apigee endpoint used by clients to connect to the service. - output: true - - !ruby/object:Api::Type::String - name: 'port' - description: | - Output only. Port number of the exposed Apigee endpoint. - output: true - - !ruby/object:Api::Type::Array - name: 'consumerAcceptList' - description: | - Optional. Customer accept list represents the list of projects (id/number) on customer - side that can privately connect to the service attachment. It is an optional field - which the customers can provide during the instance creation. By default, the customer - project associated with the Apigee organization will be included to the list. - required: false - item_type: Api::Type::String - - !ruby/object:Api::Type::String - name: 'serviceAttachment' - description: | - Output only. Resource name of the service attachment created for the instance in - the format: projects/*/regions/*/serviceAttachments/* Apigee customers can privately - forward traffic to this service attachment using the PSC endpoints. - output: true - references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Creating a runtime instance': - 'https://cloud.google.com/apigee/docs/api-platform/get-started/create-instance' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances/create' - - !ruby/object:Api::Resource - name: 'Environment' - base_url: 'environments' - create_url: '{{org_id}}/environments' - self_link: '{{org_id}}/environments/{{name}}' - update_url: '{{org_id}}/environments/{{name}}' - update_verb: :PATCH - update_mask: true - async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: True - allowed: - - True - - False - error: !ruby/object:Api::OpAsync::Error - path: 'error' - message: 'message' - description: | - An `Environment` in Apigee. - iam_policy: !ruby/object:Api::Resource::IamPolicy - exclude: false - method_name_separator: ':' - parent_resource_attribute: 'env_id' - import_format: ["{{%org_id}}/environments/{{name}}", "{{name}}"] - base_url: "{{org_id}}/environments/{{name}}" - self_link: "{{org_id}}/environments/{{name}}" - parameters: - - !ruby/object:Api::Type::String - name: 'orgId' - description: | - The Apigee Organization associated with the Apigee environment, - in the format `organizations/{{org_name}}`. - required: true - input: true - url_param_only: true - properties: - - !ruby/object:Api::Type::String - name: 'name' - description: | - The resource ID of the environment. - required: true - input: true - - !ruby/object:Api::Type::String - name: 'displayName' - description: | - Display name of the environment. - required: false - input: true - - !ruby/object:Api::Type::String - name: 'description' - description: | - Description of the environment. - required: false - input: true - - !ruby/object:Api::Type::Enum - name: 'deploymentType' - description: | - Optional. Deployment type supported by the environment. The deployment type can be - set when creating the environment and cannot be changed. When you enable archive - deployment, you will be prevented from performing a subset of actions within the - environment, including: - Managing the deployment of API proxy or shared flow revisions; - Creating, updating, or deleting resource files; - Creating, updating, or deleting target servers. - values: - - "DEPLOYMENT_TYPE_UNSPECIFIED" - - "PROXY" - - "ARCHIVE" - input: true - - !ruby/object:Api::Type::Enum - name: 'apiProxyType' - description: | - Optional. API Proxy type supported by the environment. The type can be set when creating - the Environment and cannot be changed. - values: - - "API_PROXY_TYPE_UNSPECIFIED" - - "PROGRAMMABLE" - - "CONFIGURABLE" - input: true - - !ruby/object:Api::Type::NestedObject - name: 'nodeConfig' - description: | - NodeConfig for setting the min/max number of nodes associated with the environment. - properties: - - !ruby/object:Api::Type::String - name: 'minNodeCount' - description: | - The minimum total number of gateway nodes that the is reserved for all instances that - has the specified environment. If not specified, the default is determined by the - recommended minimum number of nodes for that gateway. - - !ruby/object:Api::Type::String - name: 'maxNodeCount' - description: | - The maximum total number of gateway nodes that the is reserved for all instances that - has the specified environment. If not specified, the default is determined by the - recommended maximum number of nodes for that gateway. - - !ruby/object:Api::Type::String - name: 'currentAggregateNodeCount' - description: | - The current total number of gateway nodes that each environment currently has across - all instances. - output: true - references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Creating an environment': - 'https://cloud.google.com/apigee/docs/api-platform/get-started/create-environment' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.environments/create' - - !ruby/object:Api::Resource - name: 'Envgroup' - base_url: 'envgroups' - create_url: '{{org_id}}/envgroups' - self_link: '{{org_id}}/envgroups/{{name}}' - update_verb: :PATCH - update_mask: true - async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: True - allowed: - - True - - False - error: !ruby/object:Api::OpAsync::Error - path: 'error' - message: 'message' - description: | - An `Environment group` in Apigee. - parameters: - - !ruby/object:Api::Type::String - name: 'orgId' - description: | - The Apigee Organization associated with the Apigee environment group, - in the format `organizations/{{org_name}}`. - required: true - input: true - url_param_only: true - properties: - - !ruby/object:Api::Type::String - name: 'name' - description: | - The resource ID of the environment group. - required: true - input: true - - !ruby/object:Api::Type::Array - name: 'hostnames' - description: | - Hostnames of the environment group. - required: false - item_type: Api::Type::String - references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Creating an environment': - 'https://cloud.google.com/apigee/docs/api-platform/get-started/create-environment' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.envgroups/create' - - !ruby/object:Api::Resource - name: 'InstanceAttachment' - base_url: '{{instance_id}}/attachments' - create_url: '{{instance_id}}/attachments' - delete_url: '{{instance_id}}/attachments/{{name}}' - self_link: '{{instance_id}}/attachments/{{name}}' - async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: True - allowed: - - True - - False - error: !ruby/object:Api::OpAsync::Error - path: 'error' - message: 'message' - input: true - description: | - An `Instance attachment` in Apigee. - parameters: - - !ruby/object:Api::Type::String - name: 'instanceId' - description: | - The Apigee instance associated with the Apigee environment, - in the format `organisations/{{org_name}}/instances/{{instance_name}}`. - required: true - url_param_only: true - properties: - - !ruby/object:Api::Type::String - name: 'environment' - description: | - The resource ID of the environment. - required: true - - !ruby/object:Api::Type::String - name: 'name' - description: | - The name of the newly created attachment (output parameter). - output: true - references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Creating an environment': - 'https://cloud.google.com/apigee/docs/api-platform/get-started/create-environment' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances.attachments/create' - - !ruby/object:Api::Resource - name: 'EnvgroupAttachment' - base_url: '{{envgroup_id}}/attachments' - create_url: '{{envgroup_id}}/attachments' - delete_url: '{{envgroup_id}}/attachments/{{name}}' - self_link: '{{envgroup_id}}/attachments/{{name}}' - async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: True - allowed: - - True - - False - error: !ruby/object:Api::OpAsync::Error - path: 'error' - message: 'message' - input: true - description: | - An `Environment Group attachment` in Apigee. - parameters: - - !ruby/object:Api::Type::String - name: 'envgroupId' - description: | - The Apigee environment group associated with the Apigee environment, - in the format `organizations/{{org_name}}/envgroups/{{envgroup_name}}`. - required: true - url_param_only: true - properties: - - !ruby/object:Api::Type::String - name: 'environment' - description: | - The resource ID of the environment. - required: true - - !ruby/object:Api::Type::String - name: 'name' - description: | - The name of the newly created attachment (output parameter). - output: true - references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Creating an environment': - 'https://cloud.google.com/apigee/docs/api-platform/get-started/create-environment' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.envgroups.attachments/create' - - !ruby/object:Api::Resource - name: 'EndpointAttachment' - base_url: 'endpointAttachments' - create_url: '{{org_id}}/endpointAttachments?endpointAttachmentId={{endpoint_attachment_id}}' - self_link: '{{org_id}}/endpointAttachments/{{endpoint_attachment_id}}' - async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: True - allowed: - - True - - False - error: !ruby/object:Api::OpAsync::Error - path: 'error' - message: 'message' - input: true - description: | - Apigee Endpoint Attachment. - parameters: - - !ruby/object:Api::Type::String - name: 'orgId' - description: | - The Apigee Organization associated with the Apigee instance, - in the format `organizations/{{org_name}}`. - required: true - input: true - url_param_only: true - - !ruby/object:Api::Type::String - name: 'endpointAttachmentId' - description: | - ID of the endpoint attachment. - required: true - input: true - url_param_only: true - properties: - - !ruby/object:Api::Type::String - name: 'name' - description: | - Name of the Endpoint Attachment in the following format: - organizations/{organization}/endpointAttachments/{endpointAttachment}. - output: true - - !ruby/object:Api::Type::String - name: 'location' - description: | - Location of the endpoint attachment. - required: true - - !ruby/object:Api::Type::String - name: 'host' - description: | - Host that can be used in either HTTP Target Endpoint directly, or as the host in Target Server. - output: true - - !ruby/object:Api::Type::String - name: 'serviceAttachment' - description: | - Format: projects/*/regions/*/serviceAttachments/* - required: true - - !ruby/object:Api::Type::String - name: 'connectionState' - description: | - State of the endpoint attachment connection to the service attachment. - output: true - references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Creating an environment': - 'https://cloud.google.com/apigee/docs/api-platform/get-started/create-environment' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.endpointAttachments/create' - - !ruby/object:Api::Resource - name: 'NatAddress' - base_url: '{{instance_id}}/natAddresses' - create_url: '{{instance_id}}/natAddresses' - delete_url: '{{instance_id}}/natAddresses/{{name}}' - self_link: '{{instance_id}}/natAddresses/{{name}}' - async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: True - allowed: - - True - - False - error: !ruby/object:Api::OpAsync::Error - path: 'error' - message: 'message' - input: true - description: | - Apigee NAT (network address translation) address. A NAT address is a static external IP address used for Internet egress traffic. This is not avaible for Apigee hybrid. - Apigee NAT addresses are not automatically activated because they might require explicit allow entries on the target systems first. See https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances.natAddresses/activate - parameters: - - !ruby/object:Api::Type::String - name: 'instanceId' - description: | - The Apigee instance associated with the Apigee environment, - in the format `organizations/{{org_name}}/instances/{{instance_name}}`. - required: true - url_param_only: true - properties: - - !ruby/object:Api::Type::String - name: 'name' - description: | - Resource ID of the NAT address. - required: true - - !ruby/object:Api::Type::String - name: 'ipAddress' - description: | - The allocated NAT IP address. - output: true - - !ruby/object:Api::Type::String - name: 'state' - description: | - State of the NAT IP address. - output: true - references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Provisioning NAT IPs': - 'https://cloud.google.com/apigee/docs/api-platform/security/nat-provisioning' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.instances.natAddresses' - - !ruby/object:Api::Resource - name: 'SyncAuthorization' - self_link: 'organizations/{{name}}:getSyncAuthorization' - base_url: '' - create_url: 'organizations/{{name}}:setSyncAuthorization' - update_url: 'organizations/{{name}}:setSyncAuthorization' - read_verb: :POST - update_verb: :POST - description: | - Authorize the Synchronizer to download environment data from the control plane. - parameters: - - !ruby/object:Api::Type::String - name: 'name' - required: true - description: | - Name of the Apigee organization. - url_param_only: true - input: true - properties: - - !ruby/object:Api::Type::Array - name: 'identities' - required: true - send_empty_value: true - description: | - Array of service accounts to grant access to control plane resources, each specified using the following format: `serviceAccount:service-account-name`. - - The `service-account-name` is formatted like an email address. For example: my-synchronizer-manager-serviceAccount@my_project_id.iam.gserviceaccount.com - - You might specify multiple service accounts, for example, if you have multiple environments and wish to assign a unique service account to each one. - - The service accounts must have **Apigee Synchronizer Manager** role. See also [Create service accounts](https://cloud.google.com/apigee/docs/hybrid/v1.8/sa-about#create-the-service-accounts). - item_type: Api::Type::String - - !ruby/object:Api::Type::Fingerprint - name: 'etag' - description: | - Entity tag (ETag) used for optimistic concurrency control as a way to help prevent simultaneous updates from overwriting each other. - Used internally during updates. - references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Enable Synchronizer access': - 'https://cloud.google.com/apigee/docs/hybrid/v1.8/synchronizer-access#enable-synchronizer-access' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations#getsyncauthorization' - - !ruby/object:Api::Resource - name: 'AddonsConfig' - self_link: 'organizations/{{org}}' - base_url: 'organizations' - create_url: 'organizations/{{org}}:setAddons' - update_url: 'organizations/{{org}}:setAddons' - update_verb: :POST - delete_url: 'organizations/{{org}}:setAddons' - delete_verb: :POST - async: !ruby/object:Api::OpAsync - actions: ['create', 'update', 'delete'] - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: false - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: True - allowed: - - True - - False - error: !ruby/object:Api::OpAsync::Error - path: 'error' - message: 'message' - description: | - Configures the add-ons for the Apigee organization. The existing add-on configuration will be fully replaced. - parameters: - - !ruby/object:Api::Type::String - name: 'org' - required: true - description: | - Name of the Apigee organization. - url_param_only: true - input: true - properties: - - !ruby/object:Api::Type::NestedObject - name: 'addonsConfig' - description: Addon configurations of the Apigee organization. - properties: - - !ruby/object:Api::Type::NestedObject - name: 'advancedApiOpsConfig' - description: Configuration for the Monetization add-on. - properties: - - !ruby/object:Api::Type::Boolean - name: 'enabled' - description: Flag that specifies whether the Advanced API Ops add-on is enabled. - - !ruby/object:Api::Type::NestedObject - name: 'integrationConfig' - description: Configuration for the Monetization add-on. - properties: - - !ruby/object:Api::Type::Boolean - name: 'enabled' - description: Flag that specifies whether the Advanced API Ops add-on is enabled. - - !ruby/object:Api::Type::NestedObject - name: 'monetizationConfig' - description: Configuration for the Monetization add-on. - properties: - - !ruby/object:Api::Type::Boolean - name: 'enabled' - description: Flag that specifies whether the Advanced API Ops add-on is enabled. - - !ruby/object:Api::Type::NestedObject - name: 'apiSecurityConfig' - description: Configuration for the Monetization add-on. - properties: - - !ruby/object:Api::Type::Boolean - name: 'enabled' - description: Flag that specifies whether the Advanced API Ops add-on is enabled. - - !ruby/object:Api::Type::String - name: 'expiresAt' - description: Flag that specifies whether the Advanced API Ops add-on is enabled. - output: true - - !ruby/object:Api::Type::NestedObject - name: 'connectorsPlatformConfig' - description: Configuration for the Monetization add-on. - properties: - - !ruby/object:Api::Type::Boolean - name: 'enabled' - description: Flag that specifies whether the Advanced API Ops add-on is enabled. - - !ruby/object:Api::Type::String - name: 'expiresAt' - description: Flag that specifies whether the Advanced API Ops add-on is enabled. - output: true - references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Creating an API organization': - 'https://cloud.google.com/apigee/docs/api-platform/get-started/create-org' - api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations#setaddons' From bb3ed9addd9649fb1226f9e39cfae78cf246b2b8 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 13:12:37 -0800 Subject: [PATCH 21/41] Rename apigee_shared_flow.html.markdown to apigee_sharedflow.html.markdown --- ..._shared_flow.html.markdown => apigee_sharedflow.html.markdown} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename mmv1/third_party/terraform/website/docs/r/{apigee_shared_flow.html.markdown => apigee_sharedflow.html.markdown} (100%) diff --git a/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown b/mmv1/third_party/terraform/website/docs/r/apigee_sharedflow.html.markdown similarity index 100% rename from mmv1/third_party/terraform/website/docs/r/apigee_shared_flow.html.markdown rename to mmv1/third_party/terraform/website/docs/r/apigee_sharedflow.html.markdown From fb1ab7a607ff6dac137472f7aa6971bf878d578f Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 13:13:00 -0800 Subject: [PATCH 22/41] Rename apigee_shared_flow_deployment.html.markdown to apigee_sharedflow_deployment.html.markdown --- ...t.html.markdown => apigee_sharedflow_deployment.html.markdown} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename mmv1/third_party/terraform/website/docs/r/{apigee_shared_flow_deployment.html.markdown => apigee_sharedflow_deployment.html.markdown} (100%) diff --git a/mmv1/third_party/terraform/website/docs/r/apigee_shared_flow_deployment.html.markdown b/mmv1/third_party/terraform/website/docs/r/apigee_sharedflow_deployment.html.markdown similarity index 100% rename from mmv1/third_party/terraform/website/docs/r/apigee_shared_flow_deployment.html.markdown rename to mmv1/third_party/terraform/website/docs/r/apigee_sharedflow_deployment.html.markdown From 810f23eebc727f187bca52e5ee2783c1c4316fb8 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 13:13:30 -0800 Subject: [PATCH 23/41] Rename resource_apigee_shared_flow.go to resource_apigee_sharedflow.go --- ...urce_apigee_shared_flow.go => resource_apigee_sharedflow.go} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename mmv1/third_party/terraform/resources/{resource_apigee_shared_flow.go => resource_apigee_sharedflow.go} (99%) diff --git a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go similarity index 99% rename from mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go rename to mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go index 98016cc11e2d..1cdf87efc616 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_shared_flow.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go @@ -460,4 +460,4 @@ func apigeeSharedflowDetectBundleUpdate(_ context.Context, diff *schema.Resource return true } return diff.HasChange("config_bundle") || diff.HasChange("md5hash") -} \ No newline at end of file +} From 7ab690bd71a69fa6632c68b0bbb9980051f26816 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 13:13:52 -0800 Subject: [PATCH 24/41] Rename resource_apigee_shared_flow_deployment_test.go to resource_apigee_sharedflow_deployment_test.go --- ...ment_test.go => resource_apigee_sharedflow_deployment_test.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename mmv1/third_party/terraform/tests/{resource_apigee_shared_flow_deployment_test.go => resource_apigee_sharedflow_deployment_test.go} (100%) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_deployment_test.go b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go similarity index 100% rename from mmv1/third_party/terraform/tests/resource_apigee_shared_flow_deployment_test.go rename to mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go From 30903e12bb3ec3aea9e9b469c9f9c0218d562f58 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 13:14:11 -0800 Subject: [PATCH 25/41] Rename resource_apigee_shared_flow_test.go to resource_apigee_sharedflow_test.go --- ...gee_shared_flow_test.go => resource_apigee_sharedflow_test.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename mmv1/third_party/terraform/tests/{resource_apigee_shared_flow_test.go => resource_apigee_sharedflow_test.go} (100%) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_test.go similarity index 100% rename from mmv1/third_party/terraform/tests/resource_apigee_shared_flow_test.go rename to mmv1/third_party/terraform/tests/resource_apigee_sharedflow_test.go From 0664047b3b43c4e6bf88de2824454655839e3c3c Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 13:14:32 -0800 Subject: [PATCH 26/41] Rename resource_apigee_shared_flow_sweeper_test.go to resource_apigee_sharedflow_sweeper_test.go --- ...sweeper_test.go => resource_apigee_sharedflow_sweeper_test.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename mmv1/third_party/terraform/tests/{resource_apigee_shared_flow_sweeper_test.go => resource_apigee_sharedflow_sweeper_test.go} (100%) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_sweeper_test.go similarity index 100% rename from mmv1/third_party/terraform/tests/resource_apigee_shared_flow_sweeper_test.go rename to mmv1/third_party/terraform/tests/resource_apigee_sharedflow_sweeper_test.go From 13fb48288265925e945f840b4926ea67246b7edc Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 14:35:58 -0800 Subject: [PATCH 27/41] Update resource_apigee_sharedflow.go remove comment lines --- .../terraform/resources/resource_apigee_sharedflow.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go index 1cdf87efc616..4fff2543e36d 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go @@ -146,11 +146,9 @@ func resourceApigeeSharedFlowCreate(d *schema.ResourceData, meta interface{}) er tflog.Info(ctx, "resourceApigeeSharedFlowCreate") log.Printf("[DEBUG] resourceApigeeSharedFlowCreate") - //print debug info====== log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, name= %s", d.Get("name").(string)) log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, org_id=, %s", d.Get("org_id").(string)) log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, config_bundle=, %s", d.Get("config_bundle").(string)) - //debug================= config := meta.(*Config) userAgent, err := generateUserAgentString(d, config.userAgent) From 2703308fe7b4097e19e7beaaabc10eacf14a1cce Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 14:36:44 -0800 Subject: [PATCH 28/41] Update mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go Co-authored-by: megan07 --- .../terraform/resources/resource_apigee_sharedflow.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go index 4fff2543e36d..0eb659b4b200 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go @@ -377,7 +377,7 @@ func expandApigeeSharedFlowName(v interface{}, d TerraformResourceData, config * return v, nil } -//sendRequestRawBodyWithTimeout is derived from sendRequestWithTimeout with direct pass throught of request body +// sendRequestRawBodyWithTimeout is derived from sendRequestWithTimeout with direct pass through of request body func sendRequestRawBodyWithTimeout(config *Config, method, project, rawurl, userAgent string, body io.Reader, contentType string, timeout time.Duration, errorRetryPredicates ...RetryErrorPredicateFunc) (map[string]interface{}, error) { log.Printf("[DEBUG] sendRequestRawBodyWithTimeout start") reqHeaders := make(http.Header) From f3645721571e4a9c01c4c376c78110e6c7f89e81 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Feb 2023 14:47:29 -0800 Subject: [PATCH 29/41] Update resource_apigee_sharedflow_deployment_test.go remove unused debugging log --- .../tests/resource_apigee_sharedflow_deployment_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go index 19f481f16a73..dfa5d174fd35 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go @@ -13,8 +13,6 @@ func TestAccApigeeSharedflowDeployment_apigeeSharedflowDeploymentTestExample(t * skipIfVcr(t) t.Parallel() - fmt.Printf("from t: org_id %s", getTestOrgFromEnv(t)) - context := map[string]interface{}{ "org_id": getTestOrgFromEnv(t), "billing_account": getTestBillingAccountFromEnv(t), From 415c3ff1cac2b9b4fa61e43516c6ee3726b994cd Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Wed, 1 Mar 2023 00:42:19 +0000 Subject: [PATCH 30/41] update function name to capitalize --- .../resources/resource_apigee_sharedflow.go | 2 +- .../resource_apigee_sharedflow_deployment.go | 2 +- .../terraform/utils/provider.go.erb | 30 +++++++++---------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go index 0eb659b4b200..290a68855c9d 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go @@ -23,7 +23,7 @@ import ( "google.golang.org/api/googleapi" ) -func resourceApigeeSharedFlow() *schema.Resource { +func ResourceApigeeSharedFlow() *schema.Resource { return &schema.Resource{ Create: resourceApigeeSharedFlowCreate, Read: resourceApigeeSharedFlowRead, diff --git a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow_deployment.go b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow_deployment.go index 9018445067fe..71e8febc1e7f 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow_deployment.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow_deployment.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func resourceApigeeSharedFlowDeployment() *schema.Resource { +func ResourceApigeeSharedFlowDeployment() *schema.Resource { return &schema.Resource{ Create: resourceApigeeSharedflowDeploymentCreate, Read: resourceApigeeSharedflowDeploymentRead, diff --git a/mmv1/third_party/terraform/utils/provider.go.erb b/mmv1/third_party/terraform/utils/provider.go.erb index fe856b5f9c47..15430b6fb669 100644 --- a/mmv1/third_party/terraform/utils/provider.go.erb +++ b/mmv1/third_party/terraform/utils/provider.go.erb @@ -409,6 +409,8 @@ end # products.each do map[string]*schema.Resource{ // ####### START handwritten resources ########### "google_app_engine_application": ResourceAppEngineApplication(), + "google_apigee_sharedflow": ResourceApigeeSharedFlow(), + "google_apigee_sharedflow_deployment": ResourceApigeeSharedFlowDeployment(), "google_bigquery_table": ResourceBigQueryTable(), "google_bigtable_gc_policy": ResourceBigtableGCPolicy(), "google_bigtable_instance": ResourceBigtableInstance(), @@ -482,21 +484,17 @@ end # products.each do "google_runtimeconfig_config": ResourceRuntimeconfigConfig(), "google_runtimeconfig_variable": ResourceRuntimeconfigVariable(), <% end -%> - - "google_service_account": resourceGoogleServiceAccount(), - "google_service_account_key": resourceGoogleServiceAccountKey(), - "google_service_networking_peered_dns_domain": resourceGoogleServiceNetworkingPeeredDNSDomain(), - "google_storage_bucket": resourceStorageBucket(), - "google_storage_bucket_acl": resourceStorageBucketAcl(), - "google_storage_bucket_object": resourceStorageBucketObject(), - "google_storage_object_acl": resourceStorageObjectAcl(), - "google_storage_default_object_acl": resourceStorageDefaultObjectAcl(), - "google_storage_notification": resourceStorageNotification(), - "google_storage_transfer_job": resourceStorageTransferJob(), - "google_apigee_sharedflow": resourceApigeeSharedFlow(), - "google_apigee_sharedflow_deployment": resourceApigeeSharedFlowDeployment(), - "google_tags_location_tag_binding": resourceTagsLocationTagBinding(), - + "google_service_account": ResourceGoogleServiceAccount(), + "google_service_account_key": ResourceGoogleServiceAccountKey(), + "google_service_networking_peered_dns_domain": ResourceGoogleServiceNetworkingPeeredDNSDomain(), + "google_storage_bucket": ResourceStorageBucket(), + "google_storage_bucket_acl": ResourceStorageBucketAcl(), + "google_storage_bucket_object": ResourceStorageBucketObject(), + "google_storage_object_acl": ResourceStorageObjectAcl(), + "google_storage_default_object_acl": ResourceStorageDefaultObjectAcl(), + "google_storage_notification": ResourceStorageNotification(), + "google_storage_transfer_job": ResourceStorageTransferJob(), + "google_tags_location_tag_binding": ResourceTagsLocationTagBinding(), // ####### END handwritten resources ########### }, map[string]*schema.Resource{ @@ -702,4 +700,4 @@ func validateCredentials(v interface{}, k string) (warnings []string, errors []e } return -} +} \ No newline at end of file From b9c6e59a6d4538be813460428e9cd950acbf9e1a Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 1 Mar 2023 11:46:07 -0800 Subject: [PATCH 31/41] Update resource_apigee_sharedflow_deployment_test.go remove fmt.print --- .../tests/resource_apigee_sharedflow_deployment_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go index dfa5d174fd35..bd194dc94a12 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go @@ -140,7 +140,6 @@ func testAccCheckApigeeSharedflowDeploymentDestroyProducer(t *testing.T) func(s if config.BillingProject != "" { billingProject = config.BillingProject } - fmt.Printf("testAccCheckApigeeSharedflowDeploymentDestroyProducer, url %s", url) _, err = sendRequest(config, "GET", billingProject, url, config.userAgent, nil) if err == nil { return fmt.Errorf("ApigeeSharedFlow still exists at %s", url) From f2fe53a794ae1ef138ab179edbe8df8afef1368b Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Thu, 2 Mar 2023 02:23:31 +0000 Subject: [PATCH 32/41] add flowhook --- .../resources/resource_apigee_flowhook.go | 239 ++++++++++++++++++ .../tests/resource_apigee_flowhook_test.go | 162 ++++++++++++ .../terraform/utils/provider.go.erb | 1 + .../docs/d/apigee_flowhook.html.markdown | 71 ++++++ 4 files changed, 473 insertions(+) create mode 100644 mmv1/third_party/terraform/resources/resource_apigee_flowhook.go create mode 100644 mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go create mode 100644 mmv1/third_party/terraform/website/docs/d/apigee_flowhook.html.markdown diff --git a/mmv1/third_party/terraform/resources/resource_apigee_flowhook.go b/mmv1/third_party/terraform/resources/resource_apigee_flowhook.go new file mode 100644 index 000000000000..a220a85f88d6 --- /dev/null +++ b/mmv1/third_party/terraform/resources/resource_apigee_flowhook.go @@ -0,0 +1,239 @@ +package google + +import ( + "fmt" + "log" + "reflect" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func ResourceApigeeFlowhook() *schema.Resource { + return &schema.Resource{ + Create: resourceApigeeFlowhookCreate, + Read: resourceApigeeFlowhookRead, + Delete: resourceApigeeFlowhookDelete, + + Importer: &schema.ResourceImporter{ + State: resourceApigeeFlowhookImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Description of the flow hook.`, + }, + "environment": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The resource ID of the environment.`, + }, + "flow_hook_point": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Where in the API call flow the flow hook is invoked. Must be one of PreProxyFlowHook, PostProxyFlowHook, PreTargetFlowHook, or PostTargetFlowHook.`, + }, + "org_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The Apigee Organization associated with the environment`, + }, + "sharedflow": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Id of the Sharedflow attaching to a flowhook point.`, + }, + "continue_on_error": { + Type: schema.TypeBool, + Required: true, + ForceNew: true, + Description: `Flag that specifies whether execution should continue if the flow hook throws an exception. Set to true to continue execution. Set to false to stop execution if the flow hook throws an exception. Defaults to true.`, + }, + }, + UseJSONNumber: true, + } +} + +func resourceApigeeFlowhookCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + descriptionProp, err := expandApigeeFlowhookDescription(d.Get("description"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + sharedflowProp, err := expandApigeeFlowhookSharedflow(d.Get("sharedflow"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("sharedflow"); !isEmptyValue(reflect.ValueOf(sharedflowProp)) && (ok || !reflect.DeepEqual(v, sharedflowProp)) { + obj["sharedFlow"] = sharedflowProp + } + continue_on_errorProp, err := expandApigeeFlowhookContinueOnError(d.Get("continue_on_error"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("continue_on_error"); !isEmptyValue(reflect.ValueOf(continue_on_errorProp)) && (ok || !reflect.DeepEqual(v, continue_on_errorProp)) { + obj["continueOnError"] = continue_on_errorProp + } + + url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new Flowhook: %#v", obj) + billingProject := "" + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestWithTimeout(config, "PUT", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating Flowhook: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating Flowhook %q: %#v", d.Id(), res) + + return resourceApigeeFlowhookRead(d, meta) +} + +func resourceApigeeFlowhookRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}") + if err != nil { + return err + } + + billingProject := "" + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequest(config, "GET", billingProject, url, userAgent, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("ApigeeFlowhook %q", d.Id())) + } + if res["sharedFlow"] == nil || res["sharedFlow"].(string) == "" { + //if response does not contain shared_flow field, then nothing is attached to this flowhook, we treat this "binding" resource non-existent + d.SetId("") + return nil + } + if err := d.Set("description", flattenApigeeFlowhookDescription(res["description"], d, config)); err != nil { + return fmt.Errorf("Error reading Flowhook: %s", err) + } + if err := d.Set("sharedflow", flattenApigeeFlowhookSharedflow(res["sharedFlow"], d, config)); err != nil { + return fmt.Errorf("Error reading Flowhook: %s", err) + } + if err := d.Set("continue_on_error", flattenApigeeFlowhookContinueOnError(res["continueOnError"], d, config)); err != nil { + return fmt.Errorf("Error reading Flowhook: %s", err) + } + + return nil +} + +func resourceApigeeFlowhookDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + billingProject := "" + + url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting Flowhook %q", d.Id()) + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "Flowhook") + } + + log.Printf("[DEBUG] Finished deleting Flowhook %q: %#v", d.Id(), res) + return nil +} + +func resourceApigeeFlowhookImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{ + "organizations/(?P[^/]+)/environments/(?P[^/]+)/flowhooks/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenApigeeFlowhookDescription(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenApigeeFlowhookSharedflow(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenApigeeFlowhookContinueOnError(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func expandApigeeFlowhookDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandApigeeFlowhookSharedflow(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandApigeeFlowhookContinueOnError(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go b/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go new file mode 100644 index 000000000000..9aa16b60e5a1 --- /dev/null +++ b/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go @@ -0,0 +1,162 @@ +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccApigeeFlowhook_apigeeFlowhookTestExample(t *testing.T) { + skipIfVcr(t) + t.Parallel() + + context := map[string]interface{}{ + "org_id": getTestOrgFromEnv(t), + "billing_account": getTestBillingAccountFromEnv(t), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckApigeeFlowhookDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccApigeeFlowhook_apigeeFlowhookTestExample(context), + }, + { + ResourceName: "google_apigee_flowhook.flowhook_test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +func testAccApigeeFlowhook_apigeeFlowhookTestExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_account}" +} + +resource "google_project_service" "apigee" { + project = google_project.project.project_id + service = "apigee.googleapis.com" +} + +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" +} + +resource "google_apigee_sharedflow" "test_apigee_sharedflow" { + name = "tf-test-apigee-sharedflow" + org_id = google_project.project.project_id + config_bundle = "./test-fixtures/apigee/apigee_sharedflow_bundle.zip" + depends_on = [google_apigee_organization.apigee_org] +} + +resource "google_apigee_sharedflow_deployment" "sharedflow_deployment_test" { + environment = google_apigee_environment.apigee_environment.name + org_id = google_apigee_sharedflow.test_apigee_sharedflow.org_id + revision = google_apigee_sharedflow.test_apigee_sharedflow.revision[length(google_apigee_sharedflow.test_apigee_sharedflow.revision)-1] + sharedflow_id = google_apigee_sharedflow.test_apigee_sharedflow.name +} + +resource "google_apigee_flowhook" "flowhook_test" { + environment = google_apigee_sharedflow_deployment.sharedflow_deployment_test.environment + org_id = google_apigee_sharedflow.test_apigee_sharedflow.org_id + flow_hook_point = "PreProxyFlowHook" + sharedflow = google_apigee_sharedflow.test_apigee_sharedflow.name + description = "test flowhook" + continue_on_error = true + } +`, context) +} + +func testAccCheckApigeeFlowhookDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_apigee_flowhook" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := googleProviderConfig(t) + + url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + fmt.Printf("testAccCheckApigeeFlowhookDestroyProducer, url %s", url) + res, err := sendRequest(config, "GET", billingProject, url, config.userAgent, nil) + //Flowhooks always exist, we treat the binding as a removable resource, thus we check if the sharedFlow field to detect sharedflow attachment + if err == nil && res != nil && res["sharedFlow"] != nil { + return fmt.Errorf("Flowhook still still have attachment at %s", url) + } + } + + return nil + } +} diff --git a/mmv1/third_party/terraform/utils/provider.go.erb b/mmv1/third_party/terraform/utils/provider.go.erb index 15430b6fb669..e4b5f4bf9a72 100644 --- a/mmv1/third_party/terraform/utils/provider.go.erb +++ b/mmv1/third_party/terraform/utils/provider.go.erb @@ -411,6 +411,7 @@ end # products.each do "google_app_engine_application": ResourceAppEngineApplication(), "google_apigee_sharedflow": ResourceApigeeSharedFlow(), "google_apigee_sharedflow_deployment": ResourceApigeeSharedFlowDeployment(), + "google_apigee_flowhook": ResourceApigeeFlowhook(), "google_bigquery_table": ResourceBigQueryTable(), "google_bigtable_gc_policy": ResourceBigtableGCPolicy(), "google_bigtable_instance": ResourceBigtableInstance(), diff --git a/mmv1/third_party/terraform/website/docs/d/apigee_flowhook.html.markdown b/mmv1/third_party/terraform/website/docs/d/apigee_flowhook.html.markdown new file mode 100644 index 000000000000..dd2d6dd66171 --- /dev/null +++ b/mmv1/third_party/terraform/website/docs/d/apigee_flowhook.html.markdown @@ -0,0 +1,71 @@ +--- +subcategory: "Apigee" +description: |- + Represents a sharedflow attacehment to a flowhook point. +--- + +# google\_apigee\_flowhook + +Represents a sharedflow attacehment to a flowhook point. + + +To get more information about Flowhook, see: + +* [API documentation](https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.environments.flowhooks#FlowHook) +* How-to Guides + * [organizations.environments.flowhooks](https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.environments.flowhooks#FlowHook) + +## Argument Reference + +The following arguments are supported: + + +* `org_id` - + (Required) + The Apigee Organization associated with the environment + +* `environment` - + (Required) + The resource ID of the environment. + +* `flow_hook_point` - + (Required) + Where in the API call flow the flow hook is invoked. Must be one of PreProxyFlowHook, PostProxyFlowHook, PreTargetFlowHook, or PostTargetFlowHook. + +* `description` - + (Required) + Description of the flow hook. + +* `sharedflow` - + (Required) + Id of the Sharedflow attaching to a flowhook point. + +* `continue_on_error` - + (Required) + Flag that specifies whether execution should continue if the flow hook throws an exception. Set to true to continue execution. Set to false to stop execution if the flow hook throws an exception. Defaults to true. + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}` + + +## Timeouts + +This resource provides the following +[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: + +- `create` - Default is 20 minutes. +- `delete` - Default is 20 minutes. + +## Import + + +Flowhook can be imported using any of these accepted formats: + +``` +$ terraform import google_apigee_flowhook.default organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}} +$ terraform import google_apigee_flowhook.default {{org_id}}/{{environment}}/{{flow_hook_point}} +``` From a05ebea6029ed08bc31acedc662c25b111cf5f16 Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Thu, 2 Mar 2023 02:25:39 +0000 Subject: [PATCH 33/41] move flowhook doc --- .../terraform/website/docs/{d => r}/apigee_flowhook.html.markdown | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename mmv1/third_party/terraform/website/docs/{d => r}/apigee_flowhook.html.markdown (100%) diff --git a/mmv1/third_party/terraform/website/docs/d/apigee_flowhook.html.markdown b/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown similarity index 100% rename from mmv1/third_party/terraform/website/docs/d/apigee_flowhook.html.markdown rename to mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown From 68d8ce7db4031c851e92b59bf5977902077f129e Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 2 Mar 2023 11:18:47 -0800 Subject: [PATCH 34/41] Update mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go Co-authored-by: megan07 --- .../terraform/tests/resource_apigee_flowhook_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go b/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go index 9aa16b60e5a1..9a3588ed57b0 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go @@ -153,7 +153,7 @@ func testAccCheckApigeeFlowhookDestroyProducer(t *testing.T) func(s *terraform.S res, err := sendRequest(config, "GET", billingProject, url, config.userAgent, nil) //Flowhooks always exist, we treat the binding as a removable resource, thus we check if the sharedFlow field to detect sharedflow attachment if err == nil && res != nil && res["sharedFlow"] != nil { - return fmt.Errorf("Flowhook still still have attachment at %s", url) + return fmt.Errorf("Flowhook still has an attachment at %s", url) } } From 7984858db7ebc0c9631f8d847f4e07aebd07c3ad Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 2 Mar 2023 11:19:04 -0800 Subject: [PATCH 35/41] Update mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown Co-authored-by: megan07 --- .../terraform/website/docs/r/apigee_flowhook.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown b/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown index dd2d6dd66171..7918c4ac7e58 100644 --- a/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown @@ -6,7 +6,7 @@ description: |- # google\_apigee\_flowhook -Represents a sharedflow attacehment to a flowhook point. +Represents a sharedflow attachment to a flowhook point. To get more information about Flowhook, see: From 823c092b967dac4f7fb0d7294e56965970721279 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 2 Mar 2023 11:19:14 -0800 Subject: [PATCH 36/41] Update mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown Co-authored-by: megan07 --- .../terraform/website/docs/r/apigee_flowhook.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown b/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown index 7918c4ac7e58..9ba45000a083 100644 --- a/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown @@ -1,7 +1,7 @@ --- subcategory: "Apigee" description: |- - Represents a sharedflow attacehment to a flowhook point. + Represents a sharedflow attachment to a flowhook point. --- # google\_apigee\_flowhook From 2a4df9cd3702d7e1380ea71eba249925a4b8067f Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 2 Mar 2023 11:49:03 -0800 Subject: [PATCH 37/41] Update mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go Co-authored-by: megan07 --- .../terraform/tests/resource_apigee_flowhook_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go b/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go index 9a3588ed57b0..edf0b990a61d 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go @@ -151,7 +151,7 @@ func testAccCheckApigeeFlowhookDestroyProducer(t *testing.T) func(s *terraform.S } fmt.Printf("testAccCheckApigeeFlowhookDestroyProducer, url %s", url) res, err := sendRequest(config, "GET", billingProject, url, config.userAgent, nil) - //Flowhooks always exist, we treat the binding as a removable resource, thus we check if the sharedFlow field to detect sharedflow attachment + // Flowhooks always exist, we treat the binding as a removable resource, thus we check if the sharedFlow field to detect sharedflow attachment if err == nil && res != nil && res["sharedFlow"] != nil { return fmt.Errorf("Flowhook still has an attachment at %s", url) } From 3defe5fd1513a2ad6cf580f69d67dee192283ffd Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 2 Mar 2023 11:50:39 -0800 Subject: [PATCH 38/41] Update resource_apigee_flowhook_test.go remove fmt.print --- .../third_party/terraform/tests/resource_apigee_flowhook_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go b/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go index edf0b990a61d..e86c5e583c05 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go @@ -149,7 +149,6 @@ func testAccCheckApigeeFlowhookDestroyProducer(t *testing.T) func(s *terraform.S if config.BillingProject != "" { billingProject = config.BillingProject } - fmt.Printf("testAccCheckApigeeFlowhookDestroyProducer, url %s", url) res, err := sendRequest(config, "GET", billingProject, url, config.userAgent, nil) // Flowhooks always exist, we treat the binding as a removable resource, thus we check if the sharedFlow field to detect sharedflow attachment if err == nil && res != nil && res["sharedFlow"] != nil { From b8ec591885495c8268270dadb25fd609ea2b12b5 Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Mon, 6 Mar 2023 20:23:29 +0000 Subject: [PATCH 39/41] update some resource attribute properties --- .../terraform/resources/resource_apigee_flowhook.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mmv1/third_party/terraform/resources/resource_apigee_flowhook.go b/mmv1/third_party/terraform/resources/resource_apigee_flowhook.go index a220a85f88d6..003126eb0793 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_flowhook.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_flowhook.go @@ -27,7 +27,7 @@ func ResourceApigeeFlowhook() *schema.Resource { Schema: map[string]*schema.Schema{ "description": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, Description: `Description of the flow hook.`, }, @@ -57,8 +57,9 @@ func ResourceApigeeFlowhook() *schema.Resource { }, "continue_on_error": { Type: schema.TypeBool, - Required: true, ForceNew: true, + Optional: true, + Default: true, Description: `Flag that specifies whether execution should continue if the flow hook throws an exception. Set to true to continue execution. Set to false to stop execution if the flow hook throws an exception. Defaults to true.`, }, }, From ff82a533b8ffa2ea6154476eed979df1bf3af37e Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 6 Mar 2023 14:01:59 -0800 Subject: [PATCH 40/41] Update apigee_flowhook.html.markdown updated `description` and `continue_on_error` as optional --- .../terraform/website/docs/r/apigee_flowhook.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown b/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown index 9ba45000a083..380a65ed82fe 100644 --- a/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/apigee_flowhook.html.markdown @@ -33,7 +33,7 @@ The following arguments are supported: Where in the API call flow the flow hook is invoked. Must be one of PreProxyFlowHook, PostProxyFlowHook, PreTargetFlowHook, or PostTargetFlowHook. * `description` - - (Required) + (Optional) Description of the flow hook. * `sharedflow` - @@ -41,7 +41,7 @@ The following arguments are supported: Id of the Sharedflow attaching to a flowhook point. * `continue_on_error` - - (Required) + (Optional) Flag that specifies whether execution should continue if the flow hook throws an exception. Set to true to continue execution. Set to false to stop execution if the flow hook throws an exception. Defaults to true. From 0acefe3fb3d771abac1ca9677c262b3d55a3803c Mon Sep 17 00:00:00 2001 From: Ray Xu Date: Tue, 7 Mar 2023 22:24:09 +0000 Subject: [PATCH 41/41] update referenced function naming case --- .../resources/resource_apigee_flowhook.go | 12 ++++++------ .../resources/resource_apigee_sharedflow.go | 15 +++++++-------- .../resource_apigee_sharedflow_deployment.go | 12 ++++++------ .../tests/resource_apigee_flowhook_test.go | 16 ++++++++-------- ...source_apigee_sharedflow_deployment_test.go | 16 ++++++++-------- .../resource_apigee_sharedflow_sweeper_test.go | 10 +++++----- .../tests/resource_apigee_sharedflow_test.go | 18 +++++++++--------- 7 files changed, 49 insertions(+), 50 deletions(-) diff --git a/mmv1/third_party/terraform/resources/resource_apigee_flowhook.go b/mmv1/third_party/terraform/resources/resource_apigee_flowhook.go index 003126eb0793..689e000210d3 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_flowhook.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_flowhook.go @@ -69,7 +69,7 @@ func ResourceApigeeFlowhook() *schema.Resource { func resourceApigeeFlowhookCreate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - userAgent, err := generateUserAgentString(d, config.userAgent) + userAgent, err := generateUserAgentString(d, config.UserAgent) if err != nil { return err } @@ -107,7 +107,7 @@ func resourceApigeeFlowhookCreate(d *schema.ResourceData, meta interface{}) erro billingProject = bp } - res, err := sendRequestWithTimeout(config, "PUT", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutCreate)) + res, err := SendRequestWithTimeout(config, "PUT", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutCreate)) if err != nil { return fmt.Errorf("Error creating Flowhook: %s", err) } @@ -126,7 +126,7 @@ func resourceApigeeFlowhookCreate(d *schema.ResourceData, meta interface{}) erro func resourceApigeeFlowhookRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - userAgent, err := generateUserAgentString(d, config.userAgent) + userAgent, err := generateUserAgentString(d, config.UserAgent) if err != nil { return err } @@ -143,7 +143,7 @@ func resourceApigeeFlowhookRead(d *schema.ResourceData, meta interface{}) error billingProject = bp } - res, err := sendRequest(config, "GET", billingProject, url, userAgent, nil) + res, err := SendRequest(config, "GET", billingProject, url, userAgent, nil) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("ApigeeFlowhook %q", d.Id())) } @@ -167,7 +167,7 @@ func resourceApigeeFlowhookRead(d *schema.ResourceData, meta interface{}) error func resourceApigeeFlowhookDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - userAgent, err := generateUserAgentString(d, config.userAgent) + userAgent, err := generateUserAgentString(d, config.UserAgent) if err != nil { return err } @@ -187,7 +187,7 @@ func resourceApigeeFlowhookDelete(d *schema.ResourceData, meta interface{}) erro billingProject = bp } - res, err := sendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete)) + res, err := SendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete)) if err != nil { return handleNotFoundError(err, d, "Flowhook") } diff --git a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go index 290a68855c9d..e0c136552d0f 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow.go @@ -151,7 +151,7 @@ func resourceApigeeSharedFlowCreate(d *schema.ResourceData, meta interface{}) er log.Printf("[DEBUG] resourceApigeeSharedFlowCreate, config_bundle=, %s", d.Get("config_bundle").(string)) config := meta.(*Config) - userAgent, err := generateUserAgentString(d, config.userAgent) + userAgent, err := generateUserAgentString(d, config.UserAgent) if err != nil { return err } @@ -213,7 +213,7 @@ func resourceApigeeSharedFlowUpdate(d *schema.ResourceData, meta interface{}) er func resourceApigeeSharedFlowRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - userAgent, err := generateUserAgentString(d, config.userAgent) + userAgent, err := generateUserAgentString(d, config.UserAgent) if err != nil { return err } @@ -232,7 +232,7 @@ func resourceApigeeSharedFlowRead(d *schema.ResourceData, meta interface{}) erro } log.Printf("[DEBUG] resourceApigeeSharedFlowRead sendRequest") log.Printf("[DEBUG] resourceApigeeSharedFlowRead, url=, %s", url) - res, err := sendRequest(config, "GET", billingProject, url, userAgent, nil) + res, err := SendRequest(config, "GET", billingProject, url, userAgent, nil) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("ApigeeSharedFlow %q", d.Id())) } @@ -254,7 +254,6 @@ func resourceApigeeSharedFlowRead(d *schema.ResourceData, meta interface{}) erro //setting hash to suggest update if previousLastModifiedAt != currentLastModifiedAt { - log.Printf("yoyo LastModifiedAt previous: %s, current: %s", previousLastModifiedAt, currentLastModifiedAt) d.Set("md5hash", "UNKNOWN") d.Set("detect_md5hash", "UNKNOWN") } @@ -282,7 +281,7 @@ func getApigeeSharedFlowLastModifiedAt(d *schema.ResourceData) string { func resourceApigeeSharedFlowDelete(d *schema.ResourceData, meta interface{}) error { log.Printf("[DEBUG] resourceApigeeSharedFlowDelete") config := meta.(*Config) - userAgent, err := generateUserAgentString(d, config.userAgent) + userAgent, err := generateUserAgentString(d, config.UserAgent) if err != nil { return err } @@ -302,7 +301,7 @@ func resourceApigeeSharedFlowDelete(d *schema.ResourceData, meta interface{}) er billingProject = bp } - res, err := sendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete)) + res, err := SendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete)) if err != nil { return handleNotFoundError(err, d, "SharedFlow") } @@ -398,7 +397,7 @@ func sendRequestRawBodyWithTimeout(config *Config, method, project, rawurl, user log.Printf("[DEBUG] sendRequestRawBodyWithTimeout sending request") - err := retryTimeDuration( + err := RetryTimeDuration( func() error { req, err := http.NewRequest(method, rawurl, body) if err != nil { @@ -406,7 +405,7 @@ func sendRequestRawBodyWithTimeout(config *Config, method, project, rawurl, user } req.Header = reqHeaders - res, err = config.client.Do(req) + res, err = config.Client.Do(req) if err != nil { return err } diff --git a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow_deployment.go b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow_deployment.go index 71e8febc1e7f..6c1124637260 100644 --- a/mmv1/third_party/terraform/resources/resource_apigee_sharedflow_deployment.go +++ b/mmv1/third_party/terraform/resources/resource_apigee_sharedflow_deployment.go @@ -62,7 +62,7 @@ func ResourceApigeeSharedFlowDeployment() *schema.Resource { func resourceApigeeSharedflowDeploymentCreate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - userAgent, err := generateUserAgentString(d, config.userAgent) + userAgent, err := generateUserAgentString(d, config.UserAgent) if err != nil { return err } @@ -80,7 +80,7 @@ func resourceApigeeSharedflowDeploymentCreate(d *schema.ResourceData, meta inter billingProject = bp } - res, err := sendRequestWithTimeout(config, "POST", billingProject, url, userAgent, nil, d.Timeout(schema.TimeoutCreate)) + res, err := SendRequestWithTimeout(config, "POST", billingProject, url, userAgent, nil, d.Timeout(schema.TimeoutCreate)) if err != nil { return fmt.Errorf("Error creating SharedflowDeployment: %s", err) } @@ -99,7 +99,7 @@ func resourceApigeeSharedflowDeploymentCreate(d *schema.ResourceData, meta inter func resourceApigeeSharedflowDeploymentRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - userAgent, err := generateUserAgentString(d, config.userAgent) + userAgent, err := generateUserAgentString(d, config.UserAgent) if err != nil { return err } @@ -118,7 +118,7 @@ func resourceApigeeSharedflowDeploymentRead(d *schema.ResourceData, meta interfa log.Printf("[DEBUG] Reading SharedflowDeployment at %s", url) - res, err := sendRequest(config, "GET", billingProject, url, userAgent, nil) + res, err := SendRequest(config, "GET", billingProject, url, userAgent, nil) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("ApigeeSharedflowDeployment %q", d.Id())) } @@ -129,7 +129,7 @@ func resourceApigeeSharedflowDeploymentRead(d *schema.ResourceData, meta interfa func resourceApigeeSharedflowDeploymentDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - userAgent, err := generateUserAgentString(d, config.userAgent) + userAgent, err := generateUserAgentString(d, config.UserAgent) if err != nil { return err } @@ -149,7 +149,7 @@ func resourceApigeeSharedflowDeploymentDelete(d *schema.ResourceData, meta inter billingProject = bp } - res, err := sendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete)) + res, err := SendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete)) if err != nil { return handleNotFoundError(err, d, "SharedflowDeployment") } diff --git a/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go b/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go index e86c5e583c05..93ab7c2f7437 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_flowhook_test.go @@ -10,18 +10,18 @@ import ( ) func TestAccApigeeFlowhook_apigeeFlowhookTestExample(t *testing.T) { - skipIfVcr(t) + SkipIfVcr(t) t.Parallel() context := map[string]interface{}{ - "org_id": getTestOrgFromEnv(t), - "billing_account": getTestBillingAccountFromEnv(t), - "random_suffix": randString(t, 10), + "org_id": GetTestOrgFromEnv(t), + "billing_account": GetTestBillingAccountFromEnv(t), + "random_suffix": RandString(t, 10), } - vcrTest(t, resource.TestCase{ + VcrTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + Providers: TestAccProviders, CheckDestroy: testAccCheckApigeeFlowhookDestroyProducer(t), Steps: []resource.TestStep{ { @@ -137,7 +137,7 @@ func testAccCheckApigeeFlowhookDestroyProducer(t *testing.T) func(s *terraform.S continue } - config := googleProviderConfig(t) + config := GoogleProviderConfig(t) url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}") if err != nil { @@ -149,7 +149,7 @@ func testAccCheckApigeeFlowhookDestroyProducer(t *testing.T) func(s *terraform.S if config.BillingProject != "" { billingProject = config.BillingProject } - res, err := sendRequest(config, "GET", billingProject, url, config.userAgent, nil) + res, err := SendRequest(config, "GET", billingProject, url, config.UserAgent, nil) // Flowhooks always exist, we treat the binding as a removable resource, thus we check if the sharedFlow field to detect sharedflow attachment if err == nil && res != nil && res["sharedFlow"] != nil { return fmt.Errorf("Flowhook still has an attachment at %s", url) diff --git a/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go index bd194dc94a12..57f456e93dc0 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_deployment_test.go @@ -10,18 +10,18 @@ import ( ) func TestAccApigeeSharedflowDeployment_apigeeSharedflowDeploymentTestExample(t *testing.T) { - skipIfVcr(t) + SkipIfVcr(t) t.Parallel() context := map[string]interface{}{ - "org_id": getTestOrgFromEnv(t), - "billing_account": getTestBillingAccountFromEnv(t), - "random_suffix": randString(t, 10), + "org_id": GetTestOrgFromEnv(t), + "billing_account": GetTestBillingAccountFromEnv(t), + "random_suffix": RandString(t, 10), } - vcrTest(t, resource.TestCase{ + VcrTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + Providers: TestAccProviders, CheckDestroy: testAccCheckApigeeSharedflowDeploymentDestroyProducer(t), Steps: []resource.TestStep{ { @@ -128,7 +128,7 @@ func testAccCheckApigeeSharedflowDeploymentDestroyProducer(t *testing.T) func(s continue } - config := googleProviderConfig(t) + config := GoogleProviderConfig(t) url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/sharedflows/{{sharedflow_id}}/revisions/{{revision}}/deployments") if err != nil { @@ -140,7 +140,7 @@ func testAccCheckApigeeSharedflowDeploymentDestroyProducer(t *testing.T) func(s if config.BillingProject != "" { billingProject = config.BillingProject } - _, err = sendRequest(config, "GET", billingProject, url, config.userAgent, nil) + _, err = SendRequest(config, "GET", billingProject, url, config.UserAgent, nil) if err == nil { return fmt.Errorf("ApigeeSharedFlow still exists at %s", url) } diff --git a/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_sweeper_test.go b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_sweeper_test.go index f95d8af7df0c..9cd60acc221b 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_sweeper_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_sweeper_test.go @@ -35,7 +35,7 @@ func testSweepApigeeSharedFlow(region string) error { resourceName := "ApigeeSharedFlow" log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) - config, err := sharedConfigForRegion(region) + config, err := SharedConfigForRegion(region) if err != nil { log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) return err @@ -48,7 +48,7 @@ func testSweepApigeeSharedFlow(region string) error { } t := &testing.T{} - billingId := getTestBillingAccountFromEnv(t) + billingId := GetTestBillingAccountFromEnv(t) // Setup variables to replace in list template d := &ResourceDataMock{ @@ -68,7 +68,7 @@ func testSweepApigeeSharedFlow(region string) error { return nil } - res, err := sendRequest(config, "GET", config.Project, listUrl, config.userAgent, nil) + res, err := SendRequest(config, "GET", config.Project, listUrl, config.UserAgent, nil) if err != nil { log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) return nil @@ -98,7 +98,7 @@ func testSweepApigeeSharedFlow(region string) error { return nil } // Skip resources that shouldn't be sweeped - if !isSweepableTestResource(name) { + if !IsSweepableTestResource(name) { nonPrefixCount++ continue } @@ -112,7 +112,7 @@ func testSweepApigeeSharedFlow(region string) error { deleteUrl = deleteUrl + name // Don't wait on operations as we may have a lot to delete - _, err = sendRequest(config, "DELETE", config.Project, deleteUrl, config.userAgent, nil) + _, err = SendRequest(config, "DELETE", config.Project, deleteUrl, config.UserAgent, nil) if err != nil { log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) } else { diff --git a/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_test.go b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_test.go index 9c36f78a7cb0..bfd31ebbfb47 100644 --- a/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_test.go +++ b/mmv1/third_party/terraform/tests/resource_apigee_sharedflow_test.go @@ -10,20 +10,20 @@ import ( ) func TestAccApigeeSharedFlow_apigeeSharedflowTestExample(t *testing.T) { - skipIfVcr(t) + SkipIfVcr(t) t.Parallel() - fmt.Printf("from t: org_id %s", getTestOrgFromEnv(t)) + fmt.Printf("from t: org_id %s", GetTestOrgFromEnv(t)) context := map[string]interface{}{ - "org_id": getTestOrgFromEnv(t), - "billing_account": getTestBillingAccountFromEnv(t), - "random_suffix": randString(t, 10), + "org_id": GetTestOrgFromEnv(t), + "billing_account": GetTestBillingAccountFromEnv(t), + "random_suffix": RandString(t, 10), } - vcrTest(t, resource.TestCase{ + VcrTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + Providers: TestAccProviders, CheckDestroy: testAccCheckApigeeSharedFlowDestroyProducer(t), Steps: []resource.TestStep{ { @@ -125,7 +125,7 @@ func testAccCheckApigeeSharedFlowDestroyProducer(t *testing.T) func(s *terraform continue } - config := googleProviderConfig(t) + config := GoogleProviderConfig(t) url, err := replaceVarsForTest(config, rs, "{{ApigeeBasePath}}organizations/{{org_id}}/sharedflows/{{name}}") if err != nil { @@ -138,7 +138,7 @@ func testAccCheckApigeeSharedFlowDestroyProducer(t *testing.T) func(s *terraform billingProject = config.BillingProject } fmt.Printf("testAccCheckApigeeSharedFlowDestroyProducer, url %s", url) - _, err = sendRequest(config, "GET", billingProject, url, config.userAgent, nil) + _, err = SendRequest(config, "GET", billingProject, url, config.UserAgent, nil) if err == nil { return fmt.Errorf("ApigeeSharedFlow still exists at %s", url) }