This is an automated email from the ASF dual-hosted git repository. sudo87 pushed a commit to branch fix/storage-range-import-project-displaytext in repository https://gitbox.apache.org/repos/asf/cloudstack-terraform-provider.git
commit 992f58ea1c7cf97992b5c0fbcb3ab4d75e521dee Author: Manoj Kumar <[email protected]> AuthorDate: Fri Aug 28 15:59:07 2026 +0530 Add snake_case display_text field to cloudstack_project, deprecate displaytext Every other resource in this provider uses display_text; cloudstack_project was the outlier still on displaytext, even though its own docs already described display_text as the field name. Add display_text additively (displaytext is a real field in existing users' state files and can't be renamed outright) and mark displaytext Deprecated. Create/Update/Read resolve the effective value via projectDisplayText(), preferring display_text when both are set. Read only refreshes whichever of the two fields is actually in use (config already had displaytext set and display_text unset), matching the existing conditional pattern this file already uses for account/accountid/userid. Setting both unconditionally caused a permanent diff for display_text-only configs, since Read would keep populating the deprecated field the config never referenced. Verified against the lab with two standalone configs (one using display_text, one using the legacy displaytext) against a locally-built dev-override binary: both create cleanly, both produce an empty terraform plan, and the legacy field shows the expected deprecation warning. Both test projects destroyed after verification. --- cloudstack/resource_cloudstack_project.go | 39 +++++++++++++++++++++++++------ website/docs/r/project.html.markdown | 3 +++ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/cloudstack/resource_cloudstack_project.go b/cloudstack/resource_cloudstack_project.go index 9c02846..ea74743 100644 --- a/cloudstack/resource_cloudstack_project.go +++ b/cloudstack/resource_cloudstack_project.go @@ -47,6 +47,12 @@ func resourceCloudStackProject() *schema.Resource { }, "displaytext": { + Type: schema.TypeString, + Optional: true, + Deprecated: "use display_text instead", + }, + + "display_text": { Type: schema.TypeString, Optional: true, }, @@ -76,12 +82,22 @@ func resourceCloudStackProject() *schema.Resource { } } +// projectDisplayText resolves the effective display text from the new +// display_text field and the deprecated displaytext field. display_text +// wins when both are set, since it's the field new configs should use. +func projectDisplayText(d *schema.ResourceData) string { + if v, ok := d.GetOk("display_text"); ok { + return v.(string) + } + return d.Get("displaytext").(string) +} + func resourceCloudStackProjectCreate(d *schema.ResourceData, meta any) error { cs := meta.(*cloudstack.CloudStackClient) // Get the name and displaytext name := d.Get("name").(string) - displaytext := d.Get("displaytext").(string) + displaytext := projectDisplayText(d) // Get domain if provided var domain string @@ -101,7 +117,6 @@ func resourceCloudStackProjectCreate(d *schema.ResourceData, meta any) error { // Set the basic attributes to match the existing project d.Set("name", existingProject.Name) - d.Set("displaytext", existingProject.Displaytext) d.Set("domain", existingProject.Domain) return resourceCloudStackProjectRead(d, meta) @@ -327,9 +342,19 @@ func resourceCloudStackProjectRead(d *schema.ResourceData, meta any) error { // Set the basic attributes d.Set("name", project.Name) - d.Set("displaytext", project.Displaytext) d.Set("domain", project.Domain) + // Only refresh whichever of displaytext (deprecated) / display_text the + // config is actually using, so a config that only sets one of them + // doesn't see a perpetual diff on the other. + _, displaytextOk := d.GetOk("displaytext") + _, displayTextOk := d.GetOk("display_text") + if displaytextOk && !displayTextOk { + d.Set("displaytext", project.Displaytext) + } else { + d.Set("display_text", project.Displaytext) + } + // Handle owner information more safely // Only set the account, accountid, and userid if they were explicitly set in the configuration // and if the owner information is available @@ -397,7 +422,7 @@ func resourceCloudStackProjectUpdate(d *schema.ResourceData, meta any) error { cs := meta.(*cloudstack.CloudStackClient) // Check if the name or displaytext is changed - if d.HasChange("name") || d.HasChange("displaytext") { + if d.HasChange("name") || d.HasChange("displaytext") || d.HasChange("display_text") { // Create a new parameter struct p := cs.Project.NewUpdateProjectParams(d.Id()) @@ -409,8 +434,8 @@ func resourceCloudStackProjectUpdate(d *schema.ResourceData, meta any) error { p.SetName(d.Get("name").(string)) } - if d.HasChange("displaytext") { - p.SetDisplaytext(d.Get("displaytext").(string)) + if d.HasChange("displaytext") || d.HasChange("display_text") { + p.SetDisplaytext(projectDisplayText(d)) } log.Printf("[DEBUG] Updating project %s", d.Id()) @@ -490,7 +515,7 @@ func resourceCloudStackProjectUpdate(d *schema.ResourceData, meta any) error { return retry.RetryableError(fmt.Errorf("project name not updated yet")) } - if d.HasChange("displaytext") && project.Displaytext != d.Get("displaytext").(string) { + if (d.HasChange("displaytext") || d.HasChange("display_text")) && project.Displaytext != projectDisplayText(d) { log.Printf("[DEBUG] Project %s displaytext not updated yet, retrying...", d.Id()) return retry.RetryableError(fmt.Errorf("project displaytext not updated yet")) } diff --git a/website/docs/r/project.html.markdown b/website/docs/r/project.html.markdown index 8e0bfe9..64a61c7 100644 --- a/website/docs/r/project.html.markdown +++ b/website/docs/r/project.html.markdown @@ -37,6 +37,9 @@ The following arguments are supported: * `name` - (Required) The name of the project. * `display_text` - (Required) The display text of the project. Required for API version 4.18 and lower compatibility. This requirement will be removed when support for API versions older than 4.18 is dropped. +* `displaytext` - (Optional, **Deprecated**) Use `display_text` instead. Retained for + backwards compatibility with existing state files; if both `displaytext` and + `display_text` are set, `display_text` takes precedence. * `domain` - (Optional) The domain where the project will be created. This cannot be changed after the project is created. * `account` - (Optional) The account who will be Admin for the project. Requires `domain` to be set. This can be updated after the project is created. * `accountid` - (Optional) The ID of the account owning the project. This can be updated after the project is created.
