diff --git a/spinifex/gateway/acm/certificates.go b/spinifex/gateway/acm/certificates.go index 7d4b352ad..ded190808 100644 --- a/spinifex/gateway/acm/certificates.go +++ b/spinifex/gateway/acm/certificates.go @@ -3,20 +3,24 @@ package gateway_acm import ( "context" "errors" + "time" "github.com/aws/aws-sdk-go/service/acm" "github.com/mulgadc/spinifex/spinifex/awserrors" - handlers_acm "github.com/mulgadc/spinifex/spinifex/handlers/acm" + "github.com/mulgadc/spinifex/spinifex/utils" "github.com/nats-io/nats.go" ) +// natsTimeout bounds the gateway's wait for a daemon-side ACM response. +const natsTimeout = 30 * time.Second + // ImportCertificate — CertificateManager.ImportCertificate. func ImportCertificate(ctx context.Context, natsConn *nats.Conn, accountID string, body []byte) (*acm.ImportCertificateOutput, error) { input := new(acm.ImportCertificateInput) if err := unmarshalIfBody(body, input); err != nil { return nil, errors.New(awserrors.ErrorInvalidParameter) } - return handlers_acm.NewNATSACMService(natsConn).ImportCertificate(ctx, input, accountID) + return utils.NATSRequest[acm.ImportCertificateOutput](ctx, natsConn, "acm.ImportCertificate", input, natsTimeout, accountID) } // DescribeCertificate — CertificateManager.DescribeCertificate. @@ -25,7 +29,7 @@ func DescribeCertificate(ctx context.Context, natsConn *nats.Conn, accountID str if err := unmarshalIfBody(body, input); err != nil { return nil, errors.New(awserrors.ErrorInvalidParameter) } - return handlers_acm.NewNATSACMService(natsConn).DescribeCertificate(ctx, input, accountID) + return utils.NATSRequest[acm.DescribeCertificateOutput](ctx, natsConn, "acm.DescribeCertificate", input, natsTimeout, accountID) } // GetCertificate — CertificateManager.GetCertificate. @@ -34,7 +38,7 @@ func GetCertificate(ctx context.Context, natsConn *nats.Conn, accountID string, if err := unmarshalIfBody(body, input); err != nil { return nil, errors.New(awserrors.ErrorInvalidParameter) } - return handlers_acm.NewNATSACMService(natsConn).GetCertificate(ctx, input, accountID) + return utils.NATSRequest[acm.GetCertificateOutput](ctx, natsConn, "acm.GetCertificate", input, natsTimeout, accountID) } // ListCertificates — CertificateManager.ListCertificates. @@ -43,7 +47,7 @@ func ListCertificates(ctx context.Context, natsConn *nats.Conn, accountID string if err := unmarshalIfBody(body, input); err != nil { return nil, errors.New(awserrors.ErrorInvalidParameter) } - return handlers_acm.NewNATSACMService(natsConn).ListCertificates(ctx, input, accountID) + return utils.NATSRequest[acm.ListCertificatesOutput](ctx, natsConn, "acm.ListCertificates", input, natsTimeout, accountID) } // DeleteCertificate — CertificateManager.DeleteCertificate. @@ -52,7 +56,7 @@ func DeleteCertificate(ctx context.Context, natsConn *nats.Conn, accountID strin if err := unmarshalIfBody(body, input); err != nil { return nil, errors.New(awserrors.ErrorInvalidParameter) } - return handlers_acm.NewNATSACMService(natsConn).DeleteCertificate(ctx, input, accountID) + return utils.NATSRequest[acm.DeleteCertificateOutput](ctx, natsConn, "acm.DeleteCertificate", input, natsTimeout, accountID) } // ListTagsForCertificate — CertificateManager.ListTagsForCertificate. @@ -61,7 +65,7 @@ func ListTagsForCertificate(ctx context.Context, natsConn *nats.Conn, accountID if err := unmarshalIfBody(body, input); err != nil { return nil, errors.New(awserrors.ErrorInvalidParameter) } - return handlers_acm.NewNATSACMService(natsConn).ListTagsForCertificate(ctx, input, accountID) + return utils.NATSRequest[acm.ListTagsForCertificateOutput](ctx, natsConn, "acm.ListTagsForCertificate", input, natsTimeout, accountID) } // AddTagsToCertificate — CertificateManager.AddTagsToCertificate. @@ -70,7 +74,7 @@ func AddTagsToCertificate(ctx context.Context, natsConn *nats.Conn, accountID st if err := unmarshalIfBody(body, input); err != nil { return nil, errors.New(awserrors.ErrorInvalidParameter) } - return handlers_acm.NewNATSACMService(natsConn).AddTagsToCertificate(ctx, input, accountID) + return utils.NATSRequest[acm.AddTagsToCertificateOutput](ctx, natsConn, "acm.AddTagsToCertificate", input, natsTimeout, accountID) } // RemoveTagsFromCertificate — CertificateManager.RemoveTagsFromCertificate. @@ -79,5 +83,5 @@ func RemoveTagsFromCertificate(ctx context.Context, natsConn *nats.Conn, account if err := unmarshalIfBody(body, input); err != nil { return nil, errors.New(awserrors.ErrorInvalidParameter) } - return handlers_acm.NewNATSACMService(natsConn).RemoveTagsFromCertificate(ctx, input, accountID) + return utils.NATSRequest[acm.RemoveTagsFromCertificateOutput](ctx, natsConn, "acm.RemoveTagsFromCertificate", input, natsTimeout, accountID) } diff --git a/spinifex/handlers/acm/service.go b/spinifex/handlers/acm/service.go deleted file mode 100644 index 83d0091f1..000000000 --- a/spinifex/handlers/acm/service.go +++ /dev/null @@ -1,19 +0,0 @@ -package handlers_acm - -import ( - "context" - - "github.com/aws/aws-sdk-go/service/acm" -) - -// ACMService covers BYO certificate import and lifecycle for ELBv2 HTTPS listeners. -type ACMService interface { - ImportCertificate(ctx context.Context, input *acm.ImportCertificateInput, accountID string) (*acm.ImportCertificateOutput, error) - DescribeCertificate(ctx context.Context, input *acm.DescribeCertificateInput, accountID string) (*acm.DescribeCertificateOutput, error) - GetCertificate(ctx context.Context, input *acm.GetCertificateInput, accountID string) (*acm.GetCertificateOutput, error) - ListCertificates(ctx context.Context, input *acm.ListCertificatesInput, accountID string) (*acm.ListCertificatesOutput, error) - DeleteCertificate(ctx context.Context, input *acm.DeleteCertificateInput, accountID string) (*acm.DeleteCertificateOutput, error) - ListTagsForCertificate(ctx context.Context, input *acm.ListTagsForCertificateInput, accountID string) (*acm.ListTagsForCertificateOutput, error) - AddTagsToCertificate(ctx context.Context, input *acm.AddTagsToCertificateInput, accountID string) (*acm.AddTagsToCertificateOutput, error) - RemoveTagsFromCertificate(ctx context.Context, input *acm.RemoveTagsFromCertificateInput, accountID string) (*acm.RemoveTagsFromCertificateOutput, error) -} diff --git a/spinifex/handlers/acm/service_impl.go b/spinifex/handlers/acm/service_impl.go index d6b25b9a8..5fe07ac34 100644 --- a/spinifex/handlers/acm/service_impl.go +++ b/spinifex/handlers/acm/service_impl.go @@ -45,7 +45,7 @@ type CertAuthority interface { Authorized(domain string) bool } -// ACMServiceImpl is the local, KV-backed implementation of ACMService. +// ACMServiceImpl is the local, KV-backed ACM implementation the daemon serves. type ACMServiceImpl struct { store *Store region string @@ -85,8 +85,6 @@ type ACMServiceImpl struct { CertMaterialUpdated func(ctx context.Context, certArn string) error } -var _ ACMService = (*ACMServiceImpl)(nil) - // NewACMServiceImplWithNATS builds an ACM service backed by a JetStream KV // store. cfg may be nil (tests); region then falls back to the default. // masterKey encrypts certificate private keys at rest and is required: unlike diff --git a/spinifex/handlers/acm/service_nats.go b/spinifex/handlers/acm/service_nats.go deleted file mode 100644 index ab25ec48a..000000000 --- a/spinifex/handlers/acm/service_nats.go +++ /dev/null @@ -1,56 +0,0 @@ -package handlers_acm - -import ( - "context" - "time" - - "github.com/aws/aws-sdk-go/service/acm" - "github.com/mulgadc/spinifex/spinifex/utils" - "github.com/nats-io/nats.go" -) - -const defaultTimeout = 30 * time.Second - -// NATSACMService forwards ACM operations to the daemon over NATS request/response. -type NATSACMService struct { - natsConn *nats.Conn -} - -var _ ACMService = (*NATSACMService)(nil) - -// NewNATSACMService creates a NATS-backed ACM service client. -func NewNATSACMService(conn *nats.Conn) ACMService { - return &NATSACMService{natsConn: conn} -} - -func (s *NATSACMService) ImportCertificate(ctx context.Context, input *acm.ImportCertificateInput, accountID string) (*acm.ImportCertificateOutput, error) { - return utils.NATSRequest[acm.ImportCertificateOutput](ctx, s.natsConn, "acm.ImportCertificate", input, defaultTimeout, accountID) -} - -func (s *NATSACMService) DescribeCertificate(ctx context.Context, input *acm.DescribeCertificateInput, accountID string) (*acm.DescribeCertificateOutput, error) { - return utils.NATSRequest[acm.DescribeCertificateOutput](ctx, s.natsConn, "acm.DescribeCertificate", input, defaultTimeout, accountID) -} - -func (s *NATSACMService) GetCertificate(ctx context.Context, input *acm.GetCertificateInput, accountID string) (*acm.GetCertificateOutput, error) { - return utils.NATSRequest[acm.GetCertificateOutput](ctx, s.natsConn, "acm.GetCertificate", input, defaultTimeout, accountID) -} - -func (s *NATSACMService) ListCertificates(ctx context.Context, input *acm.ListCertificatesInput, accountID string) (*acm.ListCertificatesOutput, error) { - return utils.NATSRequest[acm.ListCertificatesOutput](ctx, s.natsConn, "acm.ListCertificates", input, defaultTimeout, accountID) -} - -func (s *NATSACMService) DeleteCertificate(ctx context.Context, input *acm.DeleteCertificateInput, accountID string) (*acm.DeleteCertificateOutput, error) { - return utils.NATSRequest[acm.DeleteCertificateOutput](ctx, s.natsConn, "acm.DeleteCertificate", input, defaultTimeout, accountID) -} - -func (s *NATSACMService) ListTagsForCertificate(ctx context.Context, input *acm.ListTagsForCertificateInput, accountID string) (*acm.ListTagsForCertificateOutput, error) { - return utils.NATSRequest[acm.ListTagsForCertificateOutput](ctx, s.natsConn, "acm.ListTagsForCertificate", input, defaultTimeout, accountID) -} - -func (s *NATSACMService) AddTagsToCertificate(ctx context.Context, input *acm.AddTagsToCertificateInput, accountID string) (*acm.AddTagsToCertificateOutput, error) { - return utils.NATSRequest[acm.AddTagsToCertificateOutput](ctx, s.natsConn, "acm.AddTagsToCertificate", input, defaultTimeout, accountID) -} - -func (s *NATSACMService) RemoveTagsFromCertificate(ctx context.Context, input *acm.RemoveTagsFromCertificateInput, accountID string) (*acm.RemoveTagsFromCertificateOutput, error) { - return utils.NATSRequest[acm.RemoveTagsFromCertificateOutput](ctx, s.natsConn, "acm.RemoveTagsFromCertificate", input, defaultTimeout, accountID) -} diff --git a/spinifex/handlers/acm/service_nats_test.go b/spinifex/handlers/acm/service_nats_test.go deleted file mode 100644 index 230692c7a..000000000 --- a/spinifex/handlers/acm/service_nats_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package handlers_acm - -import ( - "context" - "testing" - - "github.com/aws/aws-sdk-go/service/acm" - "github.com/mulgadc/spinifex/spinifex/testutil" - "github.com/stretchr/testify/require" -) - -// With no daemon subscribed to acm.*, each NATS request fast-fails with -// no-responders. The point is to exercise the client delegation paths. -func TestNATSACMService_NoResponder(t *testing.T) { - _, nc, _ := testutil.StartTestJetStream(t) - svc := NewNATSACMService(nc) - - _, err := svc.ImportCertificate(context.Background(), &acm.ImportCertificateInput{}, testAccountID) - require.Error(t, err) - _, err = svc.DescribeCertificate(context.Background(), &acm.DescribeCertificateInput{}, testAccountID) - require.Error(t, err) - _, err = svc.ListCertificates(context.Background(), &acm.ListCertificatesInput{}, testAccountID) - require.Error(t, err) - _, err = svc.DeleteCertificate(context.Background(), &acm.DeleteCertificateInput{}, testAccountID) - require.Error(t, err) - _, err = svc.ListTagsForCertificate(context.Background(), &acm.ListTagsForCertificateInput{}, testAccountID) - require.Error(t, err) - _, err = svc.AddTagsToCertificate(context.Background(), &acm.AddTagsToCertificateInput{}, testAccountID) - require.Error(t, err) - _, err = svc.RemoveTagsFromCertificate(context.Background(), &acm.RemoveTagsFromCertificateInput{}, testAccountID) - require.Error(t, err) -}