ufo 6.2.2 → 6.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e630cb6fc68958a6b7f7264e6b0ff03a2d41ae13d9a1648bd13fa601d9f9aae0
4
- data.tar.gz: 2693b4ca4e3e5ffa31ff881f706de093792d93a4ff7263820308565d44685c38
3
+ metadata.gz: 69d0e411c4b48b8ec8a0a2148caf5501b3c038cb991585c4741027579a102e0c
4
+ data.tar.gz: f080bdf97e783b18bc54723ced3be52557b0749094451561de41766c052aba0e
5
5
  SHA512:
6
- metadata.gz: 116244ca9466e2458845904b34d99bc1fd2e7d1d8379c32066d2f90d70cfe7eb84628552a8250f7d4cca13dcdcf1cdad0ba812e602ba1df25c4f0b383131c057
7
- data.tar.gz: 7e7aa81c1595f231465f1694a80dc7e4f0a8f7f7c77399e28b12b71c109a2c5ea0b9674fd0e8a9b485792253e16c4fd4a27734a121affd01bb69e163fb6e9f51
6
+ metadata.gz: 860f1d782b915338e903d2c2c0cad43fbe4a915261b46a2b615a7d24870247170a3041de32b6e9de8b11161da1c8447dc3d12683e9179c8c6cd0af7ef3dc4d77
7
+ data.tar.gz: c02bc1f698f85055e2e1c99b7fbf6cf730044e23b7584509a5c2e66bd79259097b2c5ccf1706b186a64b329db31e5678fe6eacb3f120724dbfa896a0ab6fbb00
@@ -0,0 +1,15 @@
1
+ function scale_asg_to() {
2
+ n=$1
3
+ ASG=$(asg)
4
+ echo "Scaling $ASG to $n"
5
+ aws autoscaling update-auto-scaling-group --auto-scaling-group-name $ASG \
6
+ --desired-capacity $n --min-size $n --max-size $n
7
+ }
8
+
9
+ # aws cloudformation describe-stacks --stack-name ecs-qa | jq -r '.Stacks[].Outputs[] | select(.OutputKey == "Asg") | .OutputValue'
10
+ # aws cloudformation describe-stack-resources --stack-name ecs-qa | jq -r '.StackResources[] | select(.LogicalResourceId == "Asg") | .PhysicalResourceId'
11
+ function asg() {
12
+ STACK_NAME=ecs-qa
13
+ ASG=$(aws cloudformation describe-stacks --stack-name $STACK_NAME | jq -r '.Stacks[].Outputs[] | select(.OutputKey == "Asg") | .OutputValue')
14
+ echo $ASG
15
+ }
@@ -1,5 +1,8 @@
1
1
  #!/bin/bash
2
2
 
3
+ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4
+ source "$DIR/asg.sh"
5
+
3
6
  final_status=0
4
7
  function capture_status {
5
8
  if [ "$?" -ne "0" ] && [ $final_status -ne 1 ] ; then
@@ -40,6 +43,7 @@ cat .ufo/vars/base.rb
40
43
  cat .ufo/vars/dev.rb
41
44
 
42
45
  export UFO_ENV=qa
46
+ scale_asg_to 1
43
47
 
44
48
  # Deploy
45
49
  ufo ship -y
@@ -95,3 +99,5 @@ ufo ps # see full output for debugging
95
99
  ufo ps 2>&1 | grep Stack | grep worker # should be success. IE: exit 0
96
100
  ufo destroy -y
97
101
  ufo ps 2>&1 | grep No | grep found # should be success. IE: exit 0
102
+
103
+ scale_asg_to 0
@@ -1,5 +1,6 @@
1
1
  iam_policy(
2
2
  "application-autoscaling",
3
+ "autoscaling",
3
4
  "cloudformation",
4
5
  "ec2",
5
6
  "ecr",
@@ -1,8 +1,8 @@
1
- github_url("https://github.com/boltops-tools/ufo")
2
- linux_image("aws/codebuild/amazonlinux2-x86_64-standard:3.0")
3
- environment_variables(
4
- DOCKER_USER: "ssm:/codebuild/ufo/DOCKER_USER",
5
- DOCKER_PASS: "ssm:/codebuild/ufo/DOCKER_PASS",
1
+ github("boltops-tools/ufo")
2
+ image("aws/codebuild/amazonlinux2-x86_64-standard:3.0")
3
+ env_vars(
4
+ DOCKER_USER: "ssm:/#{Cody.env}/DOCKER_USER",
5
+ DOCKER_PASS: "ssm:/#{Cody.env}/DOCKER_PASS",
6
6
  )
7
7
 
8
8
  # triggers(
data/.gitignore CHANGED
@@ -19,3 +19,4 @@ tmp
19
19
 
20
20
  .ruby-version
21
21
  Gemfile.lock
22
+ .cody/output
data/CHANGELOG.md CHANGED
@@ -3,6 +3,18 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [6.2.5] - 2022-03-24
7
+ - [#159](https://github.com/tongueroo/ufo/pull/159) improve ufo call line
8
+ - [#160](https://github.com/tongueroo/ufo/pull/160) conventionally lookup up secrets and env file
9
+ - [#161](https://github.com/tongueroo/ufo/pull/161) layering support for env files
10
+ - improve acceptance pipeline
11
+
12
+ ## [6.2.4] - 2022-03-20
13
+ - [#158](https://github.com/tongueroo/ufo/pull/158) warn on missing env and secrets file instead of error
14
+
15
+ ## [6.2.3] - 2022-03-20
16
+ - [#157](https://github.com/tongueroo/ufo/pull/157) layering.show_for_commands option
17
+
6
18
  ## [6.2.2] - 2022-03-20
7
19
  - [#155](https://github.com/tongueroo/ufo/pull/155) layering.show option ability to show layers
8
20
  - [#156](https://github.com/tongueroo/ufo/pull/156) extra layering support
data/lib/ufo/cli/scale.rb CHANGED
@@ -54,6 +54,7 @@ class Ufo::CLI
54
54
 
55
55
  def register_scalable_target(scalable_target)
56
56
  # service/dev/app1-web-dev-EcsService-Q0XkN6VtxGWv|ecs:service:DesiredCount|ecs
57
+ return unless scalable_target && scalable_target.physical_resource_id # stack still creating
57
58
  resource_id, scalable_dimension, service_namespace = scalable_target.physical_resource_id.split('|')
58
59
  applicationautoscaling.register_scalable_target(
59
60
  max_capacity: @max,
data/lib/ufo/command.rb CHANGED
@@ -78,7 +78,7 @@ module Ufo
78
78
  # See comment where configure_dsl_evaluator is used about Ufo.role
79
79
  def configure_dsl_evaluator
80
80
  DslEvaluator.configure do |config|
81
- config.backtrace.select_pattern = Ufo.root.to_s
81
+ config.backtrace.select_pattern = "#{Ufo.root}/.ufo"
82
82
  config.logger = Ufo.logger
83
83
  config.on_exception = :exit
84
84
  config.root = Ufo.root
@@ -0,0 +1,39 @@
1
+ # Some limitations:
2
+ #
3
+ # * Only parsing one file: .ufo/config.rb
4
+ # * If user is using Ruby code that cannot be parse will fallback to default
5
+ #
6
+ # Think it's worth it so user only has to configure
7
+ #
8
+ # config.layering.show = true
9
+ #
10
+ class Ufo::Config
11
+ class Parse
12
+ def for(config, type: :boolean)
13
+ lines = IO.readlines("#{Ufo.root}/.ufo/config.rb")
14
+ config_line = lines.find do |l|
15
+ # IE: Regexp.new("config\.layering.show.*=")
16
+ regexp = Regexp.new("config\.#{config}.*=")
17
+ l =~ regexp && l !~ /^\s+#/
18
+ end
19
+ return false unless config_line # default is false
20
+ config_value = config_line.gsub(/.*=/,'').strip.gsub(/["']/,'')
21
+ case type
22
+ when :boolean
23
+ config_value != "false" && config_value != "nil"
24
+ when :array
25
+ eval(config_value) # IE: '["a"]' => ["a"]
26
+ else
27
+ raise "Type #{type.inspect} not supported"
28
+ end
29
+ rescue Exception => e
30
+ # if ENV['UFO_DEBUG']
31
+ puts "#{e.class} #{e.message}".color(:yellow)
32
+ puts "WARN: Unable to parse for config.layering.show".color(:yellow)
33
+ puts "Using default: config.layering.show = false"
34
+ # end
35
+ false
36
+ end
37
+ end
38
+ end
39
+
data/lib/ufo/config.rb CHANGED
@@ -86,7 +86,8 @@ module Ufo
86
86
  config.exec.enabled = true # EcsService EnableExecuteCommand
87
87
 
88
88
  config.layering = ActiveSupport::OrderedOptions.new
89
- config.layering.show = show_layers?
89
+ config.layering.show = parsed_layering_show
90
+ config.layering.show_for_commands = parsed_layering_show_for
90
91
 
91
92
  config.log = ActiveSupport::OrderedOptions.new
92
93
  config.log.root = Ufo.log_root
@@ -111,6 +112,7 @@ module Ufo
111
112
  config.secrets.pattern.secretsmanager = ":APP-:ENV-:SECRET_NAME" # => demo-dev-DB_PASS
112
113
  config.secrets.pattern.ssm = ":APP/:ENV/:SECRET_NAME" # => demo/dev/DB_PASS
113
114
  config.secrets.provider = "ssm" # default provider for conventional expansion IE: ssm or secretsmanager
115
+ config.secrets.warning = true
114
116
 
115
117
  config.ship = ActiveSupport::OrderedOptions.new
116
118
  config.ship.docker = ActiveSupport::OrderedOptions.new
@@ -165,7 +167,7 @@ module Ufo
165
167
  end
166
168
  # load_project_config gets called so early that logger is not yet configured.
167
169
  # Cannot use Ufo.config yet and cannot use logger which relies on Ufo.config
168
- # Use puts and use show_layers? which parses for the config
170
+ # Use puts and use parsed_layering_show
169
171
  show = show_layers?
170
172
  puts "Config Layers" if show
171
173
  layers.each do |layer|
@@ -180,34 +182,25 @@ module Ufo
180
182
  end
181
183
 
182
184
  def show_layers?
183
- ENV['UFO_LAYERS'] || parse_for_layering_show
185
+ show_for = parsed_layering_show_for
186
+ command = ARGV[0]
187
+ parsed_layering_show && show_for.include?(command)
184
188
  end
185
- private :show_layers?
186
189
 
187
- # Some limitations:
188
- #
189
- # * Only parsing one file: .ufo/config.rb
190
- # * If user is using Ruby code that cannot be parse will fallback to default
191
- #
192
- # Think it's worth it so user only has to configure
193
- #
194
- # config.layering.show = true
195
- #
196
- def parse_for_layering_show
197
- lines = IO.readlines("#{Ufo.root}/.ufo/config.rb")
198
- config_line = lines.find { |l| l =~ /config\.layering.show.*=/ && l !~ /^\s+#/ }
199
- return false unless config_line # default is false
200
- config_value = config_line.gsub(/.*=/,'').strip.gsub(/["']/,'')
201
- config_value != "false" && config_value != "nil"
202
- rescue Exception => e
203
- if ENV['UFO_DEBUG']
204
- puts "#{e.class} #{e.message}".color(:yellow)
205
- puts "WARN: Unable to parse for config.layering.show".color(:yellow)
206
- puts "Using default: config.layering.show = false"
207
- end
208
- false
190
+ def parsed_layering_show_for
191
+ parse.for("layering.show_for_commands", type: :array) || %w[build ship] # IE: ps exec logs are not shown
192
+ end
193
+ memoize :parsed_layering_show_for
194
+
195
+ def parsed_layering_show
196
+ ENV['UFO_LAYERS'] || parse.for("layering.show", type: :boolean)
197
+ end
198
+ private :parsed_layering_show
199
+
200
+ def parse
201
+ Parse.new
209
202
  end
210
- memoize :parse_for_layering_show
203
+ memoize :parse
211
204
 
212
205
  # Works similiar to Layering::Layer. Consider combining the logic and usin Layering::Layer
213
206
  #
data/lib/ufo/info.rb CHANGED
@@ -28,6 +28,7 @@ module Ufo
28
28
  )
29
29
  target_group = resp.target_groups.first
30
30
  load_balancer_arn = target_group.load_balancer_arns.first # assume first only
31
+ return unless load_balancer_arn # can occur while stack is being deleted
31
32
 
32
33
  resp = elb.describe_load_balancers(load_balancer_arns: [load_balancer_arn])
33
34
  resp.load_balancers.first
@@ -68,9 +68,7 @@ module Ufo::Layering
68
68
  paths
69
69
  end
70
70
 
71
- @@shown = false
72
71
  def show_layers(paths)
73
- return if @@shown
74
72
  logger.debug "Layers:"
75
73
  paths.each do |path|
76
74
  if ENV['UFO_LAYERS_ALL']
@@ -79,7 +77,6 @@ module Ufo::Layering
79
77
  logger.info " #{pretty_path(path)}" if File.exist?(path)
80
78
  end
81
79
  end
82
- @@shown = true
83
80
  end
84
81
  end
85
82
  end
@@ -14,7 +14,7 @@ module Ufo::TaskDefinition::Helpers
14
14
  else
15
15
  # Logger causes infinite loop when waf helper used in .ufo/
16
16
  logger.warn "WARN: ACM cert not found: #{domain}".color(:yellow)
17
- call_line = ufo_config_call_line
17
+ call_line = ufo_call_line
18
18
  DslEvaluator.print_code(call_line)
19
19
  nil
20
20
  end
@@ -12,7 +12,7 @@ module Ufo::TaskDefinition::Helpers
12
12
  resp.repositories.first
13
13
  rescue Aws::ECR::Errors::RepositoryNotFoundException => e
14
14
  logger.warn "WARN: #{e.class} #{e.message}".color(:yellow)
15
- call_line = ufo_config_call_line
15
+ call_line = ufo_call_line
16
16
  DslEvaluator.print_code(call_line)
17
17
  nil
18
18
  end
@@ -9,7 +9,7 @@ module Ufo::TaskDefinition::Helpers
9
9
  stack = find_stack(stack_name)
10
10
  unless stack
11
11
  logger.error "ERROR: Stack not found: #{stack_name}".color(:red)
12
- call_line = ufo_config_call_line
12
+ call_line = ufo_call_line
13
13
  DslEvaluator.print_code(call_line)
14
14
  return
15
15
  end
@@ -5,8 +5,10 @@ module Ufo::TaskDefinition::Helpers::Vars
5
5
  extend Memoist
6
6
  include AwsHelper
7
7
  include Ufo::Concerns::Names
8
- include Ufo::Utils::Pretty
9
8
  include Ufo::Config::CallableOption::Concern
9
+ include Ufo::Utils::CallLine
10
+ include Ufo::Utils::Logging
11
+ include Ufo::Utils::Pretty
10
12
 
11
13
  def initialize(options={})
12
14
  # use either file or text. text takes higher precedence
@@ -15,25 +17,61 @@ module Ufo::TaskDefinition::Helpers::Vars
15
17
  end
16
18
 
17
19
  def content
18
- @text || read(@file)
20
+ @text if @text
21
+ read(*find_files)
19
22
  end
20
23
 
21
- def read(path)
22
- full_path = "#{Ufo.root}/#{path}"
23
- unless File.exist?(full_path)
24
- puts "The #{pretty_path(full_path)} env file could not be found. Are you sure it exists?"
25
- exit 1
24
+ # Not considering .env files in project root since this is more for deployment
25
+ # Also ufo supports a smarter format than the normal .env files
26
+ def find_files
27
+ return @file if @file
28
+ layers = [
29
+ "base",
30
+ "#{Ufo.env}",
31
+ "#{Ufo.app}",
32
+ "#{Ufo.app}/base",
33
+ "#{Ufo.app}/#{Ufo.env}",
34
+ "#{Ufo.app}/#{Ufo.role}",
35
+ "#{Ufo.app}/#{Ufo.role}/base",
36
+ "#{Ufo.app}/#{Ufo.role}/#{Ufo.env}",
37
+ ]
38
+ layers.map! { |l| ".ufo/env_files/#{l}#{@ext}" }
39
+ show_layers(layers)
40
+ layers.select! { |l| File.exist?(l) }
41
+ layers
42
+ end
43
+
44
+ def show_layers(paths)
45
+ label = @ext.sub('.','').capitalize
46
+ paths.each do |path|
47
+ if ENV['UFO_LAYERS_ALL']
48
+ logger.info " #{path}"
49
+ elsif Ufo.config.layering.show
50
+ logger.info " #{path} "if File.exist?(path)
51
+ end
26
52
  end
27
- IO.read(full_path)
28
53
  end
29
54
 
30
- def env
55
+ def read(*paths)
56
+ text= ""
57
+ paths.compact.each do |path|
58
+ text << IO.read("#{Ufo.root}/#{path}")
59
+ text << "\n"
60
+ end
61
+ text
62
+ end
63
+
64
+ def env(ext='.env')
65
+ @ext = ext # assign instance variable so dont have to pass around
31
66
  lines = filtered_lines(content)
32
67
  lines.map do |line|
68
+ line = line.sub('export ', '') # allow user to use export. ufo ignores it
33
69
  key,*value = line.strip.split("=").map do |x|
34
70
  remove_surrounding_quotes(x.strip)
35
71
  end
36
72
  value = value.join('=')
73
+ # Note: env vars do NOT support valueFrom
74
+ # Docs: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definition_environment
37
75
  {
38
76
  name: key,
39
77
  value: value,
@@ -42,7 +80,7 @@ module Ufo::TaskDefinition::Helpers::Vars
42
80
  end
43
81
 
44
82
  def secrets
45
- secrets = env
83
+ secrets = env('.secrets')
46
84
  secrets.map do |item|
47
85
  value = item.delete(:value)
48
86
  arn = normalize_to_arn(item[:name], value)
@@ -69,11 +107,15 @@ module Ufo::TaskDefinition::Helpers::Vars
69
107
  # arn:aws:ssm:us-west-2:111111111111:parameter/demo/dev/DB-NAME
70
108
  # arn:aws:ssm:us-west-2:111111111111:parameter/demo/dev/DB-NAME
71
109
  def expansion(arn)
72
- # performance improvement only run names.expansion on the name portion
73
110
  md = arn.match(/(.*:)(parameter\/|secret:)(.*)/)
74
- prefix, type, name = md[1], md[2], md[3]
75
- expanded_name = names.expansion(name, dasherize: false) # dasherize: false. dont turn SECRET_NAME => SECRET-NAME
76
- "#{prefix}#{type}#{expanded_name}"
111
+ if md
112
+ prefix, type, name = md[1], md[2], md[3]
113
+ # performance improvement only run names.expansion on the name portion
114
+ expanded_name = names.expansion(name, dasherize: false) # dasherize: false. dont turn SECRET_NAME => SECRET-NAME
115
+ "#{prefix}#{type}#{expanded_name}"
116
+ else # not arn full value. In case user accidentally puts value in .secrets file KEY=value
117
+ names.expansion(arn, dasherize: false) # dasherize: false. dont turn SECRET_NAME => SECRET-NAME
118
+ end
77
119
  end
78
120
 
79
121
  # Examples with config.secrets.provider = "ssm"
@@ -6,7 +6,7 @@ module Ufo::TaskDefinition::Helpers
6
6
  alias_method :env_vars, :env
7
7
  alias_method :environment, :env
8
8
 
9
- def env_file(path)
9
+ def env_file(path=nil)
10
10
  Builder.new(file: path).env
11
11
  end
12
12
 
@@ -14,7 +14,7 @@ module Ufo::TaskDefinition::Helpers
14
14
  Builder.new(text: text).secrets
15
15
  end
16
16
 
17
- def secrets_file(path)
17
+ def secrets_file(path=nil)
18
18
  Builder.new(file: path).secrets
19
19
  end
20
20
  end
@@ -20,7 +20,7 @@ module Ufo::TaskDefinition::Helpers
20
20
  else
21
21
  # Logger causes infinite loop when waf helper used in .ufo/
22
22
  logger.warn "WARN: Web ACL not found: #{name}".color(:yellow)
23
- call_line = ufo_config_call_line
23
+ call_line = ufo_call_line
24
24
  DslEvaluator.print_code(call_line)
25
25
  end
26
26
  end
@@ -2,7 +2,7 @@ module Ufo::Utils
2
2
  module CallLine
3
3
  include Pretty
4
4
 
5
- def ufo_config_call_line
5
+ def ufo_call_line
6
6
  caller.find { |l| l.include?('.ufo/') }
7
7
  end
8
8
  end
data/lib/ufo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ufo
2
- VERSION = "6.2.2"
2
+ VERSION = "6.2.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ufo
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.2.2
4
+ version: 6.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-20 00:00:00.000000000 Z
11
+ date: 2022-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-logs
@@ -453,10 +453,11 @@ extensions: []
453
453
  extra_rdoc_files: []
454
454
  files:
455
455
  - ".cody/README.md"
456
+ - ".cody/acceptance/bin/asg.sh"
456
457
  - ".cody/acceptance/bin/build.sh"
457
458
  - ".cody/acceptance/buildspec.yml"
459
+ - ".cody/acceptance/iam_role.rb"
458
460
  - ".cody/acceptance/project.rb"
459
- - ".cody/acceptance/role.rb"
460
461
  - ".cody/shared/script/install.sh"
461
462
  - ".cody/shared/script/install/ufo.sh"
462
463
  - ".github/ISSUE_TEMPLATE.md"
@@ -594,6 +595,7 @@ files:
594
595
  - lib/ufo/config/callable_option.rb
595
596
  - lib/ufo/config/callable_option/concern.rb
596
597
  - lib/ufo/config/inits.rb
598
+ - lib/ufo/config/parse.rb
597
599
  - lib/ufo/core.rb
598
600
  - lib/ufo/docker/builder.rb
599
601
  - lib/ufo/docker/cleaner.rb