ufo 3.5.7 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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