ufo 6.2.2 → 6.2.5

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 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