ufo 3.5.7 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/Gemfile.lock +16 -10
  4. data/README.md +12 -13
  5. data/docs/_config.yml +1 -1
  6. data/docs/_docs/auto-completion.md +4 -4
  7. data/docs/_docs/automated-cleanup.md +1 -1
  8. data/docs/_docs/conventions.md +7 -7
  9. data/docs/_docs/customize-cloudformation.md +36 -0
  10. data/docs/_docs/faq.md +9 -7
  11. data/docs/_docs/fargate.md +102 -0
  12. data/docs/_docs/helpers.md +3 -3
  13. data/docs/_docs/load-balancer.md +72 -0
  14. data/docs/_docs/migrations.md +2 -2
  15. data/docs/_docs/next-steps.md +2 -2
  16. data/docs/_docs/params.md +12 -41
  17. data/docs/_docs/route53-support.md +28 -0
  18. data/docs/_docs/run-in-pieces.md +2 -2
  19. data/docs/_docs/security-groups.md +54 -0
  20. data/docs/_docs/settings-cfn.md +11 -0
  21. data/docs/_docs/settings-network.md +34 -0
  22. data/docs/_docs/settings.md +18 -15
  23. data/docs/_docs/single-task.md +3 -3
  24. data/docs/_docs/ssl-support.md +42 -0
  25. data/docs/_docs/structure.md +5 -1
  26. data/docs/_docs/stuck-cloudformation.md +30 -0
  27. data/docs/_docs/tutorial-ufo-docker-build.md +19 -31
  28. data/docs/_docs/tutorial-ufo-init.md +16 -12
  29. data/docs/_docs/tutorial-ufo-ship.md +50 -54
  30. data/docs/_docs/tutorial-ufo-ships.md +9 -7
  31. data/docs/_docs/tutorial-ufo-tasks-build.md +26 -17
  32. data/docs/_docs/ufo-current.md +50 -0
  33. data/docs/_docs/ufo-env-extra.md +21 -0
  34. data/docs/_docs/ufo-env.md +6 -13
  35. data/docs/_docs/ufo-tasks-register.md +3 -3
  36. data/docs/_docs/upgrade4.md +49 -0
  37. data/docs/_docs/variables.md +5 -5
  38. data/docs/_docs/why-cloudformation.md +22 -0
  39. data/docs/_includes/about.html +1 -1
  40. data/docs/_includes/cfn-customize.md +39 -0
  41. data/docs/_includes/commands.html +6 -6
  42. data/docs/_includes/css/ufo.css +1 -0
  43. data/docs/_includes/example.html +13 -13
  44. data/docs/_includes/reference.md +1 -1
  45. data/docs/_includes/subnav.html +22 -5
  46. data/docs/_includes/ufo-ship-options.md +7 -6
  47. data/docs/_reference/ufo-apps.md +36 -0
  48. data/docs/_reference/ufo-cancel.md +24 -0
  49. data/docs/_reference/ufo-completion.md +1 -1
  50. data/docs/_reference/ufo-completion_script.md +1 -1
  51. data/docs/_reference/ufo-current.md +93 -0
  52. data/docs/_reference/ufo-deploy.md +18 -17
  53. data/docs/_reference/ufo-destroy.md +6 -4
  54. data/docs/_reference/ufo-docker-base.md +7 -7
  55. data/docs/_reference/ufo-docker-build.md +9 -9
  56. data/docs/_reference/ufo-docker-clean.md +8 -8
  57. data/docs/_reference/ufo-docker-name.md +4 -4
  58. data/docs/_reference/ufo-docker.md +4 -2
  59. data/docs/_reference/ufo-init.md +31 -20
  60. data/docs/_reference/ufo-network-help.md +15 -0
  61. data/docs/_reference/ufo-network-init.md +38 -0
  62. data/docs/_reference/ufo-network.md +26 -0
  63. data/docs/_reference/ufo-ps.md +53 -0
  64. data/docs/_reference/ufo-releases.md +40 -0
  65. data/docs/_reference/ufo-resources.md +44 -0
  66. data/docs/_reference/ufo-rollback.md +59 -0
  67. data/docs/_reference/ufo-scale.md +23 -3
  68. data/docs/_reference/ufo-ship.md +54 -27
  69. data/docs/_reference/ufo-ships.md +17 -26
  70. data/docs/_reference/ufo-stop.md +31 -0
  71. data/docs/_reference/ufo-task.md +15 -16
  72. data/docs/_reference/ufo-tasks-build.md +10 -10
  73. data/docs/_reference/ufo-tasks-register.md +3 -3
  74. data/docs/_reference/ufo-tasks.md +1 -1
  75. data/docs/_reference/ufo-upgrade-help.md +15 -0
  76. data/docs/_reference/ufo-upgrade-v2to3.md +15 -0
  77. data/docs/_reference/ufo-upgrade-v3_3to3_4.md +15 -0
  78. data/docs/_reference/ufo-upgrade-v3to4.md +27 -0
  79. data/docs/_reference/ufo-upgrade.md +28 -0
  80. data/docs/_reference/ufo-version.md +1 -1
  81. data/docs/articles.md +2 -2
  82. data/docs/docs.md +1 -1
  83. data/docs/img/docs/cloudformation-resources.png +0 -0
  84. data/docs/img/tutorials/ecs-console-task-definitions.png +0 -0
  85. data/docs/img/tutorials/ecs-console-ufo-ship.png +0 -0
  86. data/docs/img/tutorials/ecs-console-ufo-ships.png +0 -0
  87. data/docs/quick-start.md +21 -9
  88. data/docs/reference.md +10 -2
  89. data/exe/ufo +1 -1
  90. data/lib/cfn/stack.yml +259 -0
  91. data/lib/template/.ufo/params.yml.tt +21 -60
  92. data/lib/template/.ufo/settings.yml.tt +6 -1
  93. data/lib/template/.ufo/settings/cfn/default.yml.tt +55 -0
  94. data/lib/template/.ufo/settings/network/default.yml.tt +18 -0
  95. data/lib/template/.ufo/task_definitions.rb.tt +7 -6
  96. data/lib/template/.ufo/templates/fargate.json.erb +1 -1
  97. data/lib/template/.ufo/templates/main.json.erb +1 -0
  98. data/lib/template/.ufo/variables/base.rb.tt +5 -2
  99. data/lib/template/Dockerfile +10 -15
  100. data/lib/template/bin/deploy.tt +2 -2
  101. data/lib/ufo.rb +29 -20
  102. data/lib/ufo/apps.rb +49 -0
  103. data/lib/ufo/apps/cfn_map.rb +70 -0
  104. data/lib/ufo/apps/service.rb +56 -0
  105. data/lib/ufo/aws_service.rb +15 -6
  106. data/lib/ufo/base.rb +32 -0
  107. data/lib/ufo/cancel.rb +23 -0
  108. data/lib/ufo/cli.rb +91 -27
  109. data/lib/ufo/core.rb +35 -3
  110. data/lib/ufo/current.rb +104 -0
  111. data/lib/ufo/destroy.rb +10 -41
  112. data/lib/ufo/docker/builder.rb +5 -4
  113. data/lib/ufo/docker/cleaner.rb +1 -1
  114. data/lib/ufo/docker/pusher.rb +2 -2
  115. data/lib/ufo/ecr/cleaner.rb +1 -1
  116. data/lib/ufo/help/apps.md +12 -0
  117. data/lib/ufo/help/balancer.md +3 -0
  118. data/lib/ufo/help/current.md +65 -0
  119. data/lib/ufo/help/deploy.md +4 -4
  120. data/lib/ufo/help/destroy.md +3 -3
  121. data/lib/ufo/help/docker.md +3 -1
  122. data/lib/ufo/help/docker/base.md +7 -7
  123. data/lib/ufo/help/docker/build.md +9 -9
  124. data/lib/ufo/help/docker/clean.md +8 -8
  125. data/lib/ufo/help/docker/name.md +4 -4
  126. data/lib/ufo/help/help.md +5 -0
  127. data/lib/ufo/help/init.md +24 -16
  128. data/lib/ufo/help/network/init.md +13 -0
  129. data/lib/ufo/help/ps.md +27 -0
  130. data/lib/ufo/help/releases.md +16 -0
  131. data/lib/ufo/help/resources.md +20 -0
  132. data/lib/ufo/help/rollback.md +35 -0
  133. data/lib/ufo/help/scale.md +22 -2
  134. data/lib/ufo/help/ship.md +40 -14
  135. data/lib/ufo/help/ships.md +4 -13
  136. data/lib/ufo/help/stop.md +7 -0
  137. data/lib/ufo/help/task.md +9 -9
  138. data/lib/ufo/help/tasks/build.md +10 -10
  139. data/lib/ufo/help/tasks/register.md +3 -3
  140. data/lib/ufo/help/upgrade/v3to4.md +3 -0
  141. data/lib/ufo/info.rb +62 -0
  142. data/lib/ufo/init.rb +36 -23
  143. data/lib/ufo/log_group.rb +2 -1
  144. data/lib/ufo/network.rb +24 -0
  145. data/lib/ufo/network/fetch.rb +41 -0
  146. data/lib/ufo/network/helper.rb +23 -0
  147. data/lib/ufo/network/init.rb +26 -0
  148. data/lib/ufo/param.rb +5 -5
  149. data/lib/ufo/ps.rb +102 -0
  150. data/lib/ufo/ps/task.rb +78 -0
  151. data/lib/ufo/releases.rb +14 -0
  152. data/lib/ufo/rollback.rb +53 -0
  153. data/lib/ufo/scale.rb +6 -12
  154. data/lib/ufo/sequence.rb +7 -0
  155. data/lib/ufo/setting.rb +7 -6
  156. data/lib/ufo/setting/profile.rb +24 -0
  157. data/lib/ufo/ship.rb +35 -326
  158. data/lib/ufo/stack.rb +203 -0
  159. data/lib/ufo/stack/context.rb +242 -0
  160. data/lib/ufo/stack/helper.rb +28 -0
  161. data/lib/ufo/stack/status.rb +195 -0
  162. data/lib/ufo/stop.rb +47 -0
  163. data/lib/ufo/task.rb +96 -15
  164. data/lib/ufo/tasks/register.rb +1 -1
  165. data/lib/ufo/template_scope.rb +81 -7
  166. data/lib/ufo/upgrade.rb +32 -0
  167. data/lib/ufo/{upgrade3.rb → upgrade/upgrade3.rb} +1 -1
  168. data/lib/ufo/{upgrade33_to_34.rb → upgrade/upgrade33to34.rb} +2 -2
  169. data/lib/ufo/upgrade/upgrade4.rb +161 -0
  170. data/lib/ufo/util.rb +19 -6
  171. data/lib/ufo/version.rb +1 -1
  172. data/spec/fixtures/apps/describe_services.json +96 -0
  173. data/spec/fixtures/cfn/stack-events-complete.json +1080 -0
  174. data/spec/fixtures/cfn/stack-events-in-progress.json +1080 -0
  175. data/spec/fixtures/cfn/stack-events-update-rollback-complete.json +1086 -0
  176. data/spec/fixtures/deployments.json +50 -0
  177. data/spec/fixtures/ps/describe_tasks.json +58 -0
  178. data/spec/fixtures/settings.yml +2 -0
  179. data/spec/lib/apps_spec.rb +20 -0
  180. data/spec/lib/cli_spec.rb +4 -4
  181. data/spec/lib/ps_spec.rb +14 -0
  182. data/spec/lib/setting_spec.rb +2 -1
  183. data/spec/lib/ship_spec.rb +6 -30
  184. data/spec/lib/stack/status_spec.rb +76 -0
  185. data/spec/lib/stop_spec.rb +13 -0
  186. data/spec/lib/task_spec.rb +5 -2
  187. data/spec/spec_helper.rb +1 -1
  188. data/ufo.gemspec +2 -0
  189. metadata +120 -6
  190. data/docs/_reference/ufo-upgrade3.md +0 -23
  191. data/docs/_reference/ufo-upgrade3_3_to_3_4.md +0 -23
@@ -0,0 +1,56 @@
1
+ class Ufo::Apps
2
+ class Service
3
+ extend Memoist
4
+
5
+ def initialize(service, options)
6
+ @service = service
7
+ @options = options
8
+ end
9
+
10
+ def to_a
11
+ [name, task_definition, running, launch_type, ufo?]
12
+ end
13
+
14
+ def task_definition
15
+ @service["task_definition"].split('/').last
16
+ end
17
+
18
+ def launch_type
19
+ @service["launch_type"]
20
+ end
21
+
22
+ def cfn_map
23
+ @cfn_map ||= CfnMap.new(@options).map
24
+ end
25
+
26
+ def ufo?
27
+ yes = !!cfn_map[@service["service_name"]]
28
+ yes ? "yes" : "no"
29
+ end
30
+
31
+ def name
32
+ pretty_service_name = @service["service_name"]
33
+ pretty_name = cfn_map[pretty_service_name]
34
+ if pretty_name
35
+ "#{pretty_service_name} (#{pretty_name})"
36
+ else
37
+ pretty_service_name
38
+ end
39
+ end
40
+
41
+ def running
42
+ @service["running_count"]
43
+ end
44
+
45
+ def dns
46
+ return 'dns' if ENV['TEST']
47
+ elb = info.load_balancer(@service)
48
+ elb.dns_name if elb
49
+ end
50
+
51
+ def info
52
+ Ufo::Info.new(@service)
53
+ end
54
+ memoize :info
55
+ end
56
+ end
@@ -1,3 +1,4 @@
1
+ require "aws-sdk-cloudformation"
1
2
  require "aws-sdk-cloudwatchlogs"
2
3
  require "aws-sdk-ec2"
3
4
  require "aws-sdk-ecr"
@@ -6,20 +7,28 @@ require "aws-sdk-elasticloadbalancingv2"
6
7
 
7
8
  module Ufo
8
9
  module AwsService
9
- def ecs
10
- @ecs ||= Aws::ECS::Client.new
10
+ def cloudformation
11
+ @cloudformation ||= Aws::CloudFormation::Client.new
11
12
  end
12
13
 
13
- def elb
14
- @elb ||= Aws::ElasticLoadBalancingV2::Client.new
14
+ def cloudwatchlogs
15
+ @cloudwatchlogs ||= Aws::CloudWatchLogs::Client.new
16
+ end
17
+
18
+ def ec2
19
+ @ec2 ||= Aws::EC2::Client.new
15
20
  end
16
21
 
17
22
  def ecr
18
23
  @ecr ||= Aws::ECR::Client.new
19
24
  end
20
25
 
21
- def cloudwatchlogs
22
- @cloudwatchlogs ||= Aws::CloudWatchLogs::Client.new
26
+ def ecs
27
+ @ecs ||= Aws::ECS::Client.new
28
+ end
29
+
30
+ def elb
31
+ @elb ||= Aws::ElasticLoadBalancingV2::Client.new
23
32
  end
24
33
  end
25
34
  end
@@ -0,0 +1,32 @@
1
+ module Ufo
2
+ class Base
3
+ extend Memoist
4
+ include Stack::Helper
5
+
6
+ def initialize(service, options={})
7
+ @service = switch_current(service)
8
+ @options = options
9
+
10
+ @pretty_service_name = Ufo.pretty_service_name(@service)
11
+ @cluster = @options[:cluster] || default_cluster
12
+ @stack_name = adjust_stack_name(@cluster, @service)
13
+ end
14
+
15
+ def switch_current(service)
16
+ Current.service!(service)
17
+ end
18
+
19
+ def info
20
+ Info.new(@service, @options)
21
+ end
22
+ memoize :info
23
+
24
+ def no_service_message
25
+ <<-EOL
26
+ No #{@pretty_service_name.colorize(:green)} found.
27
+ No CloudFormation stack named #{@stack_name} found.
28
+ Are sure it exists?
29
+ EOL
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,23 @@
1
+ module Ufo
2
+ class Cancel < Base
3
+ def run
4
+ stack = find_stack(@stack_name)
5
+ unless stack
6
+ puts "No #{@pretty_service_name} service to cancel."
7
+ puts "No #{@stack_name} stack to cancel. Exiting"
8
+ exit
9
+ end
10
+
11
+ puts "Canceling updates to #{@pretty_service_name}."
12
+ if stack.stack_status == "CREATE_IN_PROGRESS"
13
+ cloudformation.delete_stack(stack_name: @stack_name)
14
+ puts "Canceling stack creation."
15
+ elsif stack.stack_status =~ /_IN_PROGRESS$/
16
+ cloudformation.cancel_update_stack(stack_name: @stack_name)
17
+ puts "Canceling stack update."
18
+ else
19
+ puts "The stack is not in a state to that is cancelable: #{stack.stack_status}"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -6,7 +6,11 @@ module Ufo
6
6
  class_option :verbose, type: :boolean
7
7
  class_option :mute, type: :boolean
8
8
  class_option :noop, type: :boolean
9
- class_option :cluster, desc: "Cluster. Overrides ufo/settings.yml."
9
+ class_option :cluster, desc: "Cluster. Overrides .ufo/settings.yml."
10
+
11
+ desc "network SUBCOMMAND", "network subcommands"
12
+ long_desc Help.text(:network)
13
+ subcommand "network", Network
10
14
 
11
15
  desc "docker SUBCOMMAND", "docker subcommands"
12
16
  long_desc Help.text(:docker)
@@ -16,6 +20,10 @@ module Ufo
16
20
  long_desc Help.text(:tasks)
17
21
  subcommand "tasks", Tasks
18
22
 
23
+ desc "upgrade SUBCOMMAND", "upgrade subcommands"
24
+ long_desc Help.text(:upgrade)
25
+ subcommand "upgrade", Upgrade
26
+
19
27
  long_desc Help.text(:init)
20
28
  Init.cli_options.each do |args|
21
29
  option *args
@@ -24,50 +32,66 @@ module Ufo
24
32
 
25
33
  # common options to deploy. ship, and ships command
26
34
  ship_options = Proc.new do
27
- option :task, desc: "ECS task name, to override the task name convention."
28
- option :target_group, desc: "ELB Target Group ARN."
29
- option :target_group_prompt, type: :boolean, desc: "Enable Target Group ARN prompt", default: true
30
- option :wait, type: :boolean, desc: "Wait for deployment to complete", default: false
31
- option :pretty, type: :boolean, default: true, desc: "Pretty format the json for the task definitions"
32
- option :stop_old_tasks, type: :boolean, default: false, desc: "Stop old tasks after waiting for deploying to complete"
33
35
  option :ecr_keep, type: :numeric, desc: "ECR specific cleanup of old images. Specifies how many images to keep. Only runs if the images are ECR images. Defaults keeps all images."
36
+ # All elb options remember their 'state'
37
+ option :elb, desc: "Decides to create elb, not create elb or use existing target group."
38
+ option :elb_eip_ids, type: :array, desc: "EIP Allocation ids to use for network load balancer."
39
+ option :elb_type, desc: "ELB type: application or network. Keep current deployed elb type when not specified."
40
+ option :pretty, type: :boolean, default: true, desc: "Pretty format the json for the task definitions"
41
+ option :stop_old_tasks, type: :boolean, default: false, desc: "Stop old tasks as part of deployment to speed it up"
42
+ option :task, desc: "ECS task name, to override the task name convention."
43
+ option :wait, type: :boolean, desc: "Wait for deployment to complete", default: true
34
44
  end
35
45
 
36
46
  desc "deploy SERVICE", "Deploy task definition to ECS service without re-building the definition."
37
47
  long_desc Help.text(:deploy)
38
48
  ship_options.call
39
- def deploy(service)
49
+ def deploy(service=:current)
50
+ service = service == :current ? Current.service! : service
40
51
  task_definition = options[:task] || service # convention
41
52
  Tasks::Register.register(task_definition, options)
42
- ship = Ship.new(service, task_definition, options)
53
+ ship = Ship.new(service, options.merge(task_definition: task_definition))
43
54
  ship.deploy
44
55
  end
45
56
 
46
57
  desc "ship SERVICE", "Builds and ships container image to the ECS service."
47
58
  long_desc Help.text(:ship)
48
59
  ship_options.call
49
- def ship(service)
60
+ def ship(service=:current)
61
+ service = service == :current ? Current.service! : service
50
62
  builder = build_docker
51
63
 
52
64
  task_definition = options[:task] || service # convention
53
65
  Tasks::Builder.ship(task_definition, options)
54
- ship = Ship.new(service, task_definition, options)
66
+ ship = Ship.new(service, options.merge(task_definition: task_definition))
55
67
  ship.deploy
56
68
 
57
69
  cleanup(builder.image_name)
58
70
  end
59
71
 
72
+ desc "rollback SERVICE VERSION", "Rolls back to older task definition."
73
+ long_desc Help.text(:rollback)
74
+ def rollback(service=:current, version)
75
+ service = service == :current ? Current.service! : service
76
+ rollback = Rollback.new(service, options.merge(version: version))
77
+ rollback.deploy
78
+ end
79
+
60
80
  desc "ships [LIST_OF_SERVICES]", "Builds and ships same container image to multiple ECS services."
61
81
  long_desc Help.text(:ships)
62
82
  ship_options.call
83
+ option :wait, type: :boolean, desc: "Wait for deployment to complete", default: false
63
84
  def ships(*services)
64
85
  builder = build_docker
65
86
 
87
+ if services.empty? && !Current.services&.empty?
88
+ services = Current.services
89
+ end
66
90
  services.each_with_index do |service|
67
91
  service_name, task_definition_name = service.split(':')
68
92
  task_definition = task_definition_name || service_name # convention
69
93
  Tasks::Builder.ship(task_definition, options)
70
- ship = Ship.new(service, task_definition, options)
94
+ ship = Ship.new(service, options.merge(task_definition: task_definition))
71
95
  ship.deploy
72
96
  end
73
97
 
@@ -76,28 +100,78 @@ module Ufo
76
100
 
77
101
  desc "task TASK_DEFINITION", "Run a one-time task."
78
102
  long_desc Help.text(:task)
79
- option :docker, type: :boolean, desc: "Enable docker build and push", default: true
103
+ option :task_only, type: :boolean, desc: "Skip docker and task register steps. Only run the task."
80
104
  option :command, type: :array, aliases: 'c', desc: "Override the command used for the container"
81
105
  def task(task_definition)
82
- Docker::Builder.build(options) if @options[:docker]
83
- Tasks::Builder.ship(task_definition, options)
106
+ Docker::Builder.build(options) unless @options[:task_only]
107
+ Tasks::Builder.ship(task_definition, options) unless @options[:task_only]
84
108
  Task.new(task_definition, options).run
85
109
  end
86
110
 
111
+ desc "cancel SERVICE", "Cancel creation or update of the ECS service."
112
+ long_desc Help.text(:cancel)
113
+ option :sure, type: :boolean, desc: "By pass are you sure prompt."
114
+ def cancel(service=:current)
115
+ task_definition = options[:task] || service # convention
116
+ Cancel.new(service, options).run
117
+ end
118
+
119
+ desc "current SERVICE", "Switch the current service. Saves to `.ufo/current`"
120
+ long_desc Help.text(:current)
121
+ option :rm, type: :boolean, desc: "Remove all current settings. Removes `.ufo/current`"
122
+ option :service, desc: "Sets service as a current setting."
123
+ option :services, type: :array, desc: "Sets services as a current setting. This is used for ufo ships."
124
+ option :env_extra, desc: "Sets UFO_ENV_EXTRA as a current setting."
125
+ def current
126
+ Current.new(options).run
127
+ end
128
+
87
129
  desc "destroy SERVICE", "Destroy the ECS service."
88
130
  long_desc Help.text(:destroy)
89
131
  option :sure, type: :boolean, desc: "By pass are you sure prompt."
90
- def destroy(service)
132
+ option :wait, type: :boolean, desc: "Wait for completion", default: true
133
+ def destroy(service=:current)
91
134
  task_definition = options[:task] || service # convention
92
135
  Destroy.new(service, options).bye
93
136
  end
94
137
 
138
+ desc "apps", "List apps."
139
+ long_desc Help.text(:apps)
140
+ def apps
141
+ Apps.new(options).list
142
+ end
143
+
144
+ desc "resources SERVICE", "The ECS service resources."
145
+ long_desc Help.text(:resources)
146
+ def resources(service=:current)
147
+ Info.new(service, options).run
148
+ end
149
+
95
150
  desc "scale SERVICE COUNT", "Scale the ECS service."
96
151
  long_desc Help.text(:scale)
97
- def scale(service, count)
152
+ def scale(service=:current, count)
98
153
  Scale.new(service, count, options).update
99
154
  end
100
155
 
156
+ desc "ps SERVICE", "Show process info on ECS service."
157
+ long_desc Help.text(:ps)
158
+ option :summary, type: :boolean, default: true, desc: "Display summary header info."
159
+ def ps(service=:current)
160
+ Ps.new(service, options).run
161
+ end
162
+
163
+ desc "releases SERVICE", "Show possible 'releases' or task definitions for the service."
164
+ long_desc Help.text(:releases)
165
+ def releases(service=:current)
166
+ Releases.new(service, options).list
167
+ end
168
+
169
+ desc "stop SERVICE", "Stop tasks from old deployments. Can speed up deployments with network load balancer."
170
+ long_desc Help.text(:stop)
171
+ def stop(service=:current)
172
+ Stop.new(service, options).run
173
+ end
174
+
101
175
  desc "completion *PARAMS", "Prints words for auto-completion."
102
176
  long_desc Help.text("completion")
103
177
  def completion(*params)
@@ -110,16 +184,6 @@ module Ufo
110
184
  Completer::Script.generate
111
185
  end
112
186
 
113
- desc "upgrade3", "Upgrade from version 2 to 3."
114
- def upgrade3
115
- Upgrade3.new(options).run
116
- end
117
-
118
- desc "upgrade3_3_to_3_4", "Upgrade from version 3.3 to 3.4"
119
- def upgrade3_3_to_3_4
120
- Upgrade33_to_34.new(options).run
121
- end
122
-
123
187
  desc "version", "Prints version number of installed ufo."
124
188
  def version
125
189
  puts VERSION
@@ -3,6 +3,8 @@ require 'yaml'
3
3
 
4
4
  module Ufo
5
5
  module Core
6
+ extend Memoist
7
+
6
8
  def check_task_definition!(task_definition)
7
9
  task_definition_path = "#{Ufo.root}/.ufo/output/#{task_definition}.json"
8
10
  unless File.exist?(task_definition_path)
@@ -18,12 +20,42 @@ module Ufo
18
20
  Pathname.new(path)
19
21
  end
20
22
 
21
- @@env = nil
22
23
  def env
23
- return @@env if @@env
24
24
  ufo_env = env_from_profile(ENV['AWS_PROFILE']) || 'development'
25
25
  ufo_env = ENV['UFO_ENV'] if ENV['UFO_ENV'] # highest precedence
26
- @@env = ufo_env
26
+ ufo_env
27
+ end
28
+ memoize :env
29
+
30
+ def env_extra
31
+ env_extra = Current.env_extra
32
+ env_extra = ENV['UFO_ENV_EXTRA'] if ENV['UFO_ENV_EXTRA'] # highest precedence
33
+ return if env_extra&.empty?
34
+ env_extra
35
+ end
36
+ memoize :env_extra
37
+
38
+ def pretty_service_name(service)
39
+ [service, Ufo.env_extra].reject {|x| x==''}.compact.join('-')
40
+ end
41
+
42
+ def settings
43
+ Setting.new.data
44
+ end
45
+ memoize :settings
46
+
47
+ def cfn_profile
48
+ settings[:cfn_profile] || "default"
49
+ end
50
+
51
+ def check_ufo_project!
52
+ check_path = "#{Ufo.root}/.ufo/settings.yml"
53
+ unless File.exist?(check_path)
54
+ puts "ERROR: No settings file at #{check_path}. Are you sure you are in a project with ufo setup?".colorize(:red)
55
+ puts "Current directory: #{Dir.pwd}"
56
+ puts "If you want to set up ufo for this prjoect, please create a settings file via: ufo init"
57
+ exit 1 unless ENV['TEST']
58
+ end
27
59
  end
28
60
 
29
61
  private
@@ -0,0 +1,104 @@
1
+ require 'fileutils'
2
+ require 'yaml'
3
+
4
+ module Ufo
5
+ class Current
6
+ def initialize(options={})
7
+ Ufo.check_ufo_project!
8
+ @options = options
9
+ @file = ".ufo/current"
10
+ @path = "#{Ufo.root}/#{@file}"
11
+ end
12
+
13
+ def run
14
+ @options[:rm] ? rm : set
15
+ end
16
+
17
+ def rm
18
+ FileUtils.rm_f(@path)
19
+ puts "Current settings have been removed. Removed #{@file}"
20
+ end
21
+
22
+ def set
23
+ if @options.empty?
24
+ show
25
+ else
26
+ d = data # assign data to d to create local variable for merge to work
27
+ d = d.merge(@options).delete_if do |_,v|
28
+ v&.empty? || v == ['']
29
+ end
30
+ text = YAML.dump(d)
31
+ IO.write(@path, text)
32
+ puts "Current settings saved in .ufo/current"
33
+ show
34
+ end
35
+ end
36
+
37
+ def show
38
+ if data.empty?
39
+ puts <<-EOL
40
+ There are no current settings. To set a current service run:
41
+
42
+ ufo current --service my-service
43
+ ufo current -h # for more examples
44
+ EOL
45
+ return
46
+ end
47
+
48
+ data.each do |key, value|
49
+ puts "Current #{key}: #{value}"
50
+ end
51
+ end
52
+
53
+ def data
54
+ YAML.load(IO.read(@path)) rescue {}
55
+ end
56
+
57
+ def env_extra
58
+ current = data["env_extra"]
59
+ return current unless current&.empty?
60
+ end
61
+
62
+ def self.env_extra
63
+ Current.new.env_extra
64
+ end
65
+
66
+ def services
67
+ return data["services"] || []
68
+ end
69
+
70
+ # reads services, returns [] if not set
71
+ def self.services
72
+ Current.new.services
73
+ end
74
+
75
+ def service
76
+ current = data["service"]
77
+ return current unless current&.empty?
78
+ end
79
+
80
+ # reads service, returns nil if not set
81
+ def self.service
82
+ Current.new.service
83
+ end
84
+
85
+ # reads service, will exit if current service not set
86
+ def self.service!(service=:current)
87
+ return service if service != :current
88
+
89
+ service = Current.service
90
+ return service if service
91
+
92
+ puts "ERROR: service must be specified.".colorize(:red)
93
+ puts <<-EOL
94
+ Example:
95
+ ufo #{ARGV.first} SERVICE
96
+ You can also set a current service to be remembered with:
97
+ ufo current SERVICE
98
+ EOL
99
+ exit 1
100
+ # if want to display full help menu:
101
+ # Ufo::CLI.start(ARGV + ["-h"])
102
+ end
103
+ end
104
+ end