-
Notifications
You must be signed in to change notification settings - Fork 554
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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.