diff --git a/docs/data-sources/folder.md b/docs/data-sources/folder.md index 0a2eac7..ad7940f 100644 --- a/docs/data-sources/folder.md +++ b/docs/data-sources/folder.md @@ -26,4 +26,5 @@ In addition to all arguments above, the following attributes are exported: * `id` - The full canonical folder path, E.G. `/job/parent`. * `description` - A block of text describing the folder's purpose. +* `display_name` - The name of the folder that is displayed in the UI. * `template` - A Jenkins-compatible XML template to describe the folder. diff --git a/docs/resources/folder.md b/docs/resources/folder.md index 4e3204d..89c528d 100644 --- a/docs/resources/folder.md +++ b/docs/resources/folder.md @@ -33,6 +33,7 @@ resource "jenkins_folder" "example_child" { The following arguments are supported: * `name` - (Required) The name of the folder being created. +* `display_name` - (Optional) The name of the folder to be displayed in the UI. * `folder` - (Optional) The folder namespace to store the subfolder in. If creating in a nested folder structure you may separate folder names with `/`, such as `parent/child`. This name cannot be changed once the folder has been created, and all parent folders must be created in advance. * `description` - (Optional) A block of text describing the folder's purpose. * `security` - (Optional) An optional block defining a project-based authorization strategy, documented below. diff --git a/jenkins/data_source_jenkins_folder.go b/jenkins/data_source_jenkins_folder.go index b7b2054..994131f 100644 --- a/jenkins/data_source_jenkins_folder.go +++ b/jenkins/data_source_jenkins_folder.go @@ -17,6 +17,11 @@ func dataSourceJenkinsFolder() *schema.Resource { Required: true, ValidateDiagFunc: validateJobName, }, + "display_name": { + Type: schema.TypeString, + Description: "The name of the folder to display in the UI.", + Computed: true, + }, "folder": { Type: schema.TypeString, Description: "The folder namespace that the folder exists in.", diff --git a/jenkins/data_source_jenkins_folder_test.go b/jenkins/data_source_jenkins_folder_test.go index fa615fc..20ddc18 100644 --- a/jenkins/data_source_jenkins_folder_test.go +++ b/jenkins/data_source_jenkins_folder_test.go @@ -19,17 +19,19 @@ func TestAccJenkinsFolderDataSource_basic(t *testing.T) { Config: fmt.Sprintf(` resource jenkins_folder foo { name = "tf-acc-test-%s" + display_name = "TF Acceptance Test %s" description = "Terraform acceptance tests %s" } data jenkins_folder foo { name = jenkins_folder.foo.name - }`, randString, randString), + }`, randString, randString, randString), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("jenkins_folder.foo", "id", "/job/tf-acc-test-"+randString), resource.TestCheckResourceAttr("data.jenkins_folder.foo", "id", "/job/tf-acc-test-"+randString), resource.TestCheckResourceAttr("data.jenkins_folder.foo", "name", "tf-acc-test-"+randString), resource.TestCheckResourceAttr("data.jenkins_folder.foo", "description", "Terraform acceptance tests "+randString), + resource.TestCheckResourceAttr("data.jenkins_folder.foo", "display_name", "TF Acceptance Test "+randString), ), }, }, @@ -51,6 +53,7 @@ func TestAccJenkinsFolderDataSource_nested(t *testing.T) { resource jenkins_folder sub { name = "subfolder" + display_name = "TF Acceptance Test %s" folder = jenkins_folder.foo.id description = "Terraform acceptance tests %s" } @@ -58,13 +61,14 @@ func TestAccJenkinsFolderDataSource_nested(t *testing.T) { data jenkins_folder sub { name = jenkins_folder.sub.name folder = jenkins_folder.sub.folder - }`, randString, randString), + }`, randString, randString, randString), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("jenkins_folder.foo", "id", "/job/tf-acc-test-"+randString), resource.TestCheckResourceAttr("jenkins_folder.sub", "id", "/job/tf-acc-test-"+randString+"/job/subfolder"), resource.TestCheckResourceAttr("data.jenkins_folder.sub", "name", "subfolder"), resource.TestCheckResourceAttr("data.jenkins_folder.sub", "folder", "/job/tf-acc-test-"+randString), resource.TestCheckResourceAttr("data.jenkins_folder.sub", "description", "Terraform acceptance tests "+randString), + resource.TestCheckResourceAttr("data.jenkins_folder.sub", "display_name", "TF Acceptance Test "+randString), ), }, }, diff --git a/jenkins/folder.go b/jenkins/folder.go index bf970b0..1e67313 100644 --- a/jenkins/folder.go +++ b/jenkins/folder.go @@ -9,6 +9,7 @@ import ( type folder struct { XMLName xml.Name `xml:"com.cloudbees.hudson.plugins.folder.Folder"` Description string `xml:"description"` + DisplayName string `xml:"displayName,omitempty"` Properties folderProperties `xml:"properties"` FolderViews xmlRawProperty `xml:"folderViews"` HealthMetrics xmlRawProperty `xml:"healthMetrics"` diff --git a/jenkins/folder_test.go b/jenkins/folder_test.go index 1a21000..2280f3b 100644 --- a/jenkins/folder_test.go +++ b/jenkins/folder_test.go @@ -23,6 +23,7 @@ func Test_parseFolder(t *testing.T) { def: ` Example Description + Example Display Name @@ -87,6 +88,7 @@ func Test_parseFolder(t *testing.T) { want: &folder{ XMLName: xml.Name{Local: "com.cloudbees.hudson.plugins.folder.Folder"}, Description: "Example Description", + DisplayName: "Example Display Name", Properties: folderProperties{ Security: &folderSecurity{ InheritanceStrategy: folderPermissionInheritanceStrategy{ @@ -190,6 +192,7 @@ func Test_parseFolder(t *testing.T) { func Test_folder_Render(t *testing.T) { type fields struct { Description string + DisplayName string Properties folderProperties } tests := []struct { @@ -202,6 +205,7 @@ func Test_folder_Render(t *testing.T) { name: "success", fields: fields{ Description: "Example Description", + DisplayName: "Example Display Name", Properties: folderProperties{ Security: &folderSecurity{ Permission: []string{"example", "permission"}, @@ -229,6 +233,7 @@ func Test_folder_Render(t *testing.T) { }, want: []byte(` Example Description + Example Display Name @@ -255,6 +260,7 @@ func Test_folder_Render(t *testing.T) { t.Run(tt.name, func(t *testing.T) { j := &folder{ Description: tt.fields.Description, + DisplayName: tt.fields.DisplayName, Properties: tt.fields.Properties, } got, err := j.Render() diff --git a/jenkins/resource_jenkins_folder.go b/jenkins/resource_jenkins_folder.go index 6fc3a7f..966d131 100644 --- a/jenkins/resource_jenkins_folder.go +++ b/jenkins/resource_jenkins_folder.go @@ -27,6 +27,11 @@ func resourceJenkinsFolder() *schema.Resource { ForceNew: true, ValidateDiagFunc: validateJobName, }, + "display_name": { + Type: schema.TypeString, + Description: "The name of the folder to display in the UI.", + Optional: true, + }, "folder": { Type: schema.TypeString, Description: "The folder namespace that the folder will be added to as a subfolder.", @@ -83,6 +88,7 @@ func resourceJenkinsFolderCreate(ctx context.Context, d *schema.ResourceData, me f := folder{ Description: d.Get("description").(string), + DisplayName: d.Get("display_name").(string), } f.Properties.Security = expandSecurity(d.Get("security").(*schema.Set).List()) @@ -143,6 +149,10 @@ func resourceJenkinsFolderRead(ctx context.Context, d *schema.ResourceData, meta return diag.FromErr(err) } + if err := d.Set("display_name", f.DisplayName); err != nil { + return diag.FromErr(err) + } + if err := d.Set("folder", formatFolderID(folders)); err != nil { return diag.FromErr(err) } @@ -182,6 +192,7 @@ func resourceJenkinsFolderUpdate(ctx context.Context, d *schema.ResourceData, me // Then update the values f.Description = d.Get("description").(string) + f.DisplayName = d.Get("display_name").(string) f.Properties.Security = expandSecurity(d.Get("security").(*schema.Set).List()) // And send it back to Jenkins diff --git a/jenkins/resource_jenkins_folder_test.go b/jenkins/resource_jenkins_folder_test.go index f208b81..07fbbca 100644 --- a/jenkins/resource_jenkins_folder_test.go +++ b/jenkins/resource_jenkins_folder_test.go @@ -27,6 +27,32 @@ func TestAccJenkinsFolder_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("jenkins_folder.foo", "id", "/job/tf-acc-test-"+randString), resource.TestCheckResourceAttr("jenkins_folder.foo", "name", "tf-acc-test-"+randString), + resource.TestCheckResourceAttr("jenkins_folder.foo", "display_name", ""), + ), + }, + }, + }) +} + +func TestAccJenkinsFolder_withDisplayName(t *testing.T) { + randString := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckJenkinsFolderDestroy, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(` + resource jenkins_folder foo { + name = "tf-acc-test-%s" + display_name = "TF Acceptance Test %s" + description = "Terraform acceptance tests %s" + }`, randString, randString, randString), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("jenkins_folder.foo", "id", "/job/tf-acc-test-"+randString), + resource.TestCheckResourceAttr("jenkins_folder.foo", "name", "tf-acc-test-"+randString), + resource.TestCheckResourceAttr("jenkins_folder.foo", "display_name", "TF Acceptance Test "+randString), ), }, }, @@ -50,15 +76,17 @@ func TestAccJenkinsFolder_nested(t *testing.T) { resource jenkins_folder sub { name = "subfolder" + display_name = "TF Acceptance Test %s" folder = jenkins_folder.foo.id description = "Terraform acceptance tests ${jenkins_folder.foo.name}" - }`, randString, randString), + }`, randString, randString, randString), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("jenkins_folder.foo", "id", "/job/tf-acc-test-"+randString), resource.TestCheckResourceAttr("jenkins_folder.foo", "name", "tf-acc-test-"+randString), resource.TestCheckResourceAttr("jenkins_folder.sub", "id", "/job/tf-acc-test-"+randString+"/job/subfolder"), resource.TestCheckResourceAttr("jenkins_folder.sub", "name", "subfolder"), resource.TestCheckResourceAttr("jenkins_folder.sub", "folder", "/job/tf-acc-test-"+randString), + resource.TestCheckResourceAttr("jenkins_folder.sub", "display_name", "TF Acceptance Test "+randString), ), }, },