mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-11 18:29:00 +00:00
M-2 PR-B: Collapse IssuerService + TargetService to ctx-first signatures
- Delete bare TestConnection wrapper in IssuerService; rename
TestConnectionWithContext → TestConnection
- Delete TestTargetConnection delegate shim in TargetService (canonical
TestConnection already ctx-first)
- Add ctx first param to 10 handler-interface methods
(ListIssuers/GetIssuer/CreateIssuer/UpdateIssuer/DeleteIssuer and
ListTargets/GetTarget/CreateTarget/UpdateTarget/DeleteTarget)
- Replace 16 context.Background() call sites with received ctx
- Thread r.Context() through 12 HTTP handler sites in issuers.go and
targets.go (outer TargetHandler.TestTargetConnection HTTP method name
preserved for router compatibility)
- Update MockIssuerService, MockTargetService, and mockTargetService
(integration) for ctx-first forwarding; update test callsite literals
Audit complete. Commit: 1f6cf0eafa. Sections: 12. Findings: 2/7/10/4/6.
This commit is contained in:
+15
-20
@@ -260,9 +260,9 @@ func (s *IssuerService) Delete(ctx context.Context, id string, actor string) err
|
||||
return nil
|
||||
}
|
||||
|
||||
// TestConnectionWithContext tests the connection to an issuer by instantiating a throwaway
|
||||
// TestConnection tests the connection to an issuer by instantiating a throwaway
|
||||
// connector and calling ValidateConfig. Records the result in the database.
|
||||
func (s *IssuerService) TestConnectionWithContext(ctx context.Context, id string) error {
|
||||
func (s *IssuerService) TestConnection(ctx context.Context, id string) error {
|
||||
iss, err := s.issuerRepo.Get(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("issuer not found: %w", err)
|
||||
@@ -291,11 +291,6 @@ func (s *IssuerService) TestConnectionWithContext(ctx context.Context, id string
|
||||
return nil
|
||||
}
|
||||
|
||||
// TestConnection verifies the issuer connection (handler interface method).
|
||||
func (s *IssuerService) TestConnection(id string) error {
|
||||
return s.TestConnectionWithContext(context.Background(), id)
|
||||
}
|
||||
|
||||
// BuildRegistry loads all enabled issuers from the database and rebuilds the dynamic registry.
|
||||
// Called at server startup. Partial failures (individual issuers failing to load) are logged
|
||||
// as warnings but don't prevent the server from starting.
|
||||
@@ -633,7 +628,7 @@ func (s *IssuerService) buildEnvVarSeeds(cfg *config.Config) []*domain.Issuer {
|
||||
}
|
||||
|
||||
// ListIssuers returns paginated issuers (handler interface method).
|
||||
func (s *IssuerService) ListIssuers(page, perPage int) ([]domain.Issuer, int64, error) {
|
||||
func (s *IssuerService) ListIssuers(ctx context.Context, page, perPage int) ([]domain.Issuer, int64, error) {
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
@@ -641,7 +636,7 @@ func (s *IssuerService) ListIssuers(page, perPage int) ([]domain.Issuer, int64,
|
||||
perPage = 50
|
||||
}
|
||||
|
||||
issuers, err := s.issuerRepo.List(context.Background())
|
||||
issuers, err := s.issuerRepo.List(ctx)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to list issuers: %w", err)
|
||||
}
|
||||
@@ -658,12 +653,12 @@ func (s *IssuerService) ListIssuers(page, perPage int) ([]domain.Issuer, int64,
|
||||
}
|
||||
|
||||
// GetIssuer returns a single issuer (handler interface method).
|
||||
func (s *IssuerService) GetIssuer(id string) (*domain.Issuer, error) {
|
||||
return s.issuerRepo.Get(context.Background(), id)
|
||||
func (s *IssuerService) GetIssuer(ctx context.Context, id string) (*domain.Issuer, error) {
|
||||
return s.issuerRepo.Get(ctx, id)
|
||||
}
|
||||
|
||||
// CreateIssuer creates a new issuer (handler interface method).
|
||||
func (s *IssuerService) CreateIssuer(iss domain.Issuer) (*domain.Issuer, error) {
|
||||
func (s *IssuerService) CreateIssuer(ctx context.Context, iss domain.Issuer) (*domain.Issuer, error) {
|
||||
iss.Type = normalizeIssuerType(iss.Type)
|
||||
if !isValidIssuerType(iss.Type) {
|
||||
return nil, fmt.Errorf("unsupported issuer type: %s", iss.Type)
|
||||
@@ -700,26 +695,26 @@ func (s *IssuerService) CreateIssuer(iss domain.Issuer) (*domain.Issuer, error)
|
||||
iss.Config = redactConfigJSON(iss.Config)
|
||||
}
|
||||
|
||||
if err := s.issuerRepo.Create(context.Background(), &iss); err != nil {
|
||||
if err := s.issuerRepo.Create(ctx, &iss); err != nil {
|
||||
return nil, fmt.Errorf("failed to create issuer: %w", err)
|
||||
}
|
||||
|
||||
// Rebuild registry
|
||||
if iss.Enabled {
|
||||
s.rebuildRegistryQuiet(context.Background())
|
||||
s.rebuildRegistryQuiet(ctx)
|
||||
}
|
||||
|
||||
return &iss, nil
|
||||
}
|
||||
|
||||
// UpdateIssuer modifies an issuer (handler interface method).
|
||||
func (s *IssuerService) UpdateIssuer(id string, iss domain.Issuer) (*domain.Issuer, error) {
|
||||
func (s *IssuerService) UpdateIssuer(ctx context.Context, id string, iss domain.Issuer) (*domain.Issuer, error) {
|
||||
iss.ID = id
|
||||
iss.UpdatedAt = time.Now()
|
||||
|
||||
// Merge redacted fields with existing config
|
||||
if len(iss.Config) > 0 {
|
||||
mergedConfig, err := s.mergeRedactedConfig(context.Background(), id, iss.Config)
|
||||
mergedConfig, err := s.mergeRedactedConfig(ctx, id, iss.Config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to merge config: %w", err)
|
||||
}
|
||||
@@ -732,18 +727,18 @@ func (s *IssuerService) UpdateIssuer(id string, iss domain.Issuer) (*domain.Issu
|
||||
iss.Config = redactConfigJSON(json.RawMessage(mergedConfig))
|
||||
}
|
||||
|
||||
if err := s.issuerRepo.Update(context.Background(), &iss); err != nil {
|
||||
if err := s.issuerRepo.Update(ctx, &iss); err != nil {
|
||||
return nil, fmt.Errorf("failed to update issuer: %w", err)
|
||||
}
|
||||
|
||||
s.rebuildRegistryQuiet(context.Background())
|
||||
s.rebuildRegistryQuiet(ctx)
|
||||
|
||||
return &iss, nil
|
||||
}
|
||||
|
||||
// DeleteIssuer removes an issuer (handler interface method).
|
||||
func (s *IssuerService) DeleteIssuer(id string) error {
|
||||
if err := s.issuerRepo.Delete(context.Background(), id); err != nil {
|
||||
func (s *IssuerService) DeleteIssuer(ctx context.Context, id string) error {
|
||||
if err := s.issuerRepo.Delete(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
if s.registry != nil {
|
||||
|
||||
@@ -484,10 +484,10 @@ func TestIssuerService_TestConnection_Success(t *testing.T) {
|
||||
|
||||
svc := NewIssuerService(repo, auditService, NewIssuerRegistry(slog.Default()), "", slog.Default())
|
||||
|
||||
err := svc.TestConnectionWithContext(ctx, "iss-test-conn")
|
||||
err := svc.TestConnection(ctx, "iss-test-conn")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("TestConnectionWithContext failed: %v", err)
|
||||
t.Fatalf("TestConnection failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,7 +502,7 @@ func TestIssuerService_TestConnection_NotFound(t *testing.T) {
|
||||
registry := NewIssuerRegistry(slog.Default())
|
||||
service := NewIssuerService(repo, auditService, registry, "", slog.Default())
|
||||
|
||||
err := service.TestConnectionWithContext(ctx, "nonexistent-issuer")
|
||||
err := service.TestConnection(ctx, "nonexistent-issuer")
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("expected error for nonexistent issuer")
|
||||
@@ -542,7 +542,8 @@ func TestIssuerService_ListIssuers_HandlerInterface(t *testing.T) {
|
||||
|
||||
service := NewIssuerService(repo, auditService, NewIssuerRegistry(slog.Default()), "", slog.Default())
|
||||
|
||||
issuers, total, err := service.ListIssuers(1, 50)
|
||||
ctx := context.Background()
|
||||
issuers, total, err := service.ListIssuers(ctx, 1, 50)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("ListIssuers failed: %v", err)
|
||||
@@ -580,7 +581,8 @@ func TestIssuerService_CreateIssuer_HandlerInterface(t *testing.T) {
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
result, err := service.CreateIssuer(issuer)
|
||||
ctx := context.Background()
|
||||
result, err := service.CreateIssuer(ctx, issuer)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("CreateIssuer failed: %v", err)
|
||||
@@ -608,7 +610,8 @@ func TestIssuerService_DeleteIssuer_HandlerInterface(t *testing.T) {
|
||||
registry := NewIssuerRegistry(slog.Default())
|
||||
service := NewIssuerService(repo, auditService, registry, "", slog.Default())
|
||||
|
||||
err := service.DeleteIssuer("iss-handler-delete")
|
||||
ctx := context.Background()
|
||||
err := service.DeleteIssuer(ctx, "iss-handler-delete")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("DeleteIssuer failed: %v", err)
|
||||
@@ -722,7 +725,8 @@ func TestIssuerService_CreateIssuer_LowercaseType(t *testing.T) {
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
result, err := service.CreateIssuer(issuer)
|
||||
ctx := context.Background()
|
||||
result, err := service.CreateIssuer(ctx, issuer)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateIssuer with lowercase 'stepca' should succeed, got: %v", err)
|
||||
}
|
||||
|
||||
+11
-16
@@ -242,7 +242,7 @@ func (s *TargetService) TestConnection(ctx context.Context, id string) error {
|
||||
}
|
||||
|
||||
// ListTargets returns paginated targets (handler interface method).
|
||||
func (s *TargetService) ListTargets(page, perPage int) ([]domain.DeploymentTarget, int64, error) {
|
||||
func (s *TargetService) ListTargets(ctx context.Context, page, perPage int) ([]domain.DeploymentTarget, int64, error) {
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
@@ -250,7 +250,7 @@ func (s *TargetService) ListTargets(page, perPage int) ([]domain.DeploymentTarge
|
||||
perPage = 50
|
||||
}
|
||||
|
||||
targets, err := s.targetRepo.List(context.Background())
|
||||
targets, err := s.targetRepo.List(ctx)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to list targets: %w", err)
|
||||
}
|
||||
@@ -267,12 +267,12 @@ func (s *TargetService) ListTargets(page, perPage int) ([]domain.DeploymentTarge
|
||||
}
|
||||
|
||||
// GetTarget returns a single target (handler interface method).
|
||||
func (s *TargetService) GetTarget(id string) (*domain.DeploymentTarget, error) {
|
||||
return s.targetRepo.Get(context.Background(), id)
|
||||
func (s *TargetService) GetTarget(ctx context.Context, id string) (*domain.DeploymentTarget, error) {
|
||||
return s.targetRepo.Get(ctx, id)
|
||||
}
|
||||
|
||||
// CreateTarget creates a new target (handler interface method).
|
||||
func (s *TargetService) CreateTarget(target domain.DeploymentTarget) (*domain.DeploymentTarget, error) {
|
||||
func (s *TargetService) CreateTarget(ctx context.Context, target domain.DeploymentTarget) (*domain.DeploymentTarget, error) {
|
||||
if !isValidTargetType(target.Type) {
|
||||
return nil, fmt.Errorf("unsupported target type: %s", target.Type)
|
||||
}
|
||||
@@ -308,20 +308,20 @@ func (s *TargetService) CreateTarget(target domain.DeploymentTarget) (*domain.De
|
||||
target.Config = redactConfigJSON(target.Config)
|
||||
}
|
||||
|
||||
if err := s.targetRepo.Create(context.Background(), &target); err != nil {
|
||||
if err := s.targetRepo.Create(ctx, &target); err != nil {
|
||||
return nil, fmt.Errorf("failed to create target: %w", err)
|
||||
}
|
||||
return &target, nil
|
||||
}
|
||||
|
||||
// UpdateTarget modifies a target (handler interface method).
|
||||
func (s *TargetService) UpdateTarget(id string, target domain.DeploymentTarget) (*domain.DeploymentTarget, error) {
|
||||
func (s *TargetService) UpdateTarget(ctx context.Context, id string, target domain.DeploymentTarget) (*domain.DeploymentTarget, error) {
|
||||
target.ID = id
|
||||
target.UpdatedAt = time.Now()
|
||||
|
||||
// Merge redacted fields with existing config
|
||||
if len(target.Config) > 0 {
|
||||
mergedConfig, err := s.mergeRedactedConfig(context.Background(), id, target.Config)
|
||||
mergedConfig, err := s.mergeRedactedConfig(ctx, id, target.Config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to merge config: %w", err)
|
||||
}
|
||||
@@ -334,20 +334,15 @@ func (s *TargetService) UpdateTarget(id string, target domain.DeploymentTarget)
|
||||
target.Config = redactConfigJSON(json.RawMessage(mergedConfig))
|
||||
}
|
||||
|
||||
if err := s.targetRepo.Update(context.Background(), &target); err != nil {
|
||||
if err := s.targetRepo.Update(ctx, &target); err != nil {
|
||||
return nil, fmt.Errorf("failed to update target: %w", err)
|
||||
}
|
||||
return &target, nil
|
||||
}
|
||||
|
||||
// DeleteTarget removes a target (handler interface method).
|
||||
func (s *TargetService) DeleteTarget(id string) error {
|
||||
return s.targetRepo.Delete(context.Background(), id)
|
||||
}
|
||||
|
||||
// TestTargetConnection tests target connectivity (handler interface method).
|
||||
func (s *TargetService) TestTargetConnection(id string) error {
|
||||
return s.TestConnection(context.Background(), id)
|
||||
func (s *TargetService) DeleteTarget(ctx context.Context, id string) error {
|
||||
return s.targetRepo.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// --- Internal helpers ---
|
||||
|
||||
@@ -344,7 +344,8 @@ func TestTargetService_ListTargets_Success(t *testing.T) {
|
||||
targetRepo.AddTarget(target2)
|
||||
|
||||
// Call handler-interface method
|
||||
targets, total, err := svc.ListTargets(1, 50)
|
||||
ctx := context.Background()
|
||||
targets, total, err := svc.ListTargets(ctx, 1, 50)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -364,7 +365,8 @@ func TestTargetService_GetTarget_Success(t *testing.T) {
|
||||
target := &domain.DeploymentTarget{ID: "t-1", Name: "Target 1", Type: domain.TargetTypeNGINX}
|
||||
targetRepo.AddTarget(target)
|
||||
|
||||
result, err := svc.GetTarget("t-1")
|
||||
ctx := context.Background()
|
||||
result, err := svc.GetTarget(ctx, "t-1")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -382,7 +384,8 @@ func TestTargetService_CreateTarget_Success(t *testing.T) {
|
||||
Type: domain.TargetTypeNGINX,
|
||||
}
|
||||
|
||||
result, err := svc.CreateTarget(target)
|
||||
ctx := context.Background()
|
||||
result, err := svc.CreateTarget(ctx, target)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -405,7 +408,8 @@ func TestTargetService_CreateTarget_InvalidType(t *testing.T) {
|
||||
Type: domain.TargetType("Unknown"),
|
||||
}
|
||||
|
||||
_, err := svc.CreateTarget(target)
|
||||
ctx := context.Background()
|
||||
_, err := svc.CreateTarget(ctx, target)
|
||||
if err == nil {
|
||||
t.Fatalf("expected error for invalid type, got nil")
|
||||
}
|
||||
@@ -424,7 +428,8 @@ func TestTargetService_UpdateTarget_Success(t *testing.T) {
|
||||
Type: domain.TargetTypeApache,
|
||||
}
|
||||
|
||||
result, err := svc.UpdateTarget("t-1", updated)
|
||||
ctx := context.Background()
|
||||
result, err := svc.UpdateTarget(ctx, "t-1", updated)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -442,7 +447,8 @@ func TestTargetService_DeleteTarget_Success(t *testing.T) {
|
||||
targetRepo.AddTarget(target)
|
||||
|
||||
// Delete it
|
||||
err := svc.DeleteTarget("t-1")
|
||||
ctx := context.Background()
|
||||
err := svc.DeleteTarget(ctx, "t-1")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user