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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/Gemfile.lock +16 -10
- data/README.md +12 -13
- data/docs/_config.yml +1 -1
- data/docs/_docs/auto-completion.md +4 -4
- data/docs/_docs/automated-cleanup.md +1 -1
- data/docs/_docs/conventions.md +7 -7
- data/docs/_docs/customize-cloudformation.md +36 -0
- data/docs/_docs/faq.md +9 -7
- data/docs/_docs/fargate.md +102 -0
- data/docs/_docs/helpers.md +3 -3
- data/docs/_docs/load-balancer.md +72 -0
- data/docs/_docs/migrations.md +2 -2
- data/docs/_docs/next-steps.md +2 -2
- data/docs/_docs/params.md +12 -41
- data/docs/_docs/route53-support.md +28 -0
- data/docs/_docs/run-in-pieces.md +2 -2
- data/docs/_docs/security-groups.md +54 -0
- data/docs/_docs/settings-cfn.md +11 -0
- data/docs/_docs/settings-network.md +34 -0
- data/docs/_docs/settings.md +18 -15
- data/docs/_docs/single-task.md +3 -3
- data/docs/_docs/ssl-support.md +42 -0
- data/docs/_docs/structure.md +5 -1
- data/docs/_docs/stuck-cloudformation.md +30 -0
- data/docs/_docs/tutorial-ufo-docker-build.md +19 -31
- data/docs/_docs/tutorial-ufo-init.md +16 -12
- data/docs/_docs/tutorial-ufo-ship.md +50 -54
- data/docs/_docs/tutorial-ufo-ships.md +9 -7
- data/docs/_docs/tutorial-ufo-tasks-build.md +26 -17
- data/docs/_docs/ufo-current.md +50 -0
- data/docs/_docs/ufo-env-extra.md +21 -0
- data/docs/_docs/ufo-env.md +6 -13
- data/docs/_docs/ufo-tasks-register.md +3 -3
- data/docs/_docs/upgrade4.md +49 -0
- data/docs/_docs/variables.md +5 -5
- data/docs/_docs/why-cloudformation.md +22 -0
- data/docs/_includes/about.html +1 -1
- data/docs/_includes/cfn-customize.md +39 -0
- data/docs/_includes/commands.html +6 -6
- data/docs/_includes/css/ufo.css +1 -0
- data/docs/_includes/example.html +13 -13
- data/docs/_includes/reference.md +1 -1
- data/docs/_includes/subnav.html +22 -5
- data/docs/_includes/ufo-ship-options.md +7 -6
- data/docs/_reference/ufo-apps.md +36 -0
- data/docs/_reference/ufo-cancel.md +24 -0
- data/docs/_reference/ufo-completion.md +1 -1
- data/docs/_reference/ufo-completion_script.md +1 -1
- data/docs/_reference/ufo-current.md +93 -0
- data/docs/_reference/ufo-deploy.md +18 -17
- data/docs/_reference/ufo-destroy.md +6 -4
- data/docs/_reference/ufo-docker-base.md +7 -7
- data/docs/_reference/ufo-docker-build.md +9 -9
- data/docs/_reference/ufo-docker-clean.md +8 -8
- data/docs/_reference/ufo-docker-name.md +4 -4
- data/docs/_reference/ufo-docker.md +4 -2
- data/docs/_reference/ufo-init.md +31 -20
- data/docs/_reference/ufo-network-help.md +15 -0
- data/docs/_reference/ufo-network-init.md +38 -0
- data/docs/_reference/ufo-network.md +26 -0
- data/docs/_reference/ufo-ps.md +53 -0
- data/docs/_reference/ufo-releases.md +40 -0
- data/docs/_reference/ufo-resources.md +44 -0
- data/docs/_reference/ufo-rollback.md +59 -0
- data/docs/_reference/ufo-scale.md +23 -3
- data/docs/_reference/ufo-ship.md +54 -27
- data/docs/_reference/ufo-ships.md +17 -26
- data/docs/_reference/ufo-stop.md +31 -0
- data/docs/_reference/ufo-task.md +15 -16
- data/docs/_reference/ufo-tasks-build.md +10 -10
- data/docs/_reference/ufo-tasks-register.md +3 -3
- data/docs/_reference/ufo-tasks.md +1 -1
- data/docs/_reference/ufo-upgrade-help.md +15 -0
- data/docs/_reference/ufo-upgrade-v2to3.md +15 -0
- data/docs/_reference/ufo-upgrade-v3_3to3_4.md +15 -0
- data/docs/_reference/ufo-upgrade-v3to4.md +27 -0
- data/docs/_reference/ufo-upgrade.md +28 -0
- data/docs/_reference/ufo-version.md +1 -1
- data/docs/articles.md +2 -2
- data/docs/docs.md +1 -1
- data/docs/img/docs/cloudformation-resources.png +0 -0
- data/docs/img/tutorials/ecs-console-task-definitions.png +0 -0
- data/docs/img/tutorials/ecs-console-ufo-ship.png +0 -0
- data/docs/img/tutorials/ecs-console-ufo-ships.png +0 -0
- data/docs/quick-start.md +21 -9
- data/docs/reference.md +10 -2
- data/exe/ufo +1 -1
- data/lib/cfn/stack.yml +259 -0
- data/lib/template/.ufo/params.yml.tt +21 -60
- data/lib/template/.ufo/settings.yml.tt +6 -1
- data/lib/template/.ufo/settings/cfn/default.yml.tt +55 -0
- data/lib/template/.ufo/settings/network/default.yml.tt +18 -0
- data/lib/template/.ufo/task_definitions.rb.tt +7 -6
- data/lib/template/.ufo/templates/fargate.json.erb +1 -1
- data/lib/template/.ufo/templates/main.json.erb +1 -0
- data/lib/template/.ufo/variables/base.rb.tt +5 -2
- data/lib/template/Dockerfile +10 -15
- data/lib/template/bin/deploy.tt +2 -2
- data/lib/ufo.rb +29 -20
- data/lib/ufo/apps.rb +49 -0
- data/lib/ufo/apps/cfn_map.rb +70 -0
- data/lib/ufo/apps/service.rb +56 -0
- data/lib/ufo/aws_service.rb +15 -6
- data/lib/ufo/base.rb +32 -0
- data/lib/ufo/cancel.rb +23 -0
- data/lib/ufo/cli.rb +91 -27
- data/lib/ufo/core.rb +35 -3
- data/lib/ufo/current.rb +104 -0
- data/lib/ufo/destroy.rb +10 -41
- data/lib/ufo/docker/builder.rb +5 -4
- data/lib/ufo/docker/cleaner.rb +1 -1
- data/lib/ufo/docker/pusher.rb +2 -2
- data/lib/ufo/ecr/cleaner.rb +1 -1
- data/lib/ufo/help/apps.md +12 -0
- data/lib/ufo/help/balancer.md +3 -0
- data/lib/ufo/help/current.md +65 -0
- data/lib/ufo/help/deploy.md +4 -4
- data/lib/ufo/help/destroy.md +3 -3
- data/lib/ufo/help/docker.md +3 -1
- data/lib/ufo/help/docker/base.md +7 -7
- data/lib/ufo/help/docker/build.md +9 -9
- data/lib/ufo/help/docker/clean.md +8 -8
- data/lib/ufo/help/docker/name.md +4 -4
- data/lib/ufo/help/help.md +5 -0
- data/lib/ufo/help/init.md +24 -16
- data/lib/ufo/help/network/init.md +13 -0
- data/lib/ufo/help/ps.md +27 -0
- data/lib/ufo/help/releases.md +16 -0
- data/lib/ufo/help/resources.md +20 -0
- data/lib/ufo/help/rollback.md +35 -0
- data/lib/ufo/help/scale.md +22 -2
- data/lib/ufo/help/ship.md +40 -14
- data/lib/ufo/help/ships.md +4 -13
- data/lib/ufo/help/stop.md +7 -0
- data/lib/ufo/help/task.md +9 -9
- data/lib/ufo/help/tasks/build.md +10 -10
- data/lib/ufo/help/tasks/register.md +3 -3
- data/lib/ufo/help/upgrade/v3to4.md +3 -0
- data/lib/ufo/info.rb +62 -0
- data/lib/ufo/init.rb +36 -23
- data/lib/ufo/log_group.rb +2 -1
- data/lib/ufo/network.rb +24 -0
- data/lib/ufo/network/fetch.rb +41 -0
- data/lib/ufo/network/helper.rb +23 -0
- data/lib/ufo/network/init.rb +26 -0
- data/lib/ufo/param.rb +5 -5
- data/lib/ufo/ps.rb +102 -0
- data/lib/ufo/ps/task.rb +78 -0
- data/lib/ufo/releases.rb +14 -0
- data/lib/ufo/rollback.rb +53 -0
- data/lib/ufo/scale.rb +6 -12
- data/lib/ufo/sequence.rb +7 -0
- data/lib/ufo/setting.rb +7 -6
- data/lib/ufo/setting/profile.rb +24 -0
- data/lib/ufo/ship.rb +35 -326
- data/lib/ufo/stack.rb +203 -0
- data/lib/ufo/stack/context.rb +242 -0
- data/lib/ufo/stack/helper.rb +28 -0
- data/lib/ufo/stack/status.rb +195 -0
- data/lib/ufo/stop.rb +47 -0
- data/lib/ufo/task.rb +96 -15
- data/lib/ufo/tasks/register.rb +1 -1
- data/lib/ufo/template_scope.rb +81 -7
- data/lib/ufo/upgrade.rb +32 -0
- data/lib/ufo/{upgrade3.rb → upgrade/upgrade3.rb} +1 -1
- data/lib/ufo/{upgrade33_to_34.rb → upgrade/upgrade33to34.rb} +2 -2
- data/lib/ufo/upgrade/upgrade4.rb +161 -0
- data/lib/ufo/util.rb +19 -6
- data/lib/ufo/version.rb +1 -1
- data/spec/fixtures/apps/describe_services.json +96 -0
- data/spec/fixtures/cfn/stack-events-complete.json +1080 -0
- data/spec/fixtures/cfn/stack-events-in-progress.json +1080 -0
- data/spec/fixtures/cfn/stack-events-update-rollback-complete.json +1086 -0
- data/spec/fixtures/deployments.json +50 -0
- data/spec/fixtures/ps/describe_tasks.json +58 -0
- data/spec/fixtures/settings.yml +2 -0
- data/spec/lib/apps_spec.rb +20 -0
- data/spec/lib/cli_spec.rb +4 -4
- data/spec/lib/ps_spec.rb +14 -0
- data/spec/lib/setting_spec.rb +2 -1
- data/spec/lib/ship_spec.rb +6 -30
- data/spec/lib/stack/status_spec.rb +76 -0
- data/spec/lib/stop_spec.rb +13 -0
- data/spec/lib/task_spec.rb +5 -2
- data/spec/spec_helper.rb +1 -1
- data/ufo.gemspec +2 -0
- metadata +120 -6
- data/docs/_reference/ufo-upgrade3.md +0 -23
- data/docs/_reference/ufo-upgrade3_3_to_3_4.md +0 -23
data/lib/ufo/init.rb
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
module Ufo
|
|
2
2
|
class Init < Sequence
|
|
3
|
-
|
|
4
|
-
# https://github.com/erikhuda/thor/blob/master/lib/thor/actions.rb#L49
|
|
3
|
+
include Network::Helper
|
|
5
4
|
|
|
6
5
|
# Ugly, this is how I can get the options from to match with this Thor::Group
|
|
7
6
|
def self.cli_options
|
|
8
7
|
[
|
|
9
8
|
[:force, type: :boolean, desc: "Bypass overwrite are you sure prompt for existing files."],
|
|
10
|
-
[:image, required: true, desc: "Docker image name without the tag. Example: tongueroo/
|
|
11
|
-
[:app,
|
|
9
|
+
[:image, required: true, desc: "Docker image name without the tag. Example: tongueroo/demo-ufo. Configures ufo/settings.yml"],
|
|
10
|
+
[:app, desc: "App name. Preferably one word. Used in the generated ufo/task_definitions.rb. If not specified then the app name is inferred as the folder name."],
|
|
12
11
|
[:launch_type, default: "ec2", desc: "ec2 or fargate."],
|
|
13
12
|
[:execution_role_arn, desc: "execution role arn used by tasks, required for fargate."],
|
|
14
13
|
[:template, desc: "Custom template to use."],
|
|
15
14
|
[:template_mode, desc: "Template mode: replace or additive."],
|
|
15
|
+
[:vpc_id, desc: "Vpc id. For settings/network/default.yml."],
|
|
16
|
+
[:ecs_subnets, type: :array, desc: "Subnets for ECS tasks, defaults to --elb-subnets set to. For settings/network/default.yml"],
|
|
17
|
+
[:elb_subnets, type: :array, desc: "Subnets for ELB. For settings/network/default.yml"],
|
|
16
18
|
]
|
|
17
19
|
end
|
|
18
|
-
cli_options.each
|
|
19
|
-
class_option *args
|
|
20
|
-
end
|
|
20
|
+
cli_options.each { |o| class_option(*o) }
|
|
21
21
|
|
|
22
22
|
def setup_template_repo
|
|
23
23
|
return unless @options[:template]&.include?('/')
|
|
@@ -48,26 +48,29 @@ module Ufo
|
|
|
48
48
|
FileUtils.cd(dest)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
def set_network_options
|
|
52
|
+
configure_network_settings
|
|
53
|
+
end
|
|
54
|
+
|
|
51
55
|
def init_files
|
|
52
56
|
# map variables
|
|
53
|
-
@app = options[:app]
|
|
57
|
+
@app = options[:app] || inferred_app
|
|
54
58
|
@image = options[:image]
|
|
55
59
|
@execution_role_arn_input = get_execution_role_arn_input
|
|
56
60
|
# copy the files
|
|
57
61
|
puts "Setting up ufo project..."
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
else
|
|
63
|
-
copy_file ".ufo/templates/main.json.erb"
|
|
64
|
-
end
|
|
62
|
+
exclude_pattern = File.exist?("#{Ufo.root}/Dockerfile") ?
|
|
63
|
+
/(\.git|Dockerfile)/ :
|
|
64
|
+
/(\.git)/
|
|
65
|
+
directory ".", exclude_pattern: exclude_pattern
|
|
65
66
|
end
|
|
66
67
|
|
|
67
68
|
def upsert_gitignore
|
|
68
69
|
text =<<-EOL
|
|
69
|
-
.ufo/
|
|
70
|
+
.ufo/current
|
|
70
71
|
.ufo/data
|
|
72
|
+
.ufo/log
|
|
73
|
+
.ufo/output
|
|
71
74
|
EOL
|
|
72
75
|
if File.exist?(".gitignore")
|
|
73
76
|
append_to_file ".gitignore", text
|
|
@@ -77,9 +80,7 @@ EOL
|
|
|
77
80
|
end
|
|
78
81
|
|
|
79
82
|
def upsert_dockerignore
|
|
80
|
-
text
|
|
81
|
-
.ufo
|
|
82
|
-
EOL
|
|
83
|
+
text = ".ufo\n"
|
|
83
84
|
if File.exist?(".dockerignore")
|
|
84
85
|
append_to_file ".dockerignore", text
|
|
85
86
|
else
|
|
@@ -90,18 +91,30 @@ EOL
|
|
|
90
91
|
def user_message
|
|
91
92
|
puts "Starter ufo files created."
|
|
92
93
|
puts <<-EOL
|
|
94
|
+
Congrats 🎉 You have successfully set up ufo for your project.
|
|
93
95
|
#{"="*64}
|
|
94
|
-
Congrats 🎉 You have successfully set up ufo for your project. To deploy to ECS:
|
|
95
96
|
|
|
96
|
-
|
|
97
|
+
## Task Definition Customizations
|
|
97
98
|
|
|
98
99
|
If you need to customize the ECS task definition to configure things like memory and cpu allocation. You can do this by adjusting the files the .ufo/variables folder. These variables get applied to the .ufo/templates/main.json.erb task definition json that is passed to the ECS register task definition api.
|
|
99
100
|
|
|
100
101
|
Some additional starter example roles for your apps were set up in in .ufo/task_definitions.rb. Be sure to check it out and adjust it for your needs.
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
## Settings files
|
|
104
|
+
|
|
105
|
+
Additionally, ufo generated starter settings files at that further allow you to customize more settings.
|
|
106
|
+
|
|
107
|
+
* .ufo/settings.yml: general settings.
|
|
108
|
+
* .ufo/settings/cfn/default.yml: properties of CloudFormation resources that ufo creates.
|
|
109
|
+
* .ufo/settings/network/default.yml: network settings.
|
|
110
|
+
|
|
111
|
+
More more info refer to: http://ufoships.com/docs/settings/
|
|
112
|
+
|
|
113
|
+
To deploy to ECS:
|
|
114
|
+
|
|
115
|
+
ufo current --service #{@app}-web
|
|
116
|
+
ufo ship
|
|
103
117
|
|
|
104
|
-
More info: http://ufoships.com
|
|
105
118
|
EOL
|
|
106
119
|
end
|
|
107
120
|
end
|
data/lib/ufo/log_group.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Ufo
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def create
|
|
12
|
-
puts "Ensuring log group for #{@task_definition} exists"
|
|
12
|
+
puts "Ensuring log group for #{@task_definition.colorize(:green)} task definition exists"
|
|
13
13
|
return if @options[:noop]
|
|
14
14
|
|
|
15
15
|
Ufo.check_task_definition!(@task_definition)
|
|
@@ -17,6 +17,7 @@ module Ufo
|
|
|
17
17
|
task_def["containerDefinitions"].each do |container_def|
|
|
18
18
|
begin
|
|
19
19
|
log_group_name = container_def["logConfiguration"]["options"]["awslogs-group"]
|
|
20
|
+
puts "Log group name: #{log_group_name}"
|
|
20
21
|
rescue NoMethodError
|
|
21
22
|
# silence when the logConfiguration is not specified
|
|
22
23
|
end
|
data/lib/ufo/network.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Ufo
|
|
2
|
+
class Network < Command
|
|
3
|
+
autoload :Init, "ufo/network/init"
|
|
4
|
+
autoload :Helper, "ufo/network/helper"
|
|
5
|
+
autoload :Fetch, "ufo/network/fetch"
|
|
6
|
+
|
|
7
|
+
def self.cli_options
|
|
8
|
+
[
|
|
9
|
+
[:force, type: :boolean, desc: "Bypass overwrite are you sure prompt for existing files."],
|
|
10
|
+
[:subnets, type: :array, desc: "Subnets"],
|
|
11
|
+
[:vpc_id, desc: "Vpc id"],
|
|
12
|
+
[:filename, default: "default", desc: "Name of the settings file to create w/o extension."],
|
|
13
|
+
]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
cli_options.each { |o| option(*o) }
|
|
17
|
+
|
|
18
|
+
desc "init", "Creates network starter settings file."
|
|
19
|
+
long_desc Help.text("network:init")
|
|
20
|
+
def init
|
|
21
|
+
Init.start
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Provides access to default network settings for a vpc: subnets and security_group
|
|
2
|
+
# If no @vpc_id is provided to the initializer then the default vpc is used.
|
|
3
|
+
class Ufo::Network
|
|
4
|
+
class Fetch
|
|
5
|
+
include Ufo::AwsService
|
|
6
|
+
extend Memoist
|
|
7
|
+
|
|
8
|
+
def initialize(vpc_id)
|
|
9
|
+
@vpc_id = vpc_id
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def vpc_id
|
|
13
|
+
return @vpc_id if @vpc_id
|
|
14
|
+
|
|
15
|
+
resp = ec2.describe_vpcs(filters: [
|
|
16
|
+
{name: "isDefault", values: ["true"]}
|
|
17
|
+
])
|
|
18
|
+
resp.vpcs.first.vpc_id
|
|
19
|
+
end
|
|
20
|
+
memoize :vpc_id
|
|
21
|
+
|
|
22
|
+
# all subnets
|
|
23
|
+
def subnet_ids
|
|
24
|
+
resp = ec2.describe_subnets(filters: [
|
|
25
|
+
{name: "vpc-id", values: [vpc_id]}
|
|
26
|
+
])
|
|
27
|
+
resp.subnets.map(&:subnet_id).sort
|
|
28
|
+
end
|
|
29
|
+
memoize :subnet_ids
|
|
30
|
+
|
|
31
|
+
# default security group
|
|
32
|
+
def security_group_id
|
|
33
|
+
resp = ec2.describe_security_groups(filters: [
|
|
34
|
+
{name: "vpc-id", values: [vpc_id]},
|
|
35
|
+
{name: "group-name", values: ["default"]}
|
|
36
|
+
])
|
|
37
|
+
resp.security_groups.first.group_id
|
|
38
|
+
end
|
|
39
|
+
memoize :security_group_id
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class Ufo::Network
|
|
2
|
+
module Helper
|
|
3
|
+
private
|
|
4
|
+
# for balancer default profile
|
|
5
|
+
def configure_network_settings
|
|
6
|
+
@options = @options.dup
|
|
7
|
+
return test_network_settings if ENV['TEST']
|
|
8
|
+
|
|
9
|
+
fetch = Fetch.new(@options[:vpc_id])
|
|
10
|
+
@options[:vpc_id] ||= fetch.vpc_id
|
|
11
|
+
@options[:ecs_subnets] ||= fetch.subnet_ids
|
|
12
|
+
@options[:elb_subnets] ||= fetch.subnet_ids
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# hack for specs
|
|
16
|
+
def test_network_settings
|
|
17
|
+
@options[:vpc_id] = "vpc-111"
|
|
18
|
+
@options[:ecs_subnets] = ["subnet-111", "subnet-222"]
|
|
19
|
+
@options[:elb_subnets] = ["subnet-111", "subnet-222"]
|
|
20
|
+
@options
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Ufo
|
|
2
|
+
class Network::Init < Thor::Group
|
|
3
|
+
include Thor::Actions
|
|
4
|
+
include Network::Helper
|
|
5
|
+
|
|
6
|
+
add_runtime_options! # force, pretend, quiet, skip options
|
|
7
|
+
# https://github.com/erikhuda/thor/blob/master/lib/thor/actions.rb#L49
|
|
8
|
+
|
|
9
|
+
# Interesting, when defining the options in this class it screws up the ufo balance -h menu
|
|
10
|
+
Network.cli_options.each do |o|
|
|
11
|
+
class_option *o
|
|
12
|
+
end
|
|
13
|
+
def self.source_paths
|
|
14
|
+
[File.expand_path("../../../template/.ufo/settings/network", __FILE__)]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def set_network_options
|
|
18
|
+
configure_network_settings
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def starter_files
|
|
22
|
+
filename = @options[:filename] || "default"
|
|
23
|
+
template "default.yml", ".ufo/settings/network/#{filename}.yml"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/ufo/param.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require 'yaml'
|
|
2
|
-
require 'memoist'
|
|
3
2
|
|
|
4
3
|
module Ufo
|
|
5
4
|
class Param
|
|
@@ -13,7 +12,8 @@ module Ufo
|
|
|
13
12
|
upgrade_message!
|
|
14
13
|
|
|
15
14
|
result = RenderMePretty.result(@params_path, context: template_scope)
|
|
16
|
-
YAML.load(result)
|
|
15
|
+
data = YAML.load(result) || {}
|
|
16
|
+
data.deep_symbolize_keys
|
|
17
17
|
end
|
|
18
18
|
memoize :data
|
|
19
19
|
|
|
@@ -24,15 +24,15 @@ module Ufo
|
|
|
24
24
|
# Ufo version 3.3 to 3.4 added a concept of a .ufo/params.yml file to support
|
|
25
25
|
# fargate: https://github.com/tongueroo/ufo/pull/31
|
|
26
26
|
#
|
|
27
|
-
# Warn user and tell them to run the `ufo
|
|
27
|
+
# Warn user and tell them to run the `ufo upgrade v3_3to3_4` command to upgrade.
|
|
28
28
|
def upgrade_message!
|
|
29
29
|
return if File.exist?(@params_path)
|
|
30
30
|
|
|
31
31
|
puts "ERROR: Your project is missing the .ufo/params.yml.".colorize(:red)
|
|
32
|
-
puts "This was added in ufo version 3.4
|
|
32
|
+
puts "This was added in ufo version 3.4"
|
|
33
33
|
puts "You can find more info about the params file here: http://ufoships.com/docs/params/"
|
|
34
34
|
puts "To upgrade run:"
|
|
35
|
-
puts " ufo
|
|
35
|
+
puts " ufo upgrade v3_3to3_4"
|
|
36
36
|
exit 1
|
|
37
37
|
end
|
|
38
38
|
end
|
data/lib/ufo/ps.rb
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require 'text-table'
|
|
2
|
+
|
|
3
|
+
module Ufo
|
|
4
|
+
class Ps < Base
|
|
5
|
+
autoload :Task, 'ufo/ps/task'
|
|
6
|
+
|
|
7
|
+
delegate :service, to: :info
|
|
8
|
+
|
|
9
|
+
def run
|
|
10
|
+
unless service
|
|
11
|
+
puts no_service_message
|
|
12
|
+
return
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
summary
|
|
16
|
+
if task_arns.empty?
|
|
17
|
+
puts "There are 0 running tasks."
|
|
18
|
+
return
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
resp = ecs.describe_tasks(tasks: task_arns, cluster: @cluster)
|
|
22
|
+
display_info(resp)
|
|
23
|
+
|
|
24
|
+
display_scale_help
|
|
25
|
+
display_target_group_help
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def summary
|
|
29
|
+
return unless @options[:summary]
|
|
30
|
+
puts "=> Service: #{@pretty_service_name}"
|
|
31
|
+
puts " Service name: #{service.service_name}"
|
|
32
|
+
puts " Status: #{service.status}"
|
|
33
|
+
puts " Running count: #{service.running_count}"
|
|
34
|
+
puts " Desired count: #{service.desired_count}"
|
|
35
|
+
puts " Launch type: #{service.launch_type}"
|
|
36
|
+
puts " Task definition: #{service.task_definition.split('/').last}"
|
|
37
|
+
elb = info.load_balancer(service)
|
|
38
|
+
if elb
|
|
39
|
+
puts " Elb: #{elb.dns_name}"
|
|
40
|
+
puts " Elb type: #{elb.type}"
|
|
41
|
+
end
|
|
42
|
+
puts " Route53: #{info.route53_dns}" if info.route53_dns
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def display_target_group_help
|
|
46
|
+
events = service["events"][0..4]
|
|
47
|
+
return if events[0].message =~ /has reached a steady state/
|
|
48
|
+
|
|
49
|
+
# The error currently happens to be the 5th element.
|
|
50
|
+
#
|
|
51
|
+
# Example:
|
|
52
|
+
# "(service XXX) (instance i-XXX) (port 32875) is unhealthy in (target-group arn:aws:elasticloadbalancing:us-east-1:111111111111:targetgroup/devel-Targe-1111111111111/1111111111111111) due to (reason Health checks failed with these codes: [400])">]
|
|
53
|
+
error_event = events.find do |e|
|
|
54
|
+
e.message =~ /is unhealthy in/ &&
|
|
55
|
+
e.message =~ /targetgroup/
|
|
56
|
+
end
|
|
57
|
+
return unless error_event
|
|
58
|
+
|
|
59
|
+
puts "There are targets the target group reporting unhealthy. This can cause containers to cycle. Here's the error:"
|
|
60
|
+
puts error_event.message.colorize(:red)
|
|
61
|
+
puts "Check out the ECS console events tab for more info."
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# If the running count less than the desired account yet, check the events
|
|
65
|
+
# and show a message with helpful debugging information.
|
|
66
|
+
def display_scale_help
|
|
67
|
+
return if service.running_count >= service.desired_count
|
|
68
|
+
|
|
69
|
+
events = service["events"][0..3] # only check most recent 4 messages
|
|
70
|
+
error_event = events.find do |e|
|
|
71
|
+
e.message =~ /was unable to place a task/
|
|
72
|
+
end
|
|
73
|
+
return unless error_event
|
|
74
|
+
|
|
75
|
+
puts "There is an issue scaling the #{@service.colorize(:green)} service to #{service.desired_count}. Here's the error:"
|
|
76
|
+
puts error_event.message.colorize(:red)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def display_info(resp)
|
|
80
|
+
table = Text::Table.new
|
|
81
|
+
table.head = Task.header
|
|
82
|
+
resp["tasks"].each do |t|
|
|
83
|
+
task = Task.new(t)
|
|
84
|
+
table.rows << task.to_a unless task.hide?
|
|
85
|
+
end
|
|
86
|
+
puts table
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def task_arns
|
|
90
|
+
threads, results = [], {}
|
|
91
|
+
statuses = %w[RUNNING PENDING STOPPED]
|
|
92
|
+
statuses.each do |status|
|
|
93
|
+
threads << Thread.new do
|
|
94
|
+
resp = ecs.list_tasks(service_name: service.service_name, cluster: @cluster, desired_status: status)
|
|
95
|
+
results[status] = resp.task_arns
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
threads.map(&:join)
|
|
99
|
+
results.values.flatten.uniq
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
data/lib/ufo/ps/task.rb
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
class Ufo::Ps
|
|
2
|
+
class Task
|
|
3
|
+
def self.header
|
|
4
|
+
%w[Id Name Release Started Status Notes]
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def initialize(task)
|
|
8
|
+
@task = task
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_a
|
|
12
|
+
[id, name, release, started, status, notes]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def id
|
|
16
|
+
@task['task_arn'].split('/').last.split('-').first
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def name
|
|
20
|
+
@task["overrides"]["container_overrides"].first["name"]
|
|
21
|
+
rescue NoMethodError
|
|
22
|
+
@task["containers"].first["name"]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def release
|
|
26
|
+
@task["task_definition_arn"].split('/').last
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def started
|
|
30
|
+
started = Time.parse(@task["started_at"].to_s)
|
|
31
|
+
relative_time(started)
|
|
32
|
+
rescue ArgumentError
|
|
33
|
+
"PENDING"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def started_at
|
|
37
|
+
Time.parse(@task["started_at"].to_s)
|
|
38
|
+
rescue ArgumentError
|
|
39
|
+
nil
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# hide stopped tasks that are older than 10 minutes
|
|
43
|
+
def hide?
|
|
44
|
+
status == "STOPPED" && started_at < Time.now - 60 * 10
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def status
|
|
48
|
+
@task["last_status"]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def notes
|
|
52
|
+
return unless @task["stopped_reason"]
|
|
53
|
+
|
|
54
|
+
if @task["stopped_reason"] =~ /Task failed ELB health checks/
|
|
55
|
+
"Failed ELB health check"
|
|
56
|
+
else
|
|
57
|
+
@task["stopped_reason"]
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# https://stackoverflow.com/questions/195740/how-do-you-do-relative-time-in-rails/195894
|
|
62
|
+
def relative_time(start_time)
|
|
63
|
+
diff_seconds = Time.now - start_time
|
|
64
|
+
case diff_seconds
|
|
65
|
+
when 0 .. 59
|
|
66
|
+
"#{diff_seconds.to_i} seconds ago"
|
|
67
|
+
when 60 .. (3600-1)
|
|
68
|
+
"#{(diff_seconds/60).to_i} minutes ago"
|
|
69
|
+
when 3600 .. (3600*24-1)
|
|
70
|
+
"#{(diff_seconds/3600).to_i} hours ago"
|
|
71
|
+
when (3600*24) .. (3600*24*30)
|
|
72
|
+
"#{(diff_seconds/(3600*24)).to_i} days ago"
|
|
73
|
+
else
|
|
74
|
+
start_time.strftime("%m/%d/%Y")
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|