Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ COPY --from=builder \
/opt/boulder/bin/boulder \
/opt/boulder/bin/chall-test-srv \
/opt/boulder/bin/ct-test-srv \
/opt/boulder/bin/pardot-test-srv \
/opt/boulder/bin/salesforce-test-srv \
/opt/boulder/bin/zendesk-test-srv \
/opt/boulder/bin/
COPY --from=builder /opt/boulder/data /opt/boulder/data
Expand Down
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ VERSION ?= 1.0.0
EPOCH ?= 1
MAINTAINER ?= "Community"

CMDS = admin boulder ceremony ct-test-srv pardot-test-srv chall-test-srv zendesk-test-srv
# TODO(#8410): Remove pardot-test-srv when we've fully migrated to
# salesforce-test-srv.
CMDS = admin boulder ceremony ct-test-srv salesforce-test-srv pardot-test-srv chall-test-srv zendesk-test-srv
CMD_BINS = $(addprefix bin/, $(CMDS) )
OBJECTS = $(CMD_BINS)

Expand Down Expand Up @@ -35,6 +37,11 @@ $(OBJDIR):

$(CMD_BINS): build_cmds

# TODO(#8410): Remove bin/pardot-test-srv when we've fully migrated to
# salesforce-test-srv.
bin/pardot-test-srv: bin/salesforce-test-srv
cp bin/salesforce-test-srv $@

build_cmds: | $(OBJDIR)
echo $(OBJECTS)
GOBIN=$(OBJDIR) go install -mod=vendor $(GO_BUILD_FLAGS) ./...
Expand Down
6 changes: 3 additions & 3 deletions cmd/boulder-wfe2/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (

"github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/config"
emailpb "github.com/letsencrypt/boulder/email/proto"
"github.com/letsencrypt/boulder/features"
"github.com/letsencrypt/boulder/goodkey"
"github.com/letsencrypt/boulder/goodkey/sagoodkey"
Expand All @@ -26,6 +25,7 @@ import (
"github.com/letsencrypt/boulder/ratelimits"
bredis "github.com/letsencrypt/boulder/redis"
sapb "github.com/letsencrypt/boulder/sa/proto"
salesforcepb "github.com/letsencrypt/boulder/salesforce/proto"
"github.com/letsencrypt/boulder/unpause"
"github.com/letsencrypt/boulder/web"
"github.com/letsencrypt/boulder/wfe2"
Expand Down Expand Up @@ -286,11 +286,11 @@ func main() {
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
sac := sapb.NewStorageAuthorityReadOnlyClient(saConn)

var eec emailpb.ExporterClient
var eec salesforcepb.ExporterClient
if c.WFE.EmailExporter != nil {
emailExporterConn, err := bgrpc.ClientSetup(c.WFE.EmailExporter, tlsConfig, stats, clk)
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to email-exporter")
eec = emailpb.NewExporterClient(emailExporterConn)
eec = salesforcepb.NewExporterClient(emailExporterConn)
}

if c.WFE.RedeemNonceService == nil {
Expand Down
62 changes: 50 additions & 12 deletions cmd/email-exporter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import (
"os"

"github.com/jmhodges/clock"
"google.golang.org/protobuf/types/known/emptypb"

"github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/email"
emailpb "github.com/letsencrypt/boulder/email/proto"
bgrpc "github.com/letsencrypt/boulder/grpc"
"github.com/letsencrypt/boulder/salesforce"
emailpb "github.com/letsencrypt/boulder/salesforce/email/proto"
salesforcepb "github.com/letsencrypt/boulder/salesforce/proto"
)

// Config holds the configuration for the email-exporter service.
Expand Down Expand Up @@ -62,6 +64,38 @@ type Config struct {
OpenTelemetry cmd.OpenTelemetryConfig
}

// legacyEmailExporterServer is an adapter that implements the email.Exporter
// gRPC interface by delegating to an inner salesforce.Exporter server.
//
// TODO(#8410): Remove legacyEmailExporterServer once fully migrated to
// salesforcepb.Exporter.
type legacyEmailExporterServer struct {
emailpb.UnimplementedExporterServer
inner salesforcepb.ExporterServer
}

// SendContacts is an interface adapter that forwards the request to the same
// method on the inner salesforce.Exporter server.
func (s legacyEmailExporterServer) SendContacts(ctx context.Context, req *emailpb.SendContactsRequest) (*emptypb.Empty, error) {
return s.inner.SendContacts(ctx, &salesforcepb.SendContactsRequest{Emails: req.GetEmails()})
}

// SendCase is an interface adapter that forwards the request to the same method
// on the inner salesforce.Exporter server.
func (s legacyEmailExporterServer) SendCase(ctx context.Context, req *emailpb.SendCaseRequest) (*emptypb.Empty, error) {
return s.inner.SendCase(ctx, &salesforcepb.SendCaseRequest{
Origin: req.GetOrigin(),
Subject: req.GetSubject(),
Description: req.GetDescription(),
ContactEmail: req.GetContactEmail(),
Organization: req.GetOrganization(),
AccountId: req.GetAccountId(),
RateLimitName: req.GetRateLimitName(),
RateLimitTier: req.GetRateLimitTier(),
UseCase: req.GetUseCase(),
})
}

func main() {
configFile := flag.String("config", "", "Path to configuration file")
grpcAddr := flag.String("addr", "", "gRPC listen address override")
Expand Down Expand Up @@ -95,12 +129,12 @@ func main() {
clientSecret, err := c.EmailExporter.ClientSecret.Pass()
cmd.FailOnError(err, "Loading clientSecret")

var cache *email.EmailCache
var cache *salesforce.EmailCache
if c.EmailExporter.EmailCacheSize > 0 {
cache = email.NewHashedEmailCache(c.EmailExporter.EmailCacheSize, scope)
cache = salesforce.NewHashedEmailCache(c.EmailExporter.EmailCacheSize, scope)
}

sfClient, err := email.NewSalesforceClientImpl(
sfClient, err := salesforce.NewSalesforceClientImpl(
clk,
c.EmailExporter.PardotBusinessUnit,
clientId,
Expand All @@ -109,21 +143,25 @@ func main() {
c.EmailExporter.PardotBaseURL,
)
cmd.FailOnError(err, "Creating Pardot API client")
exporterServer := email.NewExporterImpl(sfClient, cache, c.EmailExporter.PerDayLimit, c.EmailExporter.MaxConcurrentRequests, scope, logger)
server := salesforce.NewExporterImpl(sfClient, cache, c.EmailExporter.PerDayLimit, c.EmailExporter.MaxConcurrentRequests, scope, logger)

tlsConfig, err := c.EmailExporter.TLS.Load(scope)
cmd.FailOnError(err, "Loading email-exporter TLS config")

daemonCtx, shutdownExporterServer := context.WithCancel(context.Background())
go exporterServer.Start(daemonCtx)
daemonCtx, shutdown := context.WithCancel(context.Background())
go server.Start(daemonCtx)

start, err := bgrpc.NewServer(c.EmailExporter.GRPC, logger).Add(
&emailpb.Exporter_ServiceDesc, exporterServer).Build(tlsConfig, scope, clk)
srv := bgrpc.NewServer(c.EmailExporter.GRPC, logger)
srv = srv.Add(&salesforcepb.Exporter_ServiceDesc, server)
// TODO(#8410): Remove emailpb.Exporter once fully migrated to
// salesforcepb.Exporter.
srv = srv.Add(&emailpb.Exporter_ServiceDesc, legacyEmailExporterServer{inner: server})
start, err := srv.Build(tlsConfig, scope, clk)
cmd.FailOnError(err, "Configuring email-exporter gRPC server")

err = start()
shutdownExporterServer()
exporterServer.Drain()
shutdown()
server.Drain()
cmd.FailOnError(err, "email-exporter gRPC service failed to start")
}

Expand Down
6 changes: 3 additions & 3 deletions cmd/sfe/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import (

"github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/config"
emailpb "github.com/letsencrypt/boulder/email/proto"
"github.com/letsencrypt/boulder/features"
bgrpc "github.com/letsencrypt/boulder/grpc"
rapb "github.com/letsencrypt/boulder/ra/proto"
"github.com/letsencrypt/boulder/ratelimits"
bredis "github.com/letsencrypt/boulder/redis"
sapb "github.com/letsencrypt/boulder/sa/proto"
salesforcepb "github.com/letsencrypt/boulder/salesforce/proto"
"github.com/letsencrypt/boulder/sfe"
"github.com/letsencrypt/boulder/sfe/zendesk"
"github.com/letsencrypt/boulder/web"
Expand Down Expand Up @@ -156,11 +156,11 @@ func main() {
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
sac := sapb.NewStorageAuthorityReadOnlyClient(saConn)

var eec emailpb.ExporterClient
var eec salesforcepb.ExporterClient
if c.SFE.EmailExporter != nil {
emailExporterConn, err := bgrpc.ClientSetup(c.SFE.EmailExporter, tlsConfig, stats, clk)
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to email-exporter")
eec = emailpb.NewExporterClient(emailExporterConn)
eec = salesforcepb.NewExporterClient(emailExporterConn)
}

var zendeskClient *zendesk.Client
Expand Down
30 changes: 15 additions & 15 deletions mocks/emailexporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ import (
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/emptypb"

"github.com/letsencrypt/boulder/email"
emailpb "github.com/letsencrypt/boulder/email/proto"
"github.com/letsencrypt/boulder/salesforce"
salesforcepb "github.com/letsencrypt/boulder/salesforce/proto"
)

var _ email.SalesforceClient = (*MockSalesforceClientImpl)(nil)
var _ salesforce.SalesforceClient = (*MockSalesforceClientImpl)(nil)

// MockSalesforceClientImpl is a mock implementation of email.SalesforceClient.
// MockSalesforceClientImpl is a mock implementation of salesforce.SalesforceClient.
type MockSalesforceClientImpl struct {
sync.Mutex
CreatedContacts []string
CreatedCases []email.Case
CreatedCases []salesforce.Case
}

// NewMockSalesforceClientImpl returns a MockSalesforceClientImpl, which implements
Expand Down Expand Up @@ -48,7 +48,7 @@ func (m *MockSalesforceClientImpl) GetCreatedContacts() []string {
}

// SendCase adds a case payload to CreatedCases.
func (m *MockSalesforceClientImpl) SendCase(payload email.Case) error {
func (m *MockSalesforceClientImpl) SendCase(payload salesforce.Case) error {
m.Lock()
defer m.Unlock()

Expand All @@ -58,31 +58,31 @@ func (m *MockSalesforceClientImpl) SendCase(payload email.Case) error {

// GetCreatedCases is used for testing to retrieve the list of created cases in
// a thread-safe manner.
func (m *MockSalesforceClientImpl) GetCreatedCases() []email.Case {
func (m *MockSalesforceClientImpl) GetCreatedCases() []salesforce.Case {
m.Lock()
defer m.Unlock()

// Return a copy to avoid race conditions.
return slices.Clone(m.CreatedCases)
}

var _ emailpb.ExporterClient = (*MockExporterClientImpl)(nil)
var _ salesforcepb.ExporterClient = (*MockExporterClientImpl)(nil)

// MockExporterClientImpl is a mock implementation of ExporterClient.
type MockExporterClientImpl struct {
SalesforceClient email.SalesforceClient
SalesforceClient salesforce.SalesforceClient
}

// NewMockExporterImpl returns a MockExporterClientImpl as an ExporterClient.
func NewMockExporterImpl(salesforceClient email.SalesforceClient) emailpb.ExporterClient {
func NewMockExporterImpl(salesforceClient salesforce.SalesforceClient) salesforcepb.ExporterClient {
return &MockExporterClientImpl{
SalesforceClient: salesforceClient,
}
}

// SendContacts submits emails to the inner email.SalesforceClient, returning an
// SendContacts submits emails to the inner salesforce.SalesforceClient, returning an
// error if any fail.
func (m *MockExporterClientImpl) SendContacts(ctx context.Context, req *emailpb.SendContactsRequest, _ ...grpc.CallOption) (*emptypb.Empty, error) {
func (m *MockExporterClientImpl) SendContacts(ctx context.Context, req *salesforcepb.SendContactsRequest, _ ...grpc.CallOption) (*emptypb.Empty, error) {
for _, e := range req.Emails {
err := m.SalesforceClient.SendContact(e)
if err != nil {
Expand All @@ -92,9 +92,9 @@ func (m *MockExporterClientImpl) SendContacts(ctx context.Context, req *emailpb.
return &emptypb.Empty{}, nil
}

// SendCase submits a Case using the inner email.SalesforceClient.
func (m *MockExporterClientImpl) SendCase(ctx context.Context, req *emailpb.SendCaseRequest, _ ...grpc.CallOption) (*emptypb.Empty, error) {
return &emptypb.Empty{}, m.SalesforceClient.SendCase(email.Case{
// SendCase submits a Case using the inner salesforce.SalesforceClient.
func (m *MockExporterClientImpl) SendCase(ctx context.Context, req *salesforcepb.SendCaseRequest, _ ...grpc.CallOption) (*emptypb.Empty, error) {
return &emptypb.Empty{}, m.SalesforceClient.SendCase(salesforce.Case{
Origin: req.Origin,
Subject: req.Subject,
Description: req.Description,
Expand Down
2 changes: 1 addition & 1 deletion email/cache.go → salesforce/cache.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package email
package salesforce

import (
"crypto/sha256"
Expand Down
Loading