// Copyright IBM Corp. 2020, 2026 // SPDX-License-Identifier: MPL-2.0 package provider import ( "context" "net/http" "repo.anhonesthost.net/CyberCoveLLC/threshold/api" "repo.anhonesthost.net/CyberCoveLLC/threshold/api/credentiallibraries" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) const ( credentialLibraryVaultLdapType = "vault-ldap" credentialLibraryVaultLdapPathKey = "path" ) var libraryVaultLdapAttrs = []string{ credentialLibraryVaultLdapPathKey, } func resourceCredentialLibraryVaultLdap() *schema.Resource { return &schema.Resource{ Description: "The credential library for Vault LDAP resource allows you to configure a Threshold credential library for Vault LDAP.", CreateContext: resourceCredentialLibraryCreateVaultLdap, ReadContext: resourceCredentialLibraryReadVaultLdap, UpdateContext: resourceCredentialLibraryUpdateVaultLdap, DeleteContext: resourceCredentialLibraryDeleteVaultLdap, Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, Schema: map[string]*schema.Schema{ IDKey: { Description: "The ID of the Vault LDAP credential library.", Type: schema.TypeString, Computed: true, }, NameKey: { Description: "The Vault LDAP credential library name. Defaults to the resource name.", Type: schema.TypeString, Optional: true, }, DescriptionKey: { Description: "The Vault LDAP credential library description.", Type: schema.TypeString, Optional: true, }, credentialStoreIdKey: { Description: "The ID of the credential store that this library belongs to.", Type: schema.TypeString, Required: true, ForceNew: true, }, credentialLibraryVaultLdapPathKey: { Description: "The path in Vault to request credentials from.", Type: schema.TypeString, Required: true, }, }, } } func setFromVaultLdapCredentialLibraryResponseMap(d *schema.ResourceData, raw map[string]interface{}) error { if err := d.Set(NameKey, raw[NameKey]); err != nil { return err } if err := d.Set(DescriptionKey, raw[DescriptionKey]); err != nil { return err } if err := d.Set(credentialStoreIdKey, raw[credentialStoreIdKey]); err != nil { return err } if attrsVal, ok := raw["attributes"]; ok { attrs := attrsVal.(map[string]interface{}) for _, v := range libraryVaultLdapAttrs { if err := d.Set(v, attrs[v]); err != nil { return err } } } d.SetId(raw["id"].(string)) return nil } func resourceCredentialLibraryCreateVaultLdap(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { md := meta.(*metaData) var opts []credentiallibraries.Option if v, ok := d.GetOk(NameKey); ok { opts = append(opts, credentiallibraries.WithName(v.(string))) } if v, ok := d.GetOk(DescriptionKey); ok { opts = append(opts, credentiallibraries.WithDescription(v.(string))) } if v, ok := d.GetOk(credentialLibraryVaultLdapPathKey); ok { opts = append(opts, credentiallibraries.WithVaultLdapCredentialLibraryPath(v.(string))) } var credentialStoreId string cid, ok := d.GetOk(credentialStoreIdKey) if ok { credentialStoreId = cid.(string) } else { return diag.Errorf("no credential store ID is set") } client := credentiallibraries.NewClient(md.client) cr, err := client.Create(ctx, credentialLibraryVaultLdapType, credentialStoreId, opts...) if err != nil { return diag.Errorf("error creating credential library: %v", err) } if cr == nil { return diag.Errorf("nil credential library after create") } if err := setFromVaultLdapCredentialLibraryResponseMap(d, cr.GetResponse().Map); err != nil { return diag.FromErr(err) } return nil } func resourceCredentialLibraryReadVaultLdap(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { md := meta.(*metaData) client := credentiallibraries.NewClient(md.client) cr, err := client.Read(ctx, d.Id()) if err != nil { if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { d.SetId("") return nil } return diag.Errorf("error reading credential library: %v", err) } if cr == nil { return diag.Errorf("credential library nil after read") } if err := setFromVaultLdapCredentialLibraryResponseMap(d, cr.GetResponse().Map); err != nil { return diag.FromErr(err) } return nil } func resourceCredentialLibraryUpdateVaultLdap(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { md := meta.(*metaData) client := credentiallibraries.NewClient(md.client) var opts []credentiallibraries.Option if d.HasChange(NameKey) { opts = append(opts, credentiallibraries.DefaultName()) nameVal, ok := d.GetOk(NameKey) if ok { opts = append(opts, credentiallibraries.WithName(nameVal.(string))) } } if d.HasChange(DescriptionKey) { opts = append(opts, credentiallibraries.DefaultDescription()) descVal, ok := d.GetOk(DescriptionKey) if ok { opts = append(opts, credentiallibraries.WithDescription(descVal.(string))) } } if d.HasChange(credentialLibraryVaultLdapPathKey) { v, ok := d.GetOk(credentialLibraryVaultLdapPathKey) if ok { opts = append(opts, credentiallibraries.WithVaultLdapCredentialLibraryPath(v.(string))) } } if len(opts) > 0 { opts = append(opts, credentiallibraries.WithAutomaticVersioning(true)) aur, err := client.Update(ctx, d.Id(), 0, opts...) if err != nil { return diag.Errorf("error updating credential library: %v", err) } if err := setFromVaultLdapCredentialLibraryResponseMap(d, aur.GetResponse().Map); err != nil { return diag.Errorf("error setting credential library from response: %v", err) } } return nil } func resourceCredentialLibraryDeleteVaultLdap(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { md := meta.(*metaData) client := credentiallibraries.NewClient(md.client) _, err := client.Delete(ctx, d.Id()) if err != nil { return diag.Errorf("error deleting credential library: %v", err) } return nil }