Skip to content

Commit

Permalink
added multiple deploy apps\stacks
Browse files Browse the repository at this point in the history
  • Loading branch information
psihachina committed Oct 12, 2022
1 parent 8a973ac commit 2949d48
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 45 deletions.
35 changes: 16 additions & 19 deletions internal/commands/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import (

type UpOptions struct {
Config *config.Project
AppName string
SkipBuildAndPush bool
SkipGen bool
AutoApprove bool
UI terminal.UI
Apps []string
}

type Apps map[string]*interface{}
Expand Down Expand Up @@ -60,7 +60,6 @@ func NewCmdUp(project *config.Project) *cobra.Command {
Example: upExample,
Short: "Bring full application up from the bottom to the top.",
Long: upLongDesc,
Args: cobra.MaximumNArgs(1),
ValidArgsFunction: config.GetApps,
RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
Expand Down Expand Up @@ -139,7 +138,7 @@ func (o *UpOptions) Complete(cmd *cobra.Command, args []string) error {
}
}

o.AppName = cmd.Flags().Args()[0]
o.Apps = cmd.Flags().Args()
}

o.UI = terminal.ConsoleUI(context.Background(), o.Config.PlainText)
Expand All @@ -148,13 +147,13 @@ func (o *UpOptions) Complete(cmd *cobra.Command, args []string) error {
}

func (o *UpOptions) Validate() error {
if o.AppName == "" {
err := o.validateAll()
if len(o.Apps) > 0 {
err := o.validate()
if err != nil {
return err
}
} else {
err := o.validate()
err := o.validateAll()
if err != nil {
return err
}
Expand All @@ -165,20 +164,22 @@ func (o *UpOptions) Validate() error {

func (o *UpOptions) Run() error {
ui := o.UI
if o.AppName == "" {
err := deployAll(ui, o)
if len(o.Apps) > 0 {
err := manager.InDependencyOrder(aws.BackgroundContext(), o.Config.GetStates(o.Apps...), func(c context.Context, name string) error {
return deployInfra(name, ui, o.Config, o.SkipGen)
})
if err != nil {
return err
}
} else {
if _, ok := o.Config.Terraform[o.AppName]; ok {
err := deployInfra(o.AppName, ui, o.Config, o.SkipGen)
if err != nil {
return err
}
err = manager.InDependencyOrder(aws.BackgroundContext(), o.Config.GetApps(o.Apps...), func(c context.Context, name string) error {
return deployApp(name, ui, o.Config)
})
if err != nil {
return err
}

err := deployApp(o.AppName, ui, o.Config)
} else {
err := deployAll(ui, o)
if err != nil {
return err
}
Expand All @@ -196,10 +197,6 @@ func (o *UpOptions) validate() error {
return fmt.Errorf("can't validate options: namespace must be specified")
}

if len(o.AppName) == 0 {
return fmt.Errorf("can't validate options: app name must be specified")
}

return nil
}

Expand Down
93 changes: 67 additions & 26 deletions internal/config/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,48 +134,89 @@ func (p *Project) SettingAWSClient(sess *session.Session) {
)
}

func (p *Project) GetApps() map[string]*interface{} {
func (p *Project) GetApps(names ...string) map[string]*interface{} {
apps := map[string]*interface{}{}

for name, body := range p.Ecs {
var v interface{}
v = map[string]interface{}{
"depends_on": body.DependsOn,
if len(names) > 0 {
for _, name := range names {
if s, ok := p.Ecs[name]; ok {
var v interface{}
v = map[string]interface{}{
"depends_on": s.DependsOn,
}
apps[name] = &v
}
if s, ok := p.Serverless[name]; ok {
var v interface{}
v = map[string]interface{}{
"depends_on": s.DependsOn,
}
apps[name] = &v
}
if s, ok := p.Alias[name]; ok {
var v interface{}
v = map[string]interface{}{
"depends_on": s.DependsOn,
}
apps[name] = &v
}
}
} else {
for name, body := range p.Ecs {
var v interface{}
v = map[string]interface{}{
"depends_on": body.DependsOn,
}
apps[name] = &v
}
apps[name] = &v
}

for name, body := range p.Serverless {
var v interface{}
v = map[string]interface{}{
"depends_on": body.DependsOn,
for name, body := range p.Serverless {
var v interface{}
v = map[string]interface{}{
"depends_on": body.DependsOn,
}
apps[name] = &v
}
apps[name] = &v
}

for name, body := range p.Alias {
var v interface{}
v = map[string]interface{}{
"depends_on": body.DependsOn,
for name, body := range p.Alias {
var v interface{}
v = map[string]interface{}{
"depends_on": body.DependsOn,
}
apps[name] = &v
}
apps[name] = &v
}

return apps
}

func (p *Project) GetStates() map[string]*interface{} {
func (p *Project) GetStates(stacks ...string) map[string]*interface{} {
states := map[string]*interface{}{}

for name, body := range p.Terraform {
if name == "infra" {
continue
if len(stacks) > 0 {
for _, stack := range stacks {
if stack == "infra" {
continue
}
if s, ok := p.Terraform[stack]; ok {
var v interface{}
v = map[string]interface{}{
"depends_on": s.DependsOn,
}
states[stack] = &v
}
}
var v interface{}
v = map[string]interface{}{
"depends_on": body.DependsOn,
} else {
for name, body := range p.Terraform {
if name == "infra" {
continue
}
var v interface{}
v = map[string]interface{}{
"depends_on": body.DependsOn,
}
states[name] = &v
}
states[name] = &v
}

return states
Expand Down
117 changes: 117 additions & 0 deletions internal/config/project_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package config

import (
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
"testing"
)

func TestProject_GetStates(t *testing.T) {
type fields struct {
Terraform map[string]*Terraform
}
type args struct {
stacks []string
}
tests := []struct {
name string
fields fields
args args
want map[string]*interface{}
}{
{name: "success", fields: fields{
Terraform: map[string]*Terraform{
"test": {},
"test1": {},
"test2": {},
"test3": {},
},
}, args: args{}, want: map[string]*interface{}{"test": nil, "test1": nil, "test2": nil, "test3": nil}},
{name: "success", fields: fields{
Terraform: map[string]*Terraform{
"test": {},
"test1": {},
"test2": {},
"test3": {},
},
}, args: args{stacks: []string{"test", "test2"}}, want: map[string]*interface{}{"test": nil, "test2": nil}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Project{
Terraform: tt.fields.Terraform,
}
got := p.GetStates(tt.args.stacks...)
gotKeys := maps.Keys(got)
wantKeys := maps.Keys(tt.want)
slices.Sort(gotKeys)
slices.Sort(wantKeys)
if !slices.Equal(gotKeys, wantKeys) {
t.Errorf("GetStates() = %v, want %v", maps.Keys(got), maps.Keys(tt.want))
}
})
}
}

func TestProject_GetApps(t *testing.T) {
type fields struct {
Serverless map[string]*Serverless
Ecs map[string]*Ecs
Alias map[string]*Alias
}
type args struct {
names []string
}
tests := []struct {
name string
fields fields
args args
want map[string]*interface{}
}{
{name: "success", fields: fields{
Serverless: map[string]*Serverless{
"testSls1": {},
"testSls2": {},
},
Ecs: map[string]*Ecs{
"testEcs1": {},
"testEcs2": {},
},
Alias: map[string]*Alias{
"testAlias1": {},
"testAlias2": {},
},
}, args: args{}, want: map[string]*interface{}{"testAlias1": nil, "testAlias2": nil, "testEcs1": nil, "testEcs2": nil, "testSls2": nil, "testSls1": nil}},
{name: "success", fields: fields{
Serverless: map[string]*Serverless{
"testSls1": {},
"testSls2": {},
},
Ecs: map[string]*Ecs{
"testEcs1": {},
"testEcs2": {},
},
Alias: map[string]*Alias{
"testAlias1": {},
"testAlias2": {},
},
}, args: args{names: []string{"testSls1", "testAlias1"}}, want: map[string]*interface{}{"testSls1": nil, "testAlias1": nil}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Project{
Ecs: tt.fields.Ecs,
Serverless: tt.fields.Serverless,
Alias: tt.fields.Alias,
}
got := p.GetApps(tt.args.names...)
gotKeys := maps.Keys(got)
wantKeys := maps.Keys(tt.want)
slices.Sort(gotKeys)
slices.Sort(wantKeys)
if !slices.Equal(gotKeys, wantKeys) {
t.Errorf("GetStates() = %v, want %v", maps.Keys(got), maps.Keys(tt.want))
}
})
}
}

0 comments on commit 2949d48

Please sign in to comment.