in internal/pkg/cli/svc_package.go [83:262]
func newPackageSvcOpts(vars packageSvcVars) (*packageSvcOpts, error) {
ws, err := workspace.New()
if err != nil {
return nil, fmt.Errorf("new workspace: %w", err)
}
store, err := config.NewStore()
if err != nil {
return nil, fmt.Errorf("connect to config store: %w", err)
}
deployStore, err := deploy.NewStore(store)
if err != nil {
return nil, fmt.Errorf("new deploy store: %w", err)
}
p := sessions.NewProvider()
sess, err := p.Default()
if err != nil {
return nil, fmt.Errorf("retrieve default session: %w", err)
}
prompter := prompt.New()
opts := &packageSvcOpts{
packageSvcVars: vars,
initAddonsClient: initPackageAddonsClient,
ws: ws,
store: store,
appCFN: cloudformation.New(sess),
runner: exec.NewCmd(),
sel: selector.NewWorkspaceSelect(prompter, store, ws),
prompt: prompter,
identity: identity.New(sess),
stackWriter: os.Stdout,
paramsWriter: ioutil.Discard,
addonsWriter: ioutil.Discard,
fs: &afero.Afero{Fs: afero.NewOsFs()},
snsTopicGetter: deployStore,
newInterpolator: newManifestInterpolator,
}
appVersionGetter, err := describe.NewAppDescriber(vars.appName)
if err != nil {
return nil, fmt.Errorf("new app describer for application %s: %w", vars.name, err)
}
opts.stackSerializer = func(mft interface{}, env *config.Environment, app *config.Application, rc stack.RuntimeConfig) (stackSerializer, error) {
var serializer stackSerializer
switch t := mft.(type) {
case *manifest.LoadBalancedWebService:
if err := validateLBWSRuntime(app, env.Name, t, appVersionGetter); err != nil {
return nil, err
}
var options []stack.LoadBalancedWebServiceOption
if !t.NLBConfig.IsEmpty() {
envDescriber, err := describe.NewEnvDescriber(describe.NewEnvDescriberConfig{
App: app.Name,
Env: env.Name,
ConfigStore: store,
DeployStore: deployStore,
})
if err != nil {
return nil, fmt.Errorf("create describer for environment %s in application %s: %w", env.Name, app.Name, err)
}
cidrBlocks, err := envDescriber.PublicCIDRBlocks()
if err != nil {
return nil, err
}
options = append(options, stack.WithNLB(cidrBlocks))
}
if app.RequiresDNSDelegation() {
var caller identity.Caller
caller, err = opts.identity.Get()
if err != nil {
return nil, fmt.Errorf("get identity: %w", err)
}
options = append(options, stack.WithDNSDelegation(deploy.AppInformation{
Name: env.App,
DNSName: app.Domain,
AccountPrincipalARN: caller.RootUserARN,
}))
if !t.RoutingRule.Disabled() {
options = append(options, stack.WithHTTPS())
}
}
serializer, err = stack.NewLoadBalancedWebService(t, env.Name, app.Name, rc, options...)
if err != nil {
return nil, fmt.Errorf("init load balanced web service stack serializer: %w", err)
}
case *manifest.RequestDrivenWebService:
caller, err := opts.identity.Get()
if err != nil {
return nil, fmt.Errorf("get identity: %w", err)
}
appInfo := deploy.AppInformation{
Name: env.App,
DNSName: app.Domain,
AccountPrincipalARN: caller.RootUserARN,
}
if t.Alias == nil {
serializer, err = stack.NewRequestDrivenWebService(t, env.Name, appInfo, rc)
if err != nil {
return nil, fmt.Errorf("init request-driven web service stack serializer: %w", err)
}
break
}
if err = validateRDSvcAliasAndAppVersion(opts.name, aws.StringValue(t.Alias), env.Name, app, appVersionGetter); err != nil {
return nil, err
}
resources, err := opts.appCFN.GetAppResourcesByRegion(app, env.Region)
if err != nil {
return nil, fmt.Errorf("get application %s resources from region %s: %w", app.Name, env.Region, err)
}
urls, err := uploadRDWSCustomResources(&uploadCustomResourcesOpts{
uploader: template.New(),
newS3Uploader: func() (uploader, error) {
envRegion := env.Region
sess, err := p.DefaultWithRegion(env.Region)
if err != nil {
return nil, fmt.Errorf("create session with region %s: %w", envRegion, err)
}
s3Client := s3.New(sess)
return s3Client, nil
},
}, resources)
if err != nil {
return nil, err
}
serializer, err = stack.NewRequestDrivenWebServiceWithAlias(t, env.Name, appInfo, rc, urls)
if err != nil {
return nil, fmt.Errorf("init request-driven web service stack serializer: %w", err)
}
case *manifest.BackendService:
serializer, err = stack.NewBackendService(t, env.Name, app.Name, rc)
if err != nil {
return nil, fmt.Errorf("init backend service stack serializer: %w", err)
}
case *manifest.WorkerService:
var topics []deploy.Topic
topics, err = opts.snsTopicGetter.ListSNSTopics(opts.appName, opts.envName)
if err != nil {
return nil, err
}
var topicARNs []string
for _, topic := range topics {
topicARNs = append(topicARNs, topic.ARN())
}
type subscriptions interface {
Subscriptions() []manifest.TopicSubscription
}
subscriptionGetter, ok := mft.(subscriptions)
if !ok {
return nil, errors.New("manifest does not have required method Subscriptions")
}
// Cache the subscriptions for later.
topicSubs := subscriptionGetter.Subscriptions()
if err = validateTopicsExist(topicSubs, topicARNs, app.Name, env.Name); err != nil {
return nil, err
}
serializer, err = stack.NewWorkerService(t, env.Name, app.Name, rc)
if err != nil {
return nil, fmt.Errorf("init worker service stack serializer: %w", err)
}
default:
return nil, fmt.Errorf("create stack serializer for manifest of type %T", t)
}
return serializer, nil
}
opts.newEndpointGetter = func(app, env string) (endpointGetter, error) {
d, err := describe.NewEnvDescriber(describe.NewEnvDescriberConfig{
App: app,
Env: env,
ConfigStore: store,
})
if err != nil {
return nil, fmt.Errorf("new env describer for environment %s in app %s: %v", env, app, err)
}
return d, nil
}
return opts, nil
}