func newPackageSvcOpts()

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
}