diff --git a/.changelog/4383.txt b/.changelog/4383.txt new file mode 100644 index 00000000000..b395b5efc10 --- /dev/null +++ b/.changelog/4383.txt @@ -0,0 +1,3 @@ +```release-note:bug +project: fixed a bug in `google_project_access_approval_settings` where the default `project` was used rather than `project_id` +``` diff --git a/google/resource_access_approval_project_settings.go b/google/resource_access_approval_project_settings.go index 655462839a4..0f9d3efecf0 100644 --- a/google/resource_access_approval_project_settings.go +++ b/google/resource_access_approval_project_settings.go @@ -73,6 +73,12 @@ resources of that resource. A maximum of 50 email addresses are allowed.`, }, Set: schema.HashString, }, + "project": { + Type: schema.TypeString, + Optional: true, + Deprecated: "Deprecated in favor of `project_id`", + Description: `Deprecated in favor of 'project_id'`, + }, "enrolled_ancestor": { Type: schema.TypeBool, Computed: true, @@ -81,13 +87,7 @@ resources of that resource. A maximum of 50 email addresses are allowed.`, "name": { Type: schema.TypeString, Computed: true, - Description: `The resource name of the settings. Format is "projects/{project_id/accessApprovalSettings"`, - }, - "project": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, + Description: `The resource name of the settings. Format is "projects/{project_id}/accessApprovalSettings"`, }, }, UseJSONNumber: true, @@ -143,8 +143,14 @@ func resourceAccessApprovalProjectSettingsCreate(d *schema.ResourceData, meta in } else if v, ok := d.GetOkExists("enrolled_services"); !isEmptyValue(reflect.ValueOf(enrolledServicesProp)) && (ok || !reflect.DeepEqual(v, enrolledServicesProp)) { obj["enrolledServices"] = enrolledServicesProp } + projectProp, err := expandAccessApprovalProjectSettingsProject(d.Get("project"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("project"); !isEmptyValue(reflect.ValueOf(projectProp)) && (ok || !reflect.DeepEqual(v, projectProp)) { + obj["project"] = projectProp + } - url, err := replaceVars(d, config, "{{AccessApprovalBasePath}}projects/{{project}}/accessApprovalSettings") + url, err := replaceVars(d, config, "{{AccessApprovalBasePath}}projects/{{project_id}}/accessApprovalSettings") if err != nil { return err } @@ -152,12 +158,6 @@ func resourceAccessApprovalProjectSettingsCreate(d *schema.ResourceData, meta in log.Printf("[DEBUG] Creating new ProjectSettings: %#v", obj) billingProject := "" - project, err := getProject(d, config) - if err != nil { - return fmt.Errorf("Error fetching project for ProjectSettings: %s", err) - } - billingProject = project - // err == nil indicates that the billing_project value was found if bp, err := getBillingProject(d, config); err == nil { billingProject = bp @@ -172,6 +172,10 @@ func resourceAccessApprovalProjectSettingsCreate(d *schema.ResourceData, meta in if d.HasChange("enrolled_services") { updateMask = append(updateMask, "enrolledServices") } + + if d.HasChange("project") { + updateMask = append(updateMask, "project") + } // updateMask is a URL parameter but not present in the schema, so replaceVars // won't set it url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -187,7 +191,7 @@ func resourceAccessApprovalProjectSettingsCreate(d *schema.ResourceData, meta in } // Store the ID now - id, err := replaceVars(d, config, "projects/{{project}}/accessApprovalSettings") + id, err := replaceVars(d, config, "projects/{{project_id}}/accessApprovalSettings") if err != nil { return fmt.Errorf("Error constructing id: %s", err) } @@ -205,19 +209,13 @@ func resourceAccessApprovalProjectSettingsRead(d *schema.ResourceData, meta inte return err } - url, err := replaceVars(d, config, "{{AccessApprovalBasePath}}projects/{{project}}/accessApprovalSettings") + url, err := replaceVars(d, config, "{{AccessApprovalBasePath}}projects/{{project_id}}/accessApprovalSettings") if err != nil { return err } billingProject := "" - project, err := getProject(d, config) - if err != nil { - return fmt.Errorf("Error fetching project for ProjectSettings: %s", err) - } - billingProject = project - // err == nil indicates that the billing_project value was found if bp, err := getBillingProject(d, config); err == nil { billingProject = bp @@ -228,10 +226,6 @@ func resourceAccessApprovalProjectSettingsRead(d *schema.ResourceData, meta inte return handleNotFoundError(err, d, fmt.Sprintf("AccessApprovalProjectSettings %q", d.Id())) } - if err := d.Set("project", project); err != nil { - return fmt.Errorf("Error reading ProjectSettings: %s", err) - } - if err := d.Set("name", flattenAccessApprovalProjectSettingsName(res["name"], d, config)); err != nil { return fmt.Errorf("Error reading ProjectSettings: %s", err) } @@ -244,6 +238,9 @@ func resourceAccessApprovalProjectSettingsRead(d *schema.ResourceData, meta inte if err := d.Set("enrolled_ancestor", flattenAccessApprovalProjectSettingsEnrolledAncestor(res["enrolledAncestor"], d, config)); err != nil { return fmt.Errorf("Error reading ProjectSettings: %s", err) } + if err := d.Set("project", flattenAccessApprovalProjectSettingsProject(res["project"], d, config)); err != nil { + return fmt.Errorf("Error reading ProjectSettings: %s", err) + } return nil } @@ -257,12 +254,6 @@ func resourceAccessApprovalProjectSettingsUpdate(d *schema.ResourceData, meta in billingProject := "" - project, err := getProject(d, config) - if err != nil { - return fmt.Errorf("Error fetching project for ProjectSettings: %s", err) - } - billingProject = project - obj := make(map[string]interface{}) notificationEmailsProp, err := expandAccessApprovalProjectSettingsNotificationEmails(d.Get("notification_emails"), d, config) if err != nil { @@ -276,8 +267,14 @@ func resourceAccessApprovalProjectSettingsUpdate(d *schema.ResourceData, meta in } else if v, ok := d.GetOkExists("enrolled_services"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enrolledServicesProp)) { obj["enrolledServices"] = enrolledServicesProp } + projectProp, err := expandAccessApprovalProjectSettingsProject(d.Get("project"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("project"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, projectProp)) { + obj["project"] = projectProp + } - url, err := replaceVars(d, config, "{{AccessApprovalBasePath}}projects/{{project}}/accessApprovalSettings") + url, err := replaceVars(d, config, "{{AccessApprovalBasePath}}projects/{{project_id}}/accessApprovalSettings") if err != nil { return err } @@ -292,6 +289,10 @@ func resourceAccessApprovalProjectSettingsUpdate(d *schema.ResourceData, meta in if d.HasChange("enrolled_services") { updateMask = append(updateMask, "enrolledServices") } + + if d.HasChange("project") { + updateMask = append(updateMask, "project") + } // updateMask is a URL parameter but not present in the schema, so replaceVars // won't set it url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -326,7 +327,7 @@ func resourceAccessApprovalProjectSettingsDelete(d *schema.ResourceData, meta in obj["notificationEmails"] = []string{} obj["enrolledServices"] = []string{} - url, err := replaceVars(d, config, "{{AccessApprovalBasePath}}projects/{{project}}/accessApprovalSettings") + url, err := replaceVars(d, config, "{{AccessApprovalBasePath}}projects/{{project_id}}/accessApprovalSettings") if err != nil { return err } @@ -358,14 +359,14 @@ func resourceAccessApprovalProjectSettingsDelete(d *schema.ResourceData, meta in func resourceAccessApprovalProjectSettingsImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { config := meta.(*Config) if err := parseImportId([]string{ - "projects/(?P[^/]+)/accessApprovalSettings", - "(?P[^/]+)", + "projects/(?P[^/]+)/accessApprovalSettings", + "(?P[^/]+)", }, d, config); err != nil { return nil, err } // Replace import id for the resource id - id, err := replaceVars(d, config, "projects/{{project}}/accessApprovalSettings") + id, err := replaceVars(d, config, "projects/{{project_id}}/accessApprovalSettings") if err != nil { return nil, fmt.Errorf("Error constructing id: %s", err) } @@ -416,6 +417,10 @@ func flattenAccessApprovalProjectSettingsEnrolledAncestor(v interface{}, d *sche return v } +func flattenAccessApprovalProjectSettingsProject(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + func expandAccessApprovalProjectSettingsNotificationEmails(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { v = v.(*schema.Set).List() return v, nil @@ -458,3 +463,7 @@ func expandAccessApprovalProjectSettingsEnrolledServicesCloudProduct(v interface func expandAccessApprovalProjectSettingsEnrolledServicesEnrollmentLevel(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } + +func expandAccessApprovalProjectSettingsProject(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/website/docs/r/access_approval_project_settings.html.markdown b/website/docs/r/access_approval_project_settings.html.markdown index f93ab4ed4e6..e6073345217 100644 --- a/website/docs/r/access_approval_project_settings.html.markdown +++ b/website/docs/r/access_approval_project_settings.html.markdown @@ -93,18 +93,19 @@ The `enrolled_services` block supports: Notifications relating to a resource will be sent to all emails in the settings of ancestor resources of that resource. A maximum of 50 email addresses are allowed. -* `project` - (Optional) The ID of the project in which the resource belongs. - If it is not provided, the provider project is used. +* `project` - + (Optional, Deprecated) + Deprecated in favor of `project_id` ## Attributes Reference In addition to the arguments listed above, the following computed attributes are exported: -* `id` - an identifier for the resource with format `projects/{{project}}/accessApprovalSettings` +* `id` - an identifier for the resource with format `projects/{{project_id}}/accessApprovalSettings` * `name` - - The resource name of the settings. Format is "projects/{project_id/accessApprovalSettings" + The resource name of the settings. Format is "projects/{project_id}/accessApprovalSettings" * `enrolled_ancestor` - If the field is true, that indicates that at least one service is enrolled for Access Approval in one or more ancestors of the Project. @@ -125,10 +126,6 @@ This resource provides the following ProjectSettings can be imported using any of these accepted formats: ``` -$ terraform import google_project_access_approval_settings.default projects/{{project}}/accessApprovalSettings -$ terraform import google_project_access_approval_settings.default {{project}} +$ terraform import google_project_access_approval_settings.default projects/{{project_id}}/accessApprovalSettings +$ terraform import google_project_access_approval_settings.default {{project_id}} ``` - -## User Project Overrides - -This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override).