Skip to content

Commit

Permalink
Add Namespace attribute for credential_vault_approle (#69)
Browse files Browse the repository at this point in the history
* save

* save

* examples

* examples

* tests for both

* docs, tests

Co-authored-by: Ryan Nixon <r.taiidani@gmail.com>
  • Loading branch information
JVanAartsen and taiidani committed Dec 18, 2021
1 parent aac2fe0 commit 1639d0a
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/data-sources/credential_vault_approle.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ In addition to all arguments above, the following attributes are exported:
* `id` - The full canonical job path, E.G. `/job/job-name`.
* `description` - A human readable description of the credentials being stored.
* `scope` - The visibility of the credentials to Jenkins agents. This must be set to either "GLOBAL" or "SYSTEM".
* `namespace` - The Vault namespace of the approle credential.
* `path` - The unique name of the approle auth backend. Defaults to `approle`.
* `role_id` - The role_id to be associated with the credentials.
1 change: 1 addition & 0 deletions docs/resources/credential_vault_approle.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ The following arguments are supported:
* `folder` - (Optional) The folder namespace to store the credentials in. If not set will default to global Jenkins credentials.
* `scope` - (Optional) The visibility of the credentials to Jenkins agents. This must be set to either "GLOBAL" or "SYSTEM". If not set will default to "GLOBAL".
* `description` - (Optional) A human readable description of the credentials being stored.
* `namespace` - (Optional) The Vault namespace of the approle credential.
* `path` - (Optional) The unique name of the approle auth backend. Defaults to `approle`.
* `role_id` - (Required) The role_id to be associated with the credentials.
* `secret_id` - (Optional) The secret_id to be associated with the credentials. If empty then the secret_id property will become unmanaged and expected to be set manually within Jenkins. If set then the secret_id will be updated only upon changes -- if the secret_id is set manually within Jenkins then it will not reconcile this drift until the next time the secret_id property is changed.
Expand Down
28 changes: 28 additions & 0 deletions example/credentials_vault_approle.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
resource "jenkins_credential_vault_approle" "global" {
name = "global-approle"
role_id = "foo"
secret_id = "bar"
}

resource "jenkins_credential_vault_approle" "folder" {
name = "folder-approle"
folder = jenkins_folder.example.id
role_id = "foo"
secret_id = "bar"
}


resource "jenkins_credential_vault_approle" "global-namespaced" {
name = "global-approle-namespaced"
role_id = "foo"
secret_id = "bar"
namespace = "my-namespace"
}

resource "jenkins_credential_vault_approle" "folder-namespaced" {
name = "folder-approle-namespaced"
folder = jenkins_folder.example.id
role_id = "foo"
secret_id = "bar"
namespace = "my-namespace"
}
5 changes: 5 additions & 0 deletions jenkins/data_source_jenkins_credential_vault_approle.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ func dataSourceJenkinsCredentialVaultAppRole() *schema.Resource {
Description: "The credentials descriptive text.",
Computed: true,
},
"namespace": {
Type: schema.TypeString,
Description: "Namespace of the roles approle backend.",
Optional: true,
},
"path": {
Type: schema.TypeString,
Description: "Path of the roles approle backend.",
Expand Down
75 changes: 75 additions & 0 deletions jenkins/data_source_jenkins_credential_vault_approle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,78 @@ func TestAccJenkinsCredentialVaultAppRoleDataSource_nested(t *testing.T) {
},
})
}

func TestAccJenkinsCredentialVaultAppRoleDataSource_basic_namespaced(t *testing.T) {
randString := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
resource jenkins_credential_vault_approle foo {
name = "tf-acc-test-%s"
description = "Terraform acceptance tests %s"
role_id = "foo"
secret_id = "bar"
namespace = "my-namespace"
}
data jenkins_credential_vault_approle foo {
name = jenkins_credential_vault_approle.foo.name
domain = "_"
}`, randString, randString),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("jenkins_credential_vault_approle.foo", "id", "/tf-acc-test-"+randString),
resource.TestCheckResourceAttr("data.jenkins_credential_vault_approle.foo", "id", "/tf-acc-test-"+randString),
resource.TestCheckResourceAttr("data.jenkins_credential_vault_approle.foo", "name", "tf-acc-test-"+randString),
resource.TestCheckResourceAttr("data.jenkins_credential_vault_approle.foo", "description", "Terraform acceptance tests "+randString),
resource.TestCheckResourceAttr("data.jenkins_credential_vault_approle.foo", "role_id", "foo"),
resource.TestCheckResourceAttr("data.jenkins_credential_vault_approle.foo", "namespace", "my-namespace"),
),
},
},
})
}

func TestAccJenkinsCredentialVaultAppRoleDataSource_nested_namespaced(t *testing.T) {
randString := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
resource jenkins_folder foo {
name = "tf-acc-test-%s"
}
resource jenkins_credential_vault_approle sub {
name = "subfolder"
folder = jenkins_folder.foo.id
description = "Terraform acceptance tests %s"
role_id = "foo"
secret_id = "bar"
namespace = "my-namespace"
}
data jenkins_credential_vault_approle sub {
name = jenkins_credential_vault_approle.sub.name
domain = "_"
folder = jenkins_credential_vault_approle.sub.folder
}`, randString, randString),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("jenkins_folder.foo", "id", "/job/tf-acc-test-"+randString),
resource.TestCheckResourceAttr("jenkins_credential_vault_approle.sub", "id", "/job/tf-acc-test-"+randString+"/subfolder"),
resource.TestCheckResourceAttr("data.jenkins_credential_vault_approle.sub", "name", "subfolder"),
resource.TestCheckResourceAttr("data.jenkins_credential_vault_approle.sub", "folder", "/job/tf-acc-test-"+randString),
resource.TestCheckResourceAttr("data.jenkins_credential_vault_approle.sub", "description", "Terraform acceptance tests "+randString),
resource.TestCheckResourceAttr("data.jenkins_credential_vault_approle.sub", "role_id", "foo"),
resource.TestCheckResourceAttr("data.jenkins_credential_vault_approle.sub", "namespace", "my-namespace"),
),
},
},
})
}
9 changes: 9 additions & 0 deletions jenkins/resource_jenkins_credential_vault_approle.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type VaultAppRoleCredentials struct {
ID string `xml:"id"`
Scope string `xml:"scope"`
Description string `xml:"description"`
Namespace string `xml:"namespace"`
Path string `xml:"path"`
RoleID string `xml:"roleId"`
SecretID string `xml:"secretId"`
Expand Down Expand Up @@ -64,6 +65,11 @@ func resourceJenkinsCredentialVaultAppRole() *schema.Resource {
Optional: true,
Default: "Managed by Terraform",
},
"namespace": {
Type: schema.TypeString,
Description: "Namespace of the roles approle backend.",
Optional: true,
},
"path": {
Type: schema.TypeString,
Description: "Path of the roles approle backend.",
Expand Down Expand Up @@ -99,6 +105,7 @@ func resourceJenkinsCredentialVaultAppRoleCreate(ctx context.Context, d *schema.
ID: d.Get("name").(string),
Scope: d.Get("scope").(string),
Description: d.Get("description").(string),
Namespace: d.Get("namespace").(string),
Path: d.Get("path").(string),
RoleID: d.Get("role_id").(string),
SecretID: d.Get("secret_id").(string),
Expand Down Expand Up @@ -139,6 +146,7 @@ func resourceJenkinsCredentialVaultAppRoleRead(ctx context.Context, d *schema.Re
d.SetId(generateCredentialID(d.Get("folder").(string), cred.ID))
_ = d.Set("scope", cred.Scope)
_ = d.Set("description", cred.Description)
_ = d.Set("namespace", cred.Namespace)
_ = d.Set("path", cred.Path)
_ = d.Set("role_id", cred.RoleID)
// NOTE: We are NOT setting the password here, as the password returned by GetSingle is garbage
Expand All @@ -156,6 +164,7 @@ func resourceJenkinsCredentialVaultAppRoleUpdate(ctx context.Context, d *schema.
ID: d.Get("name").(string),
Scope: d.Get("scope").(string),
Description: d.Get("description").(string),
Namespace: d.Get("namespace").(string),
Path: d.Get("path").(string),
RoleID: d.Get("role_id").(string),
}
Expand Down
124 changes: 124 additions & 0 deletions jenkins/resource_jenkins_credential_vault_approle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,130 @@ func TestAccJenkinsCredentialVaultAppRole_basic(t *testing.T) {
})
}

func TestAccJenkinsCredentialVaultAppRole_basic_namespaced(t *testing.T) {
var cred VaultAppRoleCredentials

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckJenkinsCredentialVaultAppRoleDestroy,
Steps: []resource.TestStep{
{
Config: `
resource jenkins_credential_vault_approle foo {
name = "test-approle"
role_id = "foo"
secret_id = "bar"
namespace = "my-namespace"
}`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("jenkins_credential_vault_approle.foo", "id", "/test-approle"),
testAccCheckJenkinsCredentialVaultAppRoleExists("jenkins_credential_vault_approle.foo", &cred),
),
},
{
// Update by adding description
Config: `
resource jenkins_credential_vault_approle foo {
name = "test-approle"
description = "new-description"
namespace = "my-namespace"
role_id = "foo"
secret_id = "bar"
}`,
Check: resource.ComposeTestCheckFunc(
testAccCheckJenkinsCredentialVaultAppRoleExists("jenkins_credential_vault_approle.foo", &cred),
resource.TestCheckResourceAttr("jenkins_credential_vault_approle.foo", "description", "new-description"),
),
},
},
})
}

func TestAccJenkinsCredentialVaultAppRole_folder_namespaced(t *testing.T) {
var cred VaultAppRoleCredentials
randString := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: resource.ComposeTestCheckFunc(
testAccCheckJenkinsCredentialVaultAppRoleDestroy,
testAccCheckJenkinsFolderDestroy,
),
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
resource jenkins_folder foo {
name = "tf-acc-test-%s"
description = "Terraform acceptance testing"
lifecycle {
ignore_changes = [template]
}
}
resource jenkins_folder foo_sub {
name = "subfolder"
folder = jenkins_folder.foo.id
description = "Terraform acceptance testing"
lifecycle {
ignore_changes = [template]
}
}
resource jenkins_credential_vault_approle foo {
name = "test-approle"
folder = jenkins_folder.foo_sub.id
role_id = "foo"
secret_id = "bar"
namespace = "my-namespace"
}`, randString),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("jenkins_credential_vault_approle.foo", "id", "/job/tf-acc-test-"+randString+"/job/subfolder/test-approle"),
testAccCheckJenkinsCredentialVaultAppRoleExists("jenkins_credential_vault_approle.foo", &cred),
),
},
{
// Update by adding description
Config: fmt.Sprintf(`
resource jenkins_folder foo {
name = "tf-acc-test-%s"
description = "Terraform acceptance testing"
lifecycle {
ignore_changes = [template]
}
}
resource jenkins_folder foo_sub {
name = "subfolder"
folder = jenkins_folder.foo.id
description = "Terraform acceptance testing"
lifecycle {
ignore_changes = [template]
}
}
resource jenkins_credential_vault_approle foo {
name = "test-approle"
folder = jenkins_folder.foo_sub.id
description = "new-description"
role_id = "foo"
secret_id = "bar"
namespace = "my-namespace"
}`, randString),
Check: resource.ComposeTestCheckFunc(
testAccCheckJenkinsCredentialVaultAppRoleExists("jenkins_credential_vault_approle.foo", &cred),
resource.TestCheckResourceAttr("jenkins_credential_vault_approle.foo", "description", "new-description"),
),
},
},
})
}

func TestAccJenkinsCredentialVaultAppRole_folder(t *testing.T) {
var cred VaultAppRoleCredentials
randString := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
Expand Down

0 comments on commit 1639d0a

Please sign in to comment.