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.

Reply via email to