@@ -445,9 +445,8 @@ func (r *acmeCertificateResource) Update(
445445 resp .Diagnostics .Append (resp .State .Set (ctx , & plan )... )
446446}
447447
448- // Delete removes the certificate resource from Terraform state.
449- // Note: This doesn't actually delete the certificate from the node,
450- // as ACME certificates should remain on the node for the services to use.
448+ // Delete removes the certificate resource from Terraform state and cleans up ACME configuration from the node.
449+ // The certificate files are preserved on the Proxmox node, but the ACME configuration is removed.
451450func (r * acmeCertificateResource ) Delete (
452451 ctx context.Context ,
453452 req resource.DeleteRequest ,
@@ -461,10 +460,22 @@ func (r *acmeCertificateResource) Delete(
461460 return
462461 }
463462
464- // Note: We don't actually delete the certificate from the node
465- // as it's needed for the node's services. We just remove it from Terraform state.
466- // If users want to remove the certificate from the node, they should use
467- // the Proxmox UI or manually delete it via the API.
463+ nodeName := state .NodeName .ValueString ()
464+ nodeClient := r .client .Node (nodeName )
465+
466+ // Clean up the ACME configuration from the node. The certificate files will remain.
467+ toDelete := "acme,acmedomain0,acmedomain1,acmedomain2,acmedomain3,acmedomain4"
468+ configUpdate := & nodes.ConfigUpdateRequestBody {
469+ Delete : & toDelete ,
470+ }
471+
472+ if err := nodeClient .UpdateConfig (ctx , configUpdate ); err != nil {
473+ // Log a warning as the resource is being deleted anyway, but the user should be notified.
474+ resp .Diagnostics .AddWarning (
475+ "Failed to clean up node ACME configuration" ,
476+ fmt .Sprintf ("An error occurred while cleaning up ACME settings for node %s on delete: %s. Manual cleanup of /etc/pve/nodes/%s/config may be required." , nodeName , err .Error (), nodeName ),
477+ )
478+ }
468479}
469480
470481// ImportState imports an existing certificate by node name.
@@ -612,42 +623,50 @@ func (r *acmeCertificateResource) configureNodeACME(
612623 }
613624
614625 // Configure DNS challenge domains (up to 5 domains with DNS plugins)
615- if len (dnsDomains ) > 0 {
616- if len (dnsDomains ) > 5 {
617- return fmt .Errorf ("Proxmox supports a maximum of 5 DNS challenge domains, got %d" , len (dnsDomains ))
618- }
626+ if len (dnsDomains ) > 5 {
627+ return fmt .Errorf ("Proxmox supports a maximum of 5 DNS challenge domains, got %d" , len (dnsDomains ))
628+ }
619629
620- for i , domain := range dnsDomains {
621- domainConfig := & nodes.ACMEDomainConfig {
622- Domain : domain .Domain .ValueString (),
623- }
630+ for i , domain := range dnsDomains {
631+ domainConfig := & nodes.ACMEDomainConfig {
632+ Domain : domain .Domain .ValueString (),
633+ }
624634
625- if ! domain .Plugin .IsNull () {
626- plugin := domain .Plugin .ValueString ()
627- domainConfig .Plugin = & plugin
628- }
635+ if ! domain .Plugin .IsNull () {
636+ plugin := domain .Plugin .ValueString ()
637+ domainConfig .Plugin = & plugin
638+ }
629639
630- if ! domain .Alias .IsNull () {
631- alias := domain .Alias .ValueString ()
632- domainConfig .Alias = & alias
633- }
640+ if ! domain .Alias .IsNull () {
641+ alias := domain .Alias .ValueString ()
642+ domainConfig .Alias = & alias
643+ }
634644
635- // Map to the appropriate acmedomain field
636- switch i {
637- case 0 :
638- configUpdate .ACMEDomain0 = domainConfig
639- case 1 :
640- configUpdate .ACMEDomain1 = domainConfig
641- case 2 :
642- configUpdate .ACMEDomain2 = domainConfig
643- case 3 :
644- configUpdate .ACMEDomain3 = domainConfig
645- case 4 :
646- configUpdate .ACMEDomain4 = domainConfig
647- }
645+ // Map to the appropriate acmedomain field
646+ switch i {
647+ case 0 :
648+ configUpdate .ACMEDomain0 = domainConfig
649+ case 1 :
650+ configUpdate .ACMEDomain1 = domainConfig
651+ case 2 :
652+ configUpdate .ACMEDomain2 = domainConfig
653+ case 3 :
654+ configUpdate .ACMEDomain3 = domainConfig
655+ case 4 :
656+ configUpdate .ACMEDomain4 = domainConfig
648657 }
649658 }
650659
660+ // Clean up unused acmedomain slots
661+ var toDelete []string
662+ for i := len (dnsDomains ); i < 5 ; i ++ {
663+ toDelete = append (toDelete , fmt .Sprintf ("acmedomain%d" , i ))
664+ }
665+ if len (toDelete ) > 0 {
666+ deleteValue := strings .Join (toDelete , "," )
667+ configUpdate .Delete = & deleteValue
668+ }
669+
651670 // Update the node configuration
652671 return nodeClient .UpdateConfig (ctx , configUpdate )
653672}
0 commit comments