github.com/hazelops/ize@v1.1.12-0.20230915191306-97d7c0e48f11/internal/commands/deploy.go (about) 1 package commands 2 3 import ( 4 "fmt" 5 6 "github.com/aws/aws-sdk-go/aws" 7 "github.com/hazelops/ize/internal/config" 8 "github.com/hazelops/ize/internal/manager" 9 "github.com/hazelops/ize/internal/manager/alias" 10 "github.com/hazelops/ize/internal/manager/ecs" 11 "github.com/hazelops/ize/internal/manager/serverless" 12 "github.com/hazelops/ize/internal/requirements" 13 "github.com/hazelops/ize/pkg/templates" 14 "github.com/hazelops/ize/pkg/terminal" 15 "github.com/spf13/cobra" 16 ) 17 18 type DeployOptions struct { 19 Config *config.Project 20 AppName string 21 Image string 22 TaskDefinitionRevision string 23 Unsafe bool 24 Force bool 25 } 26 27 var deployLongDesc = templates.LongDesc(` 28 Deploy service. 29 App name must be specified for a app deploy. 30 31 If you install a revision of the task definition, the application will be redeployed (ECS only). 32 Warning: Redeployment using the docker runtime, a new task definition will be deployed based on the specified revision. 33 `) 34 35 var deployExample = templates.Examples(` 36 # Deploy app (config file required) 37 ize deploy <app name> 38 39 # Deploy app via config file 40 ize --config-file (or -c) /path/to/config deploy <app name> 41 42 # Deploy app via config file installed from env 43 export IZE_CONFIG_FILE=/path/to/config 44 ize deploy <app name> 45 46 # Redeploy app (ECS only) 47 ize deploy <app name> --task-definition-revision <task definition revision> 48 `) 49 50 func NewDeployFlags(project *config.Project) *DeployOptions { 51 return &DeployOptions{ 52 Config: project, 53 } 54 } 55 56 func NewCmdDeploy(project *config.Project) *cobra.Command { 57 o := NewDeployFlags(project) 58 59 cmd := &cobra.Command{ 60 Use: "deploy [flags] <app name>", 61 Example: deployExample, 62 Short: "Manage deployments", 63 Long: deployLongDesc, 64 Args: cobra.MaximumNArgs(1), 65 ValidArgsFunction: config.GetApps, 66 RunE: func(cmd *cobra.Command, args []string) error { 67 cmd.SilenceUsage = true 68 69 err := o.Complete(cmd) 70 if err != nil { 71 return err 72 } 73 74 err = o.Validate() 75 if err != nil { 76 return err 77 } 78 79 err = o.Run() 80 if err != nil { 81 return err 82 } 83 84 return nil 85 }, 86 } 87 88 cmd.Flags().StringVar(&o.TaskDefinitionRevision, "task-definition-revision", "", "set task definition revision (ECS only)") 89 cmd.Flags().BoolVar(&o.Unsafe, "unsafe", false, "set unsafe healthcheck options (accelerates deployment if possible)") 90 cmd.Flags().BoolVar(&o.Force, "force", false, "forces a deployment to take place (only serverless)") 91 92 return cmd 93 } 94 95 func (o *DeployOptions) Complete(cmd *cobra.Command) error { 96 if err := requirements.CheckRequirements(requirements.WithIzeStructure(), requirements.WithConfigFile()); err != nil { 97 return err 98 } 99 100 if len(o.Config.Serverless) != 0 { 101 if err := requirements.CheckRequirements(requirements.WithNVM()); err != nil { 102 return err 103 } 104 } 105 106 o.AppName = cmd.Flags().Args()[0] 107 108 return nil 109 } 110 111 func (o *DeployOptions) Validate() error { 112 if len(o.Config.Env) == 0 { 113 return fmt.Errorf("can't validate options: env must be specified") 114 } 115 116 if len(o.Config.Namespace) == 0 { 117 return fmt.Errorf("can't validate options: namespace must be specified") 118 } 119 120 if len(o.AppName) == 0 { 121 return fmt.Errorf("can't validate options: app name must be specified") 122 } 123 124 return nil 125 } 126 127 func (o *DeployOptions) Run() error { 128 ui := terminal.ConsoleUI(aws.BackgroundContext(), o.Config.PlainText) 129 130 ui.Output("Deploying %s app...\n", o.AppName, terminal.WithHeaderStyle()) 131 sg := ui.StepGroup() 132 defer sg.Wait() 133 134 var m manager.Manager 135 136 m = &ecs.Manager{ 137 Project: o.Config, 138 App: &config.Ecs{ 139 Name: o.AppName, 140 TaskDefinitionRevision: o.TaskDefinitionRevision, 141 Unsafe: o.Unsafe, 142 }, 143 } 144 145 if app, ok := o.Config.Serverless[o.AppName]; ok { 146 app.Name = o.AppName 147 app.Force = o.Force 148 m = &serverless.Manager{ 149 Project: o.Config, 150 App: app, 151 } 152 } 153 if app, ok := o.Config.Alias[o.AppName]; ok { 154 app.Name = o.AppName 155 m = &alias.Manager{ 156 Project: o.Config, 157 App: app, 158 } 159 } 160 if app, ok := o.Config.Ecs[o.AppName]; ok { 161 app.Name = o.AppName 162 app.TaskDefinitionRevision = o.TaskDefinitionRevision 163 app.Unsafe = o.Unsafe 164 m = &ecs.Manager{ 165 Project: o.Config, 166 App: app, 167 } 168 } 169 170 if len(o.TaskDefinitionRevision) != 0 { 171 err := m.Redeploy(ui) 172 if err != nil { 173 return err 174 } 175 176 ui.Output("Redeploy app %s completed\n", o.AppName, terminal.WithSuccessStyle()) 177 178 return nil 179 } 180 181 err := m.Deploy(ui) 182 if err != nil { 183 return err 184 } 185 186 ui.Output("Deploy app %s completed\n", o.AppName, terminal.WithSuccessStyle()) 187 188 return nil 189 }