-
Notifications
You must be signed in to change notification settings - Fork 556
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
VAULT-8099 LDAP secrets engine #1859
Conversation
* secrets/ldap: add dynamic role resource * remove unnecessary url usage
* secrets/ldap: add dynamic role resource * remove unnecessary url usage * secrets/ldap: add library set resource * initial acc tests setup with docker compose * add ldap testdata and seed command in docker compose * fix docker compose bootstrap * simplify setup; don't use custom ldif seeding * add docs * add disable_check_in_enforcement field * add user to GH workflow to fix failing CI tests * address review comments * add sidebar content * address review comments
cn: learn | ||
sn: {{.Password | utf16le | base64}} | ||
userPassword: {{.Password}} | ||
EOT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Max asked if there was a better way of handling this data other than HEREDOCs. I think the ldif attribute type "keys" can be custom. In that case, it might be possible to do something like kvv2 data_json
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like it's also possible to send a base64 encoded string as well:
https://developer.hashicorp.com/vault/api-docs/secret/ldap#creation_ldif
Alternatively, the user can create static LDIF files and reference them via the file
function?
https://developer.hashicorp.com/terraform/language/functions/file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, I forgot about the base64 option. I am guessing using an LDIF file will be the most used scenario? In that case, I think we are good as-is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM overall! Just wondering if we should change how we handle creation_ldif, deletion_ldif, and rollback_ldif to be more user friendly?
I'd been working on implementing this myself (closed #1860 in favour of this) and noticed a couple of things that I'd discovered myself during testing.
StateFunc: func (v interface{}) string {
duration, err := time.ParseDuration(v.(string))
if err == nil {
return fmt.Sprintf("%.0f", duration.Seconds())
} else {
return v.(string)
}
} Looks good other than that! |
@bmhughes Hi, thanks for pointing that out! @raymonstah I think the following changes should fix the schema issue: resource_ldap_secret_backend.go diffdiff --git a/vault/resource_ldap_secret_backend.go b/vault/resource_ldap_secret_backend.go
index 19d8c6c7..6f2876e6 100644
--- a/vault/resource_ldap_secret_backend.go
+++ b/vault/resource_ldap_secret_backend.go
@@ -159,6 +159,7 @@ func createUpdateLDAPConfigResource(ctx context.Context, d *schema.ResourceData,
consts.FieldLength,
consts.FieldPasswordPolicy,
consts.FieldRequestTimeout,
+ consts.FieldSchema,
consts.FieldUPNDomain,
consts.FieldURL,
consts.FieldUserAttr,
@@ -219,6 +220,7 @@ func readLDAPConfigResource(ctx context.Context, d *schema.ResourceData, meta in
consts.FieldLength,
consts.FieldPasswordPolicy,
consts.FieldRequestTimeout,
+ consts.FieldSchema,
consts.FieldStartTLS,
consts.FieldUPNDomain,
consts.FieldURL,
diff --git a/vault/resource_ldap_secret_backend_test.go b/vault/resource_ldap_secret_backend_test.go
index eb947a25..40d13154 100644
--- a/vault/resource_ldap_secret_backend_test.go
+++ b/vault/resource_ldap_secret_backend_test.go
@@ -22,9 +22,9 @@ To test, run the openldap service provided in the docker-compose.yaml file:
Then export the following environment variables:
- LDAP_BINDDN=cn=admin,dc=example,dc=org
- LDAP_BINDPASS=adminpassword
- LDAP_URL=ldap://localhost:1389
+ export LDAP_BINDDN=cn=admin,dc=example,dc=org
+ export LDAP_BINDPASS=adminpassword
+ export LDAP_URL=ldap://localhost:1389
*/
func TestLDAPSecretBackend(t *testing.T) {
var (
@@ -37,6 +37,7 @@ func TestLDAPSecretBackend(t *testing.T) {
userDN = "CN=Users,DC=corp,DC=example,DC=net"
updatedUserDN = "CN=Users,DC=corp,DC=hashicorp,DC=com"
)
+
resource.Test(t, resource.TestCase{
ProviderFactories: providerFactories,
PreCheck: func() {
@@ -48,6 +49,7 @@ func TestLDAPSecretBackend(t *testing.T) {
{
Config: testLDAPSecretBackendConfig_defaults(bindDN, bindPass),
Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, consts.FieldSchema, "openldap"),
resource.TestCheckResourceAttr(resourceName, consts.FieldPath, "ldap"),
resource.TestCheckResourceAttr(resourceName, consts.FieldDescription, description),
resource.TestCheckResourceAttr(resourceName, consts.FieldDefaultLeaseTTL, "0"),
@@ -60,8 +62,9 @@ func TestLDAPSecretBackend(t *testing.T) {
),
},
{
- Config: testLDAPSecretBackendConfig(path, description, bindDN, bindPass, url, userDN, true),
+ Config: testLDAPSecretBackendConfig(path, description, bindDN, bindPass, url, userDN, "", true),
Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, consts.FieldSchema, "openldap"),
resource.TestCheckResourceAttr(resourceName, consts.FieldPath, path),
resource.TestCheckResourceAttr(resourceName, consts.FieldDescription, description),
resource.TestCheckResourceAttr(resourceName, consts.FieldDefaultLeaseTTL, "3600"),
@@ -74,8 +77,37 @@ func TestLDAPSecretBackend(t *testing.T) {
),
},
{
- Config: testLDAPSecretBackendConfig(path, updatedDescription, bindDN, bindPass, url, updatedUserDN, false),
+ Config: testLDAPSecretBackendConfig(path, updatedDescription, bindDN, bindPass, url, updatedUserDN, "", false),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, consts.FieldSchema, "openldap"),
+ resource.TestCheckResourceAttr(resourceName, consts.FieldPath, path),
+ resource.TestCheckResourceAttr(resourceName, consts.FieldDescription, updatedDescription),
+ resource.TestCheckResourceAttr(resourceName, consts.FieldDefaultLeaseTTL, "3600"),
+ resource.TestCheckResourceAttr(resourceName, consts.FieldMaxLeaseTTL, "7200"),
+ resource.TestCheckResourceAttr(resourceName, consts.FieldBindDN, bindDN),
+ resource.TestCheckResourceAttr(resourceName, consts.FieldBindPass, bindPass),
+ resource.TestCheckResourceAttr(resourceName, consts.FieldURL, url),
+ resource.TestCheckResourceAttr(resourceName, consts.FieldUserDN, updatedUserDN),
+ resource.TestCheckResourceAttr(resourceName, consts.FieldInsecureTLS, "false"),
+ ),
+ },
+ testutil.GetImportTestStep(resourceName, false, nil,
+ consts.FieldBindPass, consts.FieldDescription, consts.FieldDisableRemount),
+ },
+ })
+
+ resource.Test(t, resource.TestCase{
+ ProviderFactories: providerFactories,
+ PreCheck: func() {
+ testutil.TestAccPreCheck(t)
+ SkipIfAPIVersionLT(t, testProvider.Meta(), provider.VaultVersion112)
+ }, PreventPostDestroyRefresh: true,
+ CheckDestroy: testCheckMountDestroyed(resourceType, consts.MountTypeLDAP, consts.FieldPath),
+ Steps: []resource.TestStep{
+ {
+ Config: testLDAPSecretBackendConfig(path, updatedDescription, bindDN, bindPass, url, updatedUserDN, `schema = "ad"`, false),
Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, consts.FieldSchema, "ad"),
resource.TestCheckResourceAttr(resourceName, consts.FieldPath, path),
resource.TestCheckResourceAttr(resourceName, consts.FieldDescription, updatedDescription),
resource.TestCheckResourceAttr(resourceName, consts.FieldDefaultLeaseTTL, "3600"),
@@ -103,7 +135,7 @@ resource "vault_ldap_secret_backend" "test" {
}`, bindDN, bindPass)
}
-func testLDAPSecretBackendConfig(mount, description, bindDN, bindPass, url, userDN string, insecureTLS bool) string {
+func testLDAPSecretBackendConfig(mount, description, bindDN, bindPass, url, userDN, extraConfig string, insecureTLS bool) string {
return fmt.Sprintf(`
resource "vault_ldap_secret_backend" "test" {
path = "%s"
@@ -115,6 +147,7 @@ resource "vault_ldap_secret_backend" "test" {
url = "%s"
userdn = "%s"
insecure_tls = %v
+ %s
}
-`, mount, description, bindDN, bindPass, url, userDN, insecureTLS)
+`, mount, description, bindDN, bindPass, url, userDN, insecureTLS, extraConfig)
} |
add ConflictsWith to `length` and `password_policy`
@bmhughes thanks for the feedback! I've updated the PR to take in your suggestions. Regarding your 4th point, we had a discussion and ultimately decided it would be easier to only accept int values. See #1821 (comment) for more info. |
No worries, glad I could help! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Had a comment around missing sidebar entry, but looks good otherwise 🎉
Adds the LDAP secret engine along with the following resources:
Adds the following data sources:
Deprecates the existing AD secrets engine & resources / data sources.