Skip to content

Commit 6252cab

Browse files
authored
chore: retrieve imported certificates from manifest and ssm (#3688)
This PR reads the deployed environment's manifest before attempting reading from SSM configuration for environment for imported certs. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the Apache 2.0 License.
1 parent a90c9a5 commit 6252cab

13 files changed

+205
-101
lines changed

internal/pkg/cli/deploy/svc.go

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ type aliasCertValidator interface {
147147
ValidateCertAliases(aliases []string, certs []string) error
148148
}
149149

150+
type configDescriber interface {
151+
Manifest() ([]byte, error)
152+
}
153+
150154
type workloadDeployer struct {
151155
name string
152156
app *config.Application
@@ -165,12 +169,30 @@ type workloadDeployer struct {
165169
endpointGetter endpointGetter
166170
spinner spinner
167171
templateFS template.Reader
172+
envConfigDescriber configDescriber
168173

169174
// Cached variables.
170175
defaultSess *session.Session
171176
defaultSessWithEnvRegion *session.Session
172177
envSess *session.Session
173178
store *config.Store
179+
environmentConfig *manifest.Environment
180+
}
181+
182+
func (d *workloadDeployer) cachedEnvironmentConfig() (*manifest.Environment, error) {
183+
if d.environmentConfig != nil {
184+
return d.environmentConfig, nil
185+
}
186+
mft, err := d.envConfigDescriber.Manifest()
187+
if err != nil {
188+
return nil, fmt.Errorf("read the manifest used to deploy environment %s: %w", d.env.Name, err)
189+
}
190+
env, err := manifest.UnmarshalEnvironment(mft)
191+
if err != nil {
192+
return nil, fmt.Errorf("unmarshal the manifest used to deploy environment %s: %w", d.env.Name, err)
193+
}
194+
d.environmentConfig = env
195+
return d.environmentConfig, nil
174196
}
175197

176198
// WorkloadDeployerInput is the input to for workloadDeployer constructor.
@@ -220,7 +242,7 @@ func newWorkloadDeployer(in *WorkloadDeployerInput) (*workloadDeployer, error) {
220242
imageBuilderPusher := repository.NewWithURI(
221243
ecr.New(defaultSessEnvRegion), repoName, resources.RepositoryURLs[in.Name])
222244
store := config.NewSSMStore(identity.New(defaultSession), ssm.New(defaultSession), aws.StringValue(defaultSession.Config.Region))
223-
endpointGetter, err := describe.NewEnvDescriber(describe.NewEnvDescriberConfig{
245+
envDescriber, err := describe.NewEnvDescriber(describe.NewEnvDescriberConfig{
224246
App: in.App.Name,
225247
Env: in.Env.Name,
226248
ConfigStore: store,
@@ -240,9 +262,10 @@ func newWorkloadDeployer(in *WorkloadDeployerInput) (*workloadDeployer, error) {
240262
templater: addonsSvc,
241263
imageBuilderPusher: imageBuilderPusher,
242264
deployer: cloudformation.New(envSession),
243-
endpointGetter: endpointGetter,
265+
endpointGetter: envDescriber,
244266
spinner: termprogress.NewSpinner(log.DiagnosticWriter),
245267
templateFS: template.New(),
268+
envConfigDescriber: envDescriber,
246269

247270
defaultSess: defaultSession,
248271
defaultSessWithEnvRegion: defaultSessEnvRegion,
@@ -999,9 +1022,13 @@ func (d *lbWebSvcDeployer) stackConfiguration(in *StackRuntimeConfiguration) (*s
9991022
}
10001023
opts = append(opts, stack.WithNLB(cidrBlocks))
10011024
}
1025+
envConfig, err := d.cachedEnvironmentConfig()
1026+
if err != nil {
1027+
return nil, err
1028+
}
10021029
conf, err := stack.NewLoadBalancedWebService(stack.LoadBalancedWebServiceConfig{
10031030
App: d.app,
1004-
Env: d.env,
1031+
EnvManifest: envConfig,
10051032
Manifest: d.lbMft,
10061033
RuntimeConfig: *rc,
10071034
RootUserARN: in.RootUserARN,
@@ -1026,9 +1053,13 @@ func (d *backendSvcDeployer) stackConfiguration(in *StackRuntimeConfiguration) (
10261053
return nil, err
10271054
}
10281055

1056+
envConfig, err := d.cachedEnvironmentConfig()
1057+
if err != nil {
1058+
return nil, err
1059+
}
10291060
conf, err := stack.NewBackendService(stack.BackendServiceConfig{
10301061
App: d.app,
1031-
Env: d.env,
1062+
EnvManifest: envConfig,
10321063
Manifest: d.backendMft,
10331064
RuntimeConfig: *rc,
10341065
})
@@ -1261,15 +1292,19 @@ func (d *backendSvcDeployer) validateALBRuntime() error {
12611292
if d.backendMft.RoutingRule.IsEmpty() {
12621293
return nil
12631294
}
1295+
hasImportedCerts, err := d.envHasImportedCertificates()
1296+
if err != nil {
1297+
return err
1298+
}
12641299
switch {
1265-
case d.backendMft.RoutingRule.Alias.IsEmpty() && d.env.HasImportedCerts():
1300+
case d.backendMft.RoutingRule.Alias.IsEmpty() && hasImportedCerts:
12661301
return &errSvcWithNoALBAliasDeployingToEnvWithImportedCerts{
12671302
name: d.name,
12681303
envName: d.env.Name,
12691304
}
12701305
case d.backendMft.RoutingRule.Alias.IsEmpty():
12711306
return nil
1272-
case !d.env.HasImportedCerts():
1307+
case !hasImportedCerts:
12731308
return fmt.Errorf(`cannot specify "alias" in an environment without imported certs`)
12741309
}
12751310

@@ -1278,29 +1313,41 @@ func (d *backendSvcDeployer) validateALBRuntime() error {
12781313
return fmt.Errorf("convert aliases to string slice: %w", err)
12791314
}
12801315

1281-
if err := d.aliasCertValidator.ValidateCertAliases(aliases, d.env.CustomConfig.ImportCertARNs); err != nil {
1316+
if err := d.aliasCertValidator.ValidateCertAliases(aliases, d.environmentConfig.HTTPConfig.Private.Certificates); err != nil {
12821317
return fmt.Errorf("validate aliases against the imported certificate for env %s: %w", d.env.Name, err)
12831318
}
12841319

12851320
return nil
12861321
}
12871322

1323+
func (d *backendSvcDeployer) envHasImportedCertificates() (bool, error) {
1324+
env, err := d.cachedEnvironmentConfig()
1325+
if err != nil {
1326+
return false, err
1327+
}
1328+
return len(env.HTTPConfig.Private.Certificates) != 0, nil
1329+
}
12881330
func (d *lbWebSvcDeployer) validateALBRuntime() error {
1331+
hasImportedCerts, err := d.envHasImportedCertificates()
1332+
if err != nil {
1333+
return err
1334+
}
1335+
12891336
if d.lbMft.RoutingRule.Alias.IsEmpty() {
1290-
if d.env.HasImportedCerts() {
1337+
if hasImportedCerts {
12911338
return &errSvcWithNoALBAliasDeployingToEnvWithImportedCerts{
12921339
name: d.name,
12931340
envName: d.env.Name,
12941341
}
12951342
}
12961343
return nil
12971344
}
1298-
if d.env.HasImportedCerts() {
1345+
if hasImportedCerts {
12991346
aliases, err := d.lbMft.RoutingRule.Alias.ToStringSlice()
13001347
if err != nil {
13011348
return fmt.Errorf("convert aliases to string slice: %w", err)
13021349
}
1303-
if err := d.aliasCertValidator.ValidateCertAliases(aliases, d.env.CustomConfig.ImportCertARNs); err != nil {
1350+
if err := d.aliasCertValidator.ValidateCertAliases(aliases, d.environmentConfig.HTTPConfig.Public.Certificates); err != nil {
13041351
return fmt.Errorf("validate aliases against the imported certificate for env %s: %w", d.env.Name, err)
13051352
}
13061353
return nil
@@ -1320,7 +1367,12 @@ func (d *lbWebSvcDeployer) validateNLBRuntime() error {
13201367
if d.lbMft.NLBConfig.Aliases.IsEmpty() {
13211368
return nil
13221369
}
1323-
if d.env.HasImportedCerts() {
1370+
1371+
hasImportedCerts, err := d.envHasImportedCertificates()
1372+
if err != nil {
1373+
return err
1374+
}
1375+
if hasImportedCerts {
13241376
return fmt.Errorf("cannot specify nlb.alias when env %s imports one or more certificates", d.env.Name)
13251377
}
13261378
if d.app.Domain == "" {
@@ -1334,6 +1386,14 @@ func (d *lbWebSvcDeployer) validateNLBRuntime() error {
13341386
return validateLBWSAlias(d.lbMft.NLBConfig.Aliases, d.app, d.env.Name)
13351387
}
13361388

1389+
func (d *lbWebSvcDeployer) envHasImportedCertificates() (bool, error) {
1390+
env, err := d.cachedEnvironmentConfig()
1391+
if err != nil {
1392+
return false, err
1393+
}
1394+
return len(env.HTTPConfig.Public.Certificates) != 0, nil
1395+
}
1396+
13371397
func validateLBWSAlias(aliases manifest.Alias, app *config.Application, envName string) error {
13381398
if aliases.IsEmpty() {
13391399
return nil

internal/pkg/cli/deploy/svc_test.go

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,9 @@ func TestWorkloadDeployer_DeployWorkload(t *testing.T) {
462462
inForceDeploy bool
463463
inDisableRollback bool
464464

465+
// Cached variables.
466+
inEnvironmentConfig func() *manifest.Environment
467+
465468
mock func(m *deployMocks)
466469

467470
wantErr error
@@ -476,9 +479,11 @@ func TestWorkloadDeployer_DeployWorkload(t *testing.T) {
476479
inEnvironment: &config.Environment{
477480
Name: mockEnvName,
478481
Region: "us-west-2",
479-
CustomConfig: &config.CustomizeEnv{
480-
ImportCertARNs: mockCertARNs,
481-
},
482+
},
483+
inEnvironmentConfig: func() *manifest.Environment {
484+
envConfig := &manifest.Environment{}
485+
envConfig.HTTPConfig.Public.Certificates = mockCertARNs
486+
return envConfig
482487
},
483488
inApp: &config.Application{
484489
Name: mockAppName,
@@ -492,9 +497,11 @@ func TestWorkloadDeployer_DeployWorkload(t *testing.T) {
492497
inEnvironment: &config.Environment{
493498
Name: mockEnvName,
494499
Region: "us-west-2",
495-
CustomConfig: &config.CustomizeEnv{
496-
ImportCertARNs: mockCertARNs,
497-
},
500+
},
501+
inEnvironmentConfig: func() *manifest.Environment {
502+
envConfig := &manifest.Environment{}
503+
envConfig.HTTPConfig.Public.Certificates = mockCertARNs
504+
return envConfig
498505
},
499506
inAliases: manifest.Alias{
500507
AdvancedAliases: mockMultiAliases,
@@ -565,9 +572,11 @@ func TestWorkloadDeployer_DeployWorkload(t *testing.T) {
565572
inEnvironment: &config.Environment{
566573
Name: mockEnvName,
567574
Region: "us-west-2",
568-
CustomConfig: &config.CustomizeEnv{
569-
ImportCertARNs: mockCertARNs,
570-
},
575+
},
576+
inEnvironmentConfig: func() *manifest.Environment {
577+
envConfig := &manifest.Environment{}
578+
envConfig.HTTPConfig.Public.Certificates = mockCertARNs
579+
return envConfig
571580
},
572581
inApp: &config.Application{
573582
Name: mockAppName,
@@ -798,9 +807,11 @@ func TestWorkloadDeployer_DeployWorkload(t *testing.T) {
798807
inEnvironment: &config.Environment{
799808
Name: mockEnvName,
800809
Region: "us-west-2",
801-
CustomConfig: &config.CustomizeEnv{
802-
ImportCertARNs: mockCertARNs,
803-
},
810+
},
811+
inEnvironmentConfig: func() *manifest.Environment {
812+
envConfig := &manifest.Environment{}
813+
envConfig.HTTPConfig.Public.Certificates = mockCertARNs
814+
return envConfig
804815
},
805816
inApp: &config.Application{
806817
Name: mockAppName,
@@ -850,16 +861,22 @@ func TestWorkloadDeployer_DeployWorkload(t *testing.T) {
850861
}
851862
tc.mock(m)
852863

864+
if tc.inEnvironmentConfig == nil {
865+
tc.inEnvironmentConfig = func() *manifest.Environment {
866+
return &manifest.Environment{}
867+
}
868+
}
853869
deployer := lbWebSvcDeployer{
854870
svcDeployer: &svcDeployer{
855871
workloadDeployer: &workloadDeployer{
856-
name: mockName,
857-
app: tc.inApp,
858-
env: tc.inEnvironment,
859-
resources: mockResources,
860-
deployer: m.mockServiceDeployer,
861-
endpointGetter: m.mockEndpointGetter,
862-
spinner: m.mockSpinner,
872+
name: mockName,
873+
app: tc.inApp,
874+
env: tc.inEnvironment,
875+
environmentConfig: tc.inEnvironmentConfig(),
876+
resources: mockResources,
877+
deployer: m.mockServiceDeployer,
878+
endpointGetter: m.mockEndpointGetter,
879+
spinner: m.mockSpinner,
863880
},
864881
newSvcUpdater: func(f func(*session.Session) serviceForceUpdater) serviceForceUpdater {
865882
return m.mockServiceForceUpdater
@@ -1276,9 +1293,13 @@ func TestBackendSvcDeployer_stackConfiguration(t *testing.T) {
12761293
)
12771294

12781295
tests := map[string]struct {
1279-
App *config.Application
1280-
Env *config.Environment
1281-
Manifest *manifest.BackendService
1296+
App *config.Application
1297+
Env *config.Environment
1298+
Manifest *manifest.BackendService
1299+
1300+
// Cached variables.
1301+
inEnvironmentConfig func() *manifest.Environment
1302+
12821303
setupMocks func(m *deployMocks)
12831304

12841305
expectedErr string
@@ -1324,9 +1345,11 @@ func TestBackendSvcDeployer_stackConfiguration(t *testing.T) {
13241345
},
13251346
Env: &config.Environment{
13261347
Name: mockEnvName,
1327-
CustomConfig: &config.CustomizeEnv{
1328-
ImportCertARNs: []string{"mockCertARN"},
1329-
},
1348+
},
1349+
inEnvironmentConfig: func() *manifest.Environment {
1350+
envConfig := &manifest.Environment{}
1351+
envConfig.HTTPConfig.Private.Certificates = []string{"mockCertARN"}
1352+
return envConfig
13301353
},
13311354
Manifest: &manifest.BackendService{
13321355
BackendServiceConfig: manifest.BackendServiceConfig{
@@ -1351,9 +1374,11 @@ func TestBackendSvcDeployer_stackConfiguration(t *testing.T) {
13511374
},
13521375
Env: &config.Environment{
13531376
Name: mockEnvName,
1354-
CustomConfig: &config.CustomizeEnv{
1355-
ImportCertARNs: []string{"mockCertARN"},
1356-
},
1377+
},
1378+
inEnvironmentConfig: func() *manifest.Environment {
1379+
envConfig := &manifest.Environment{}
1380+
envConfig.HTTPConfig.Private.Certificates = []string{"mockCertARN"}
1381+
return envConfig
13571382
},
13581383
Manifest: &manifest.BackendService{
13591384
BackendServiceConfig: manifest.BackendServiceConfig{
@@ -1377,9 +1402,11 @@ func TestBackendSvcDeployer_stackConfiguration(t *testing.T) {
13771402
},
13781403
Env: &config.Environment{
13791404
Name: mockEnvName,
1380-
CustomConfig: &config.CustomizeEnv{
1381-
ImportCertARNs: []string{"mockCertARN"},
1382-
},
1405+
},
1406+
inEnvironmentConfig: func() *manifest.Environment {
1407+
envConfig := &manifest.Environment{}
1408+
envConfig.HTTPConfig.Private.Certificates = []string{"mockCertARN"}
1409+
return envConfig
13831410
},
13841411
Manifest: &manifest.BackendService{
13851412
BackendServiceConfig: manifest.BackendServiceConfig{
@@ -1422,14 +1449,19 @@ func TestBackendSvcDeployer_stackConfiguration(t *testing.T) {
14221449
if tc.setupMocks != nil {
14231450
tc.setupMocks(m)
14241451
}
1425-
1452+
if tc.inEnvironmentConfig == nil {
1453+
tc.inEnvironmentConfig = func() *manifest.Environment {
1454+
return &manifest.Environment{}
1455+
}
1456+
}
14261457
deployer := &backendSvcDeployer{
14271458
svcDeployer: &svcDeployer{
14281459
workloadDeployer: &workloadDeployer{
1429-
name: mockSvcName,
1430-
app: tc.App,
1431-
env: tc.Env,
1432-
endpointGetter: m.mockEndpointGetter,
1460+
name: mockSvcName,
1461+
app: tc.App,
1462+
env: tc.Env,
1463+
endpointGetter: m.mockEndpointGetter,
1464+
environmentConfig: tc.inEnvironmentConfig(),
14331465
},
14341466
newSvcUpdater: func(f func(*session.Session) serviceForceUpdater) serviceForceUpdater {
14351467
return nil

internal/pkg/config/env.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,6 @@ type Environment struct {
2727
Telemetry *Telemetry `json:"telemetry,omitempty"` // Optional environment telemetry features.
2828
}
2929

30-
// HasImportedCerts return if the environment has imported certs.
31-
func (e *Environment) HasImportedCerts() bool {
32-
return e.CustomConfig != nil && len(e.CustomConfig.ImportCertARNs) != 0
33-
}
34-
3530
// CustomizeEnv represents the custom environment config.
3631
type CustomizeEnv struct {
3732
ImportVPC *ImportVPC `json:"importVPC,omitempty"`

0 commit comments

Comments
 (0)