mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 12:41:30 +00:00
995b72df05
Replace static env-var-based issuer wiring with GUI-driven dynamic configuration stored encrypted in PostgreSQL. Operators can now configure, test, enable/disable, and manage issuers from the dashboard without restarting the server. Key changes: - AES-256-GCM encryption for sensitive issuer config at rest (PBKDF2 key derivation with 100k iterations) - Dynamic IssuerRegistry with sync.RWMutex replacing static map - Connector factory pattern (issuerfactory.NewFromConfig) replacing 140 lines of static wiring in main.go - Migration 000009: encrypted_config, last_tested_at, test_status, source columns on issuers table - Env var seeding on first boot with ON CONFLICT DO NOTHING - Registry Rebuild() for atomic map swap after CRUD operations - Issuer type validation against domain constants on Create - Audit trail for test connection results - Conditional seeding for step-ca/OpenSSL (only when env vars set) - GUI: source badge, connection test status on issuer detail page Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
88 lines
2.8 KiB
Go
88 lines
2.8 KiB
Go
package issuerfactory
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log/slog"
|
|
|
|
"github.com/shankar0123/certctl/internal/connector/issuer"
|
|
"github.com/shankar0123/certctl/internal/connector/issuer/acme"
|
|
"github.com/shankar0123/certctl/internal/connector/issuer/digicert"
|
|
"github.com/shankar0123/certctl/internal/connector/issuer/googlecas"
|
|
"github.com/shankar0123/certctl/internal/connector/issuer/local"
|
|
"github.com/shankar0123/certctl/internal/connector/issuer/openssl"
|
|
"github.com/shankar0123/certctl/internal/connector/issuer/sectigo"
|
|
"github.com/shankar0123/certctl/internal/connector/issuer/stepca"
|
|
"github.com/shankar0123/certctl/internal/connector/issuer/vault"
|
|
)
|
|
|
|
// NewFromConfig instantiates an issuer connector from its type string and config JSON.
|
|
// The config JSON keys use snake_case matching the connector Config struct json tags.
|
|
// This replaces the manual wiring in cmd/server/main.go.
|
|
func NewFromConfig(issuerType string, configJSON json.RawMessage, logger *slog.Logger) (issuer.Connector, error) {
|
|
if len(configJSON) == 0 {
|
|
configJSON = []byte("{}")
|
|
}
|
|
|
|
switch issuerType {
|
|
case "local", "GenericCA":
|
|
var cfg local.Config
|
|
if err := json.Unmarshal(configJSON, &cfg); err != nil {
|
|
return nil, fmt.Errorf("invalid Local CA config: %w", err)
|
|
}
|
|
return local.New(&cfg, logger), nil
|
|
|
|
case "ACME":
|
|
var cfg acme.Config
|
|
if err := json.Unmarshal(configJSON, &cfg); err != nil {
|
|
return nil, fmt.Errorf("invalid ACME config: %w", err)
|
|
}
|
|
return acme.New(&cfg, logger), nil
|
|
|
|
case "StepCA":
|
|
var cfg stepca.Config
|
|
if err := json.Unmarshal(configJSON, &cfg); err != nil {
|
|
return nil, fmt.Errorf("invalid step-ca config: %w", err)
|
|
}
|
|
return stepca.New(&cfg, logger), nil
|
|
|
|
case "OpenSSL":
|
|
var cfg openssl.Config
|
|
if err := json.Unmarshal(configJSON, &cfg); err != nil {
|
|
return nil, fmt.Errorf("invalid OpenSSL config: %w", err)
|
|
}
|
|
return openssl.New(&cfg, logger), nil
|
|
|
|
case "VaultPKI":
|
|
var cfg vault.Config
|
|
if err := json.Unmarshal(configJSON, &cfg); err != nil {
|
|
return nil, fmt.Errorf("invalid Vault PKI config: %w", err)
|
|
}
|
|
return vault.New(&cfg, logger), nil
|
|
|
|
case "DigiCert":
|
|
var cfg digicert.Config
|
|
if err := json.Unmarshal(configJSON, &cfg); err != nil {
|
|
return nil, fmt.Errorf("invalid DigiCert config: %w", err)
|
|
}
|
|
return digicert.New(&cfg, logger), nil
|
|
|
|
case "Sectigo":
|
|
var cfg sectigo.Config
|
|
if err := json.Unmarshal(configJSON, &cfg); err != nil {
|
|
return nil, fmt.Errorf("invalid Sectigo config: %w", err)
|
|
}
|
|
return sectigo.New(&cfg, logger), nil
|
|
|
|
case "GoogleCAS":
|
|
var cfg googlecas.Config
|
|
if err := json.Unmarshal(configJSON, &cfg); err != nil {
|
|
return nil, fmt.Errorf("invalid Google CAS config: %w", err)
|
|
}
|
|
return googlecas.New(&cfg, logger), nil
|
|
|
|
default:
|
|
return nil, fmt.Errorf("unknown issuer type: %q", issuerType)
|
|
}
|
|
}
|