-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add resource and datasource to manage OrganizationalUnit
- Loading branch information
1 parent
21e8c27
commit b7c3ad0
Showing
7 changed files
with
292 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# ldap_ou | ||
|
||
`ldap_ou` is a data source for managing an LDAP OU. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
data "ldap_ou" "ou" { | ||
ou = "OU=MyCompany,DC=domain,DC=tld" | ||
name = "MyOU" | ||
scope = 2 | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
* `name` - (Required) LDAP OU name. | ||
* `ou` - (Required) OU where LDAP OU will be search. | ||
* `scope` - (Optional) LDAP search scope (0: BaseObject, 1: SingleLevel, 2: WholeSubtree) Defaults to `0`. | ||
|
||
## Attribute Reference | ||
|
||
* `id` - The DN of the LDAP OU. | ||
* `description` - Description attribute for the LDAP OU | ||
* `managed_by` - ManagedBy attribute. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# ldap_ou | ||
|
||
`ldap_ou` is a resource for managing an LDAP OU. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
resource "ldap_ou" "ou" { | ||
name = "MyOU" | ||
ou = "OU=MyCompany,DC=domain,DC=tld" | ||
description = "My OU description" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
* `ou` - (Required) OU where LDAP OU will be created. | ||
* `name` - (Required) LDAP OU name. | ||
* `description` - (Optional) Description attribute for the LDAP OU. Defaults to empty. | ||
* `managed_by` - (Optional) ManagedBy attribute. Defaults to ``. | ||
|
||
## Attribute Reference | ||
|
||
* `id` - The DN of the LDAP OU. | ||
|
||
## Import | ||
|
||
LDAP OU can be imported using the full LDAP DN (id), e.g. | ||
|
||
``` | ||
$ terraform import ldap_ou.example OU=Myou,OU=MyCompany,DC=domain,DC=tld | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package ldap | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/Ouest-France/goldap" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
func dataSourceLDAPOU() *schema.Resource { | ||
return &schema.Resource{ | ||
Description: "`ldap_ou` is a data source for getting an LDAP OU.", | ||
ReadContext: dataSourceLDAPOURead, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"id": { | ||
Description: "The DN of the LDAP OU.", | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"ou": { | ||
Description: "OU where LDAP OU will be search.", | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"name": { | ||
Description: "LDAP OU name.", | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"scope": { | ||
Description: "LDAP search scope", | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
Default: 0, | ||
}, | ||
"description": { | ||
Description: "Description attribute for the LDAP OU", | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"managed_by": { | ||
Description: "ManagedBy attribute", | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func dataSourceLDAPOURead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
|
||
// Get scope | ||
scope := d.Get("scope").(int) | ||
if scope < 0 || scope > 2 { | ||
return diag.FromErr(fmt.Errorf("scope must be between 0 and 2, got %d", scope)) | ||
} | ||
|
||
// If scope is 1 or 2, we search the OU DN given the OU name and the OU | ||
client := m.(*goldap.Client) | ||
|
||
// Search OU | ||
dn, err := client.SearchOUByName(d.Get("name").(string), d.Get("ou").(string), scope) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
d.SetId(dn) | ||
|
||
// Add context key to signal the Read is called from a datasource | ||
return resourceLDAPOURead(context.WithValue(ctx, CallerTypeKey, DatasourceCaller), d, m) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
package ldap | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/Ouest-France/goldap" | ||
"github.com/go-ldap/ldap/v3" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
func resourceLDAPOU() *schema.Resource { | ||
return &schema.Resource{ | ||
Description: "`ldap_ou` is a resource for managing an LDAP OU.", | ||
CreateContext: resourceLDAPOUCreate, | ||
ReadContext: resourceLDAPOURead, | ||
UpdateContext: resourceLDAPOUUpdate, | ||
DeleteContext: resourceLDAPOUDelete, | ||
Importer: &schema.ResourceImporter{ | ||
StateContext: schema.ImportStatePassthroughContext, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"id": { | ||
Description: "The DN of the LDAP OU.", | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"ou": { | ||
Description: "OU where LDAP OU will be created.", | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"name": { | ||
Description: "LDAP OU name.", | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"description": { | ||
Description: "Description attribute for the LDAP OU.", | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
"managed_by": { | ||
Description: "ManagedBy attribute", | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Default: "", | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceLDAPOUCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
client := m.(*goldap.Client) | ||
|
||
dn := fmt.Sprintf("OU=%s,%s", d.Get("name").(string), d.Get("ou").(string)) | ||
|
||
err := client.CreateOrganizationalUnit(dn, d.Get("description").(string), d.Get("managed_by").(string)) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
d.SetId(dn) | ||
|
||
return resourceLDAPOURead(ctx, d, m) | ||
} | ||
|
||
func resourceLDAPOURead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
client := m.(*goldap.Client) | ||
|
||
dn := d.Id() | ||
|
||
attributes, err := client.ReadOrganizationalUnit(dn) | ||
if err != nil { | ||
if err.(*ldap.Error).ResultCode == 32 { | ||
// Object doesn't exist | ||
|
||
// If Read is called from a datasource, return an error | ||
if ctx.Value(CallerTypeKey) == DatasourceCaller { | ||
return diag.Errorf("LDAP OU not found: %s", dn) | ||
} | ||
|
||
// If not a call from datasource, remove the resource from the state | ||
// and cleanly return | ||
d.SetId("") | ||
return nil | ||
} | ||
return diag.FromErr(err) | ||
} | ||
|
||
nameAttr, ok := attributes["ou"] | ||
if !ok || len(nameAttr) != 1 { | ||
return diag.Errorf("LDAP attribute \"name\" doesn't exist or is empty for OU: %s", dn) | ||
} | ||
|
||
if err := d.Set("name", nameAttr[0]); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
// Remove the `OU=<ou-name>,` from the DN to get the OU | ||
ou := strings.ReplaceAll(dn, fmt.Sprintf("OU=%s,", attributes["name"][0]), "") | ||
if err := d.Set("ou", ou); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
desc := "" | ||
if val, ok := attributes["description"]; ok { | ||
desc = val[0] | ||
} | ||
if err := d.Set("description", desc); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
managedBy := "" | ||
if val, ok := attributes["managedBy"]; ok { | ||
managedBy = val[0] | ||
} | ||
if err := d.Set("managed_by", managedBy); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
return diag.FromErr(err) | ||
} | ||
|
||
func resourceLDAPOUUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
client := m.(*goldap.Client) | ||
dn := fmt.Sprintf("OU=%s,%s", d.Get("name").(string), d.Get("ou").(string)) | ||
|
||
if d.HasChange("description") { | ||
if err := client.UpdateOrganizationalUnitDescription(dn, d.Get("description").(string)); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
} | ||
|
||
if d.HasChange("managed_by") { | ||
if err := client.UpdateOrganizationalUnitManagedBy(dn, d.Get("managed_by").(string)); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
} | ||
|
||
return resourceLDAPOURead(ctx, d, m) | ||
} | ||
|
||
func resourceLDAPOUDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
client := m.(*goldap.Client) | ||
dn := fmt.Sprintf("OU=%s,%s", d.Get("name").(string), d.Get("ou").(string)) | ||
|
||
err := client.DeleteOrganizationalUnit(dn) | ||
|
||
return diag.FromErr(err) | ||
} |