ufo 6.2.3 → 6.3.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/.cody/acceptance/bin/asg.sh +15 -0
  3. data/.cody/acceptance/bin/build.sh +6 -0
  4. data/.cody/acceptance/{role.rb → iam_role.rb} +1 -0
  5. data/.cody/acceptance/project.rb +5 -5
  6. data/.gitignore +1 -0
  7. data/CHANGELOG.md +12 -0
  8. data/lib/templates/hooks/docker.rb +9 -0
  9. data/lib/templates/hooks/ufo.rb +9 -0
  10. data/lib/ufo/autoloader.rb +1 -1
  11. data/lib/ufo/cfn/stack/builder/resources/iam_roles/base.rb +2 -2
  12. data/lib/ufo/cfn/stack.rb +17 -13
  13. data/lib/ufo/cli/build.rb +0 -5
  14. data/lib/ufo/cli/destroy.rb +13 -10
  15. data/lib/ufo/cli/help/new/hook.md +7 -0
  16. data/lib/ufo/cli/new/hook.rb +18 -0
  17. data/lib/ufo/cli/new.rb +11 -4
  18. data/lib/ufo/cli/scale.rb +1 -0
  19. data/lib/ufo/command.rb +1 -1
  20. data/lib/ufo/config.rb +4 -0
  21. data/lib/ufo/docker/builder.rb +5 -1
  22. data/lib/ufo/docker/pusher.rb +5 -1
  23. data/lib/ufo/hooks/builder.rb +51 -0
  24. data/lib/ufo/hooks/concern.rb +10 -0
  25. data/lib/ufo/hooks/dsl.rb +20 -0
  26. data/lib/ufo/hooks/runner.rb +37 -0
  27. data/lib/ufo/iam_role/dsl.rb +1 -1
  28. data/lib/ufo/iam_role/registry.rb +2 -2
  29. data/lib/ufo/info.rb +1 -0
  30. data/lib/ufo/layering/layer.rb +1 -4
  31. data/lib/ufo/param.rb +1 -2
  32. data/lib/ufo/task_definition/helpers/acm.rb +1 -1
  33. data/lib/ufo/task_definition/helpers/ecr.rb +1 -1
  34. data/lib/ufo/task_definition/helpers/stack_output.rb +1 -1
  35. data/lib/ufo/task_definition/helpers/vars/builder.rb +56 -14
  36. data/lib/ufo/task_definition/helpers/vars.rb +2 -2
  37. data/lib/ufo/task_definition/helpers/waf.rb +1 -1
  38. data/lib/ufo/utils/call_line.rb +1 -1
  39. data/lib/ufo/version.rb +1 -1
  40. data/spec/ufo/iam_role/builder_spec.rb +1 -1
  41. data/spec/ufo/iam_role/dsl_spec.rb +2 -2
  42. metadata +12 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fd574a73d9028bd0627e5c7d74b5bb516ee62aa1ae2a0d3c85f01470ef39284
4
- data.tar.gz: 96fcdff5429e785572cff2f4face5cc2100a1ce95a912adf6bfc275343471518
3
+ metadata.gz: 91051471ac72ee1a31948333cc0009d51f1d6ca1e1e170abe54d492a94a046f5
4
+ data.tar.gz: 4aa76fab580eb121d8e257fa7461d3be171334d2be1037bd0365988065e03f8a
5
5
  SHA512:
6
- metadata.gz: 11fccb6c4b62fe986f77a12e2aeb2d67ec7d2874ca1a9eed9afab32317a94e5235340896bd7fc590abf665b06bccfe4961fda78a0b77b2749cfbaffb4361dca3
7
- data.tar.gz: 32e9654b2700f3445a2383a84e323458bc1b81368901c3d83dac7c4d809fa7c5ef5d6bf5405dbd858b95f0ff34f8939f4660ee35118a11b5fa8976868c6f9b93
6
+ metadata.gz: 90f134dd07a15a153b7e8f4fe82d4c12dccbaea80e2041e5ff23431bacd28a78a5077d1ba5e4a8508926bfb91510ff0113e185658d444981730dc32447f552f1
7
+ data.tar.gz: af3e344e51334b7c3dd6a82fb23403da39717fb77bb15883632146ca79a3b4edc57a61dedd260d42b52d6652c4a129389acbac1009444c9da140fefb1d77ace2
@@ -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.3.0] - 2022-03-25
7
+ - [#162](https://github.com/tongueroo/ufo/pull/162) hooks support
8
+
9
+ ## [6.2.5] - 2022-03-24
10
+ - [#159](https://github.com/tongueroo/ufo/pull/159) improve ufo call line
11
+ - [#160](https://github.com/tongueroo/ufo/pull/160) conventionally lookup up secrets and env file
12
+ - [#161](https://github.com/tongueroo/ufo/pull/161) layering support for env files
13
+ - improve acceptance pipeline
14
+
15
+ ## [6.2.4] - 2022-03-20
16
+ - [#158](https://github.com/tongueroo/ufo/pull/158) warn on missing env and secrets file instead of error
17
+
6
18
  ## [6.2.3] - 2022-03-20
7
19
  - [#157](https://github.com/tongueroo/ufo/pull/157) layering.show_for_commands option
8
20
 
@@ -0,0 +1,9 @@
1
+ # Docs: https://ufoships.com/docs/config/hooks/docker/
2
+
3
+ before("build",
4
+ execute: "echo 'docker build before hook'",
5
+ )
6
+
7
+ after("build",
8
+ execute: "echo 'docker build after hook'",
9
+ )
@@ -0,0 +1,9 @@
1
+ # Docs: https://ufoships.com/docs/config/hooks/ufo/
2
+
3
+ before("ship",
4
+ execute: "echo 'ufo before ship hook'",
5
+ )
6
+
7
+ after("ship",
8
+ execute: "echo 'ufo after ship hook'",
9
+ )
@@ -4,7 +4,7 @@ module Ufo
4
4
  class Autoloader
5
5
  class Inflector < Zeitwerk::Inflector
6
6
  def camelize(basename, _abspath)
7
- map = { cli: "CLI", dsl: "DSL", version: "VERSION" }
7
+ map = { cli: "CLI", version: "VERSION" }
8
8
  map[basename.to_sym] || super
9
9
  end
10
10
  end
@@ -1,7 +1,7 @@
1
1
  module Ufo::Cfn::Stack::Builder::Resources::IamRoles
2
2
  class Base < Ufo::Cfn::Stack::Builder::Base
3
3
  def build
4
- return unless self.class.build? # important because it runs DSL#evaluate
4
+ return unless self.class.build? # important because it runs Dsl#evaluate
5
5
  Ufo::IamRole::Builder.new(self.class.role_type).build
6
6
  end
7
7
 
@@ -13,7 +13,7 @@ module Ufo::Cfn::Stack::Builder::Resources::IamRoles
13
13
  def build?
14
14
  path = lookup_path
15
15
  return unless path.nil? || File.exist?(path)
16
- Ufo::IamRole::DSL.new(path).evaluate # runs the role.rb and registers items
16
+ Ufo::IamRole::Dsl.new(path).evaluate # runs the role.rb and registers items
17
17
  Ufo::IamRole::Builder.new(role_type).build?
18
18
  end
19
19
 
data/lib/ufo/cfn/stack.rb CHANGED
@@ -25,6 +25,7 @@ module Ufo::Cfn
25
25
  class Stack < Base
26
26
  extend Memoist
27
27
  include Ufo::TaskDefinition::Helpers::AwsHelper
28
+ include Ufo::Hooks::Concern
28
29
 
29
30
  def deploy
30
31
  build
@@ -39,15 +40,14 @@ module Ufo::Cfn
39
40
 
40
41
  exit_with_message(@stack) if @stack && !updatable?(@stack)
41
42
 
42
- @stack ? perform(:update) : perform(:create)
43
-
44
- stop_old_tasks if @options[:stop_old_task]
45
-
46
- return unless @options[:wait]
47
- status.wait
43
+ run_hooks(name: "ship", file: "ufo.rb") do
44
+ @stack ? perform(:update) : perform(:create)
45
+ stop_old_tasks if @options[:stop_old_task]
46
+ return unless @options[:wait]
47
+ status.wait
48
+ end
48
49
 
49
50
  logger.info status.rollback_error_message if status.update_rollback?
50
-
51
51
  status.success?
52
52
  end
53
53
 
@@ -78,13 +78,17 @@ module Ufo::Cfn
78
78
  end
79
79
  end
80
80
 
81
+ # Run hooks here so both ufo docker and ufo ship runs it
82
+ # ufo docker => CLI::Build#build => Cfn::Stack#build
81
83
  def build
82
- vars = Vars.new(@options).values
83
- options_with_vars = @options.dup.merge(vars: vars)
84
- params = Params.new(options_with_vars)
85
- @parameters = params.build
86
- template = Template.new(options_with_vars)
87
- @template_body = template.body
84
+ run_hooks(name: "build", file: "ufo.rb") do
85
+ vars = Vars.new(@options).values
86
+ options_with_vars = @options.dup.merge(vars: vars)
87
+ params = Params.new(options_with_vars)
88
+ @parameters = params.build
89
+ template = Template.new(options_with_vars)
90
+ @template_body = template.body
91
+ end
88
92
  end
89
93
 
90
94
  def scheduling_strategy
data/lib/ufo/cli/build.rb CHANGED
@@ -7,11 +7,6 @@ class Ufo::CLI
7
7
  end
8
8
  alias_method :all, :build
9
9
 
10
- def for_deploy
11
- docker
12
- task_definition
13
- end
14
-
15
10
  def task_definition
16
11
  Ufo::TaskDefinition::Builder.new(@options).build
17
12
  end
@@ -1,27 +1,30 @@
1
1
  class Ufo::CLI
2
2
  class Destroy < Base
3
+ include Ufo::Hooks::Concern
4
+
3
5
  def run
4
6
  are_you_sure?
5
7
 
6
8
  stack = find_stack(@stack_name)
7
9
  unless stack
8
- puts "Stack #{@stack_name.color(:green)} does not exist."
10
+ logger.info "Stack #{@stack_name.color(:green)} does not exist."
9
11
  exit 1
10
12
  end
11
13
 
12
14
  if stack.stack_status =~ /_IN_PROGRESS$/
13
- puts "Cannot destroy service #{@service.color(:green)}"
14
- puts "Cannot delete stack #{@stack_name.color(:green)} in this state: #{stack.stack_status.color(:green)}"
15
- puts "If the stack is taking a long time, you can cancel the current operation with:"
16
- puts " ufo cancel #{@service}"
15
+ logger.info "Cannot destroy service #{@service.color(:green)}"
16
+ logger.info "Cannot delete stack #{@stack_name.color(:green)} in this state: #{stack.stack_status.color(:green)}"
17
+ logger.info "If the stack is taking a long time, you can cancel the current operation with:"
18
+ logger.info " ufo cancel #{@service}"
17
19
  return
18
20
  end
19
21
 
20
- cfn.delete_stack(stack_name: @stack_name)
21
- puts "Deleting stack #{@stack_name.color(:green)}"
22
-
23
- return unless @options[:wait]
24
- status.wait
22
+ run_hooks(name: "destroy", file: "ufo.rb") do
23
+ cfn.delete_stack(stack_name: @stack_name)
24
+ logger.info "Deleting stack #{@stack_name.color(:green)}"
25
+ return unless @options[:wait]
26
+ status.wait
27
+ end
25
28
  end
26
29
 
27
30
  def are_you_sure?
@@ -0,0 +1,7 @@
1
+ ## Examples
2
+
3
+ $ ufo new hook docker
4
+ create .ufo/config/hooks/docker.rb
5
+ $ ufo new hook ufo
6
+ create .ufo/config/hooks/ufo.rb
7
+ $
@@ -0,0 +1,18 @@
1
+ class Ufo::CLI::New
2
+ class Hook < Sequence
3
+ argument :type, default: "ufo", description: "IE: docker, ufo" # description doesnt really show up
4
+
5
+ def self.cli_options
6
+ [
7
+ [:force, aliases: ["y"], type: :boolean, desc: "Bypass overwrite are you sure prompt for existing files"],
8
+ ]
9
+ end
10
+ cli_options.each { |args| class_option(*args) }
11
+
12
+ public
13
+ def create_hook
14
+ set_template_source("hooks")
15
+ template "#{type}.rb", ".ufo/config/hooks/#{type}.rb"
16
+ end
17
+ end
18
+ end
data/lib/ufo/cli/new.rb CHANGED
@@ -1,17 +1,24 @@
1
1
  class Ufo::CLI
2
2
  class New < Ufo::Command
3
- desc "boot_hook", "Generate boot_hook file"
3
+ desc "boot_hook", "Generate boot_hook"
4
4
  long_desc Help.text("new/boot_hook")
5
5
  BootHook.cli_options.each do |args|
6
6
  option(*args)
7
7
  end
8
- register(BootHook, "boot_hook", "boot_hook", "Generate boot_hook file")
8
+ register(BootHook, "boot_hook", "boot_hook", "Generate boot_hook")
9
9
 
10
- desc "helper", "Generate helper file"
10
+ desc "helper", "Generate helper"
11
11
  long_desc Help.text("new/helper")
12
12
  Helper.cli_options.each do |args|
13
13
  option(*args)
14
14
  end
15
- register(Helper, "helper", "helper", "Generate helper file")
15
+ register(Helper, "helper", "helper", "Generate helper")
16
+
17
+ desc "hook", "Generate hook"
18
+ long_desc Help.text("new/hook")
19
+ Hook.cli_options.each do |args|
20
+ option(*args)
21
+ end
22
+ register(Hook, "hook", "hook", "Generate hook")
16
23
  end
17
24
  end
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
data/lib/ufo/config.rb CHANGED
@@ -85,6 +85,9 @@ module Ufo
85
85
  config.exec.command = "/bin/bash" # aws ecs execute-command cli
86
86
  config.exec.enabled = true # EcsService EnableExecuteCommand
87
87
 
88
+ config.hooks = ActiveSupport::OrderedOptions.new
89
+ config.hooks.show = true
90
+
88
91
  config.layering = ActiveSupport::OrderedOptions.new
89
92
  config.layering.show = parsed_layering_show
90
93
  config.layering.show_for_commands = parsed_layering_show_for
@@ -112,6 +115,7 @@ module Ufo
112
115
  config.secrets.pattern.secretsmanager = ":APP-:ENV-:SECRET_NAME" # => demo-dev-DB_PASS
113
116
  config.secrets.pattern.ssm = ":APP/:ENV/:SECRET_NAME" # => demo/dev/DB_PASS
114
117
  config.secrets.provider = "ssm" # default provider for conventional expansion IE: ssm or secretsmanager
118
+ config.secrets.warning = true
115
119
 
116
120
  config.ship = ActiveSupport::OrderedOptions.new
117
121
  config.ship.docker = ActiveSupport::OrderedOptions.new
@@ -2,6 +2,7 @@ module Ufo::Docker
2
2
  class Builder
3
3
  extend Memoist
4
4
  include Concerns
5
+ include Ufo::Hooks::Concern
5
6
 
6
7
  delegate :push, to: :pusher
7
8
  def self.build(options={})
@@ -28,7 +29,10 @@ module Ufo::Docker
28
29
  update_auth_token
29
30
  command = "docker build #{build_options}-t #{docker_image} -f #{@dockerfile} ."
30
31
  log = ".ufo/log/docker.log" if @options[:quiet]
31
- success = execute(command, log: log)
32
+ success = nil
33
+ run_hooks(name: "build", file: "docker.rb") do
34
+ success = execute(command, log: log)
35
+ end
32
36
  unless success
33
37
  docker_version_success = system("docker version > /dev/null 2>&1")
34
38
  unless docker_version_success
@@ -1,6 +1,7 @@
1
1
  module Ufo::Docker
2
2
  class Pusher
3
3
  include Concerns
4
+ include Ufo::Hooks::Concern
4
5
 
5
6
  delegate :docker_image, to: :builder
6
7
  attr_reader :last_image_name
@@ -17,7 +18,10 @@ module Ufo::Docker
17
18
  logger.info "Pushing Docker Image"
18
19
  command = "docker push #{last_image_name}"
19
20
  log = ".ufo/log/docker.log" if @options[:quiet]
20
- success = execute(command, log: log)
21
+ success = nil
22
+ run_hooks(name: "push", file: "docker.rb") do
23
+ success = execute(command, log: log)
24
+ end
21
25
  unless success
22
26
  logger.info "ERROR: The docker image fail to push.".color(:red)
23
27
  exit 1
@@ -0,0 +1,51 @@
1
+ module Ufo::Hooks
2
+ class Builder
3
+ extend Memoist
4
+ include Dsl
5
+ include DslEvaluator
6
+ include Ufo::Utils::Logging
7
+
8
+ attr_accessor :name
9
+ def initialize(options={})
10
+ @options = options
11
+ @file = options[:file] # IE: docker.rb
12
+ @dsl_file = "#{Ufo.root}/.ufo/config/hooks/#{@file}"
13
+ @name = options[:name].to_s
14
+ @hooks = {before: {}, after: {}}
15
+ end
16
+
17
+ def build
18
+ evaluate_file(@dsl_file)
19
+ @hooks.deep_stringify_keys!
20
+ end
21
+ memoize :build
22
+
23
+ def run_hooks
24
+ build
25
+ run_each_hook("before")
26
+ out = yield if block_given?
27
+ run_each_hook("after")
28
+ out
29
+ end
30
+
31
+ def run_each_hook(type)
32
+ hooks = @hooks.dig(type, @name) || []
33
+ hooks.each do |hook|
34
+ run_hook(type, hook)
35
+ end
36
+ end
37
+
38
+ def run_hook(type, hook)
39
+ return unless run?(hook)
40
+
41
+ id = "#{type} #{@name}"
42
+ label = " label: #{hook["label"]}" if hook["label"]
43
+ logger.info "Hook: Running #{id} hook#{label}".color(:cyan) if Ufo.config.hooks.show
44
+ Runner.new(hook).run
45
+ end
46
+
47
+ def run?(hook)
48
+ !!hook["execute"]
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,10 @@
1
+ module Ufo::Hooks
2
+ module Concern
3
+ # options example: {name: "build", file: "docker.rb"}
4
+ def run_hooks(options={}, &block)
5
+ hooks = Ufo::Hooks::Builder.new(options)
6
+ hooks.build # build hooks
7
+ hooks.run_hooks(&block)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,20 @@
1
+ module Ufo::Hooks
2
+ module Dsl
3
+ def before(*commands, **props)
4
+ commands.each do |name|
5
+ each_hook(:before, name, props)
6
+ end
7
+ end
8
+
9
+ def after(*commands, **props)
10
+ commands.each do |name|
11
+ each_hook(:after, name, props)
12
+ end
13
+ end
14
+
15
+ def each_hook(type, name, props={})
16
+ @hooks[type][name] ||= []
17
+ @hooks[type][name] << props
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ module Ufo::Hooks
2
+ class Runner
3
+ include Ufo::Utils::Logging
4
+ include Ufo::Utils::Execute
5
+
6
+ attr_reader :hook
7
+ def initialize(hook)
8
+ @hook = hook
9
+ @execute = @hook["execute"]
10
+ end
11
+
12
+ def run
13
+ case @execute
14
+ when String
15
+ execute(@execute, exit_on_fail: @hook["exit_on_fail"])
16
+ when -> (e) { e.respond_to?(:public_instance_methods) && e.public_instance_methods.include?(:call) }
17
+ executor = @execute.new
18
+ when -> (e) { e.respond_to?(:call) }
19
+ executor = @execute
20
+ else
21
+ logger.warn "WARN: execute option not set for hook: #{@hook.inspect}"
22
+ end
23
+
24
+ return unless executor
25
+
26
+ meth = executor.method(:call)
27
+ case meth.arity
28
+ when 0
29
+ executor.call # backwards compatibility
30
+ when 1
31
+ executor.call(self)
32
+ else
33
+ raise "The #{executor} call method definition has been more than 1 arguments and is not supported"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,5 +1,5 @@
1
1
  module Ufo::IamRole
2
- class DSL
2
+ class Dsl
3
3
  include DslEvaluator
4
4
  include Ufo::TaskDefinition::Helpers::AwsHelper
5
5
 
@@ -11,13 +11,13 @@ module Ufo::IamRole
11
11
  def register_policy(role_type, policy_name, *statements)
12
12
  statements.flatten!
13
13
  self.policies[role_type] ||= Set.new
14
- self.policies[role_type].add([policy_name, statements]) # using set so DSL can safely be evaluated multiple times
14
+ self.policies[role_type].add([policy_name, statements]) # using set so Dsl can safely be evaluated multiple times
15
15
  end
16
16
 
17
17
  def register_managed_policy(role_type, *policies)
18
18
  policies.flatten!
19
19
  self.managed_policies[role_type] ||= Set.new
20
- self.managed_policies[role_type].merge(policies) # using set so DSL can safely be evaluated multiple times
20
+ self.managed_policies[role_type].merge(policies) # using set so Dsl can safely be evaluated multiple times
21
21
  end
22
22
  end
23
23
  end
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,18 +68,15 @@ 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']
77
75
  logger.info " #{pretty_path(path)}"
78
- elsif Ufo.config.show_layers?
76
+ elsif Ufo.config.layering.show
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
data/lib/ufo/param.rb CHANGED
@@ -18,8 +18,7 @@ module Ufo
18
18
  memoize :data
19
19
 
20
20
  def template_scope
21
- self # TODO: add access to helpers like network
22
- # @template_scope ||= Ufo::TemplateScope.new(Ufo::DSL::Helper.new, nil)
21
+ self
23
22
  end
24
23
  end
25
24
  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.3"
2
+ VERSION = "6.3.0"
3
3
  end
@@ -12,7 +12,7 @@ describe Ufo::IamRole::Builder do
12
12
  {:Action=>["cloudwatch:PutMetricData"], :Effect=>"Allow", :Resource=>"*"}
13
13
  )
14
14
  # Called twice on purpose to show that duplicated items in the set wont create doubles.
15
- # This allows the DSL evaluate to be ran multiple times.
15
+ # This allows the Dsl evaluate to be ran multiple times.
16
16
  Ufo::IamRole::Registry.register_policy("task_role",
17
17
  "CloudwatchWrite",
18
18
  {:Action=>["cloudwatch:PutMetricData"], :Effect=>"Allow", :Resource=>"*"}
@@ -1,9 +1,9 @@
1
- describe Ufo::IamRole::DSL do
1
+ describe Ufo::IamRole::Dsl do
2
2
  let(:dsl) { described_class.new(path) }
3
3
  let(:path) { "spec/fixtures/iam_roles/task_role.rb" }
4
4
 
5
5
  context "evaluate" do
6
- it "registers policies from role DSL" do
6
+ it "registers policies from role Dsl" do
7
7
  dsl.evaluate
8
8
  expect(Ufo::IamRole::Registry.policies).not_to be_empty
9
9
  expect(Ufo::IamRole::Registry.managed_policies).not_to be_empty
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.3
4
+ version: 6.3.0
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-25 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"
@@ -479,6 +480,8 @@ files:
479
480
  - lib/templates/boot_hook/.ufo/config/boot.rb
480
481
  - lib/templates/docker/Dockerfile
481
482
  - lib/templates/helper/%underscore_name%_helper.rb.tt
483
+ - lib/templates/hooks/docker.rb
484
+ - lib/templates/hooks/ufo.rb
482
485
  - lib/templates/init/.ufo/config.rb.tt
483
486
  - lib/templates/init/.ufo/config/web/base.rb
484
487
  - lib/templates/init/.ufo/config/web/dev.rb
@@ -558,6 +561,7 @@ files:
558
561
  - lib/ufo/cli/help/init.md
559
562
  - lib/ufo/cli/help/logs.md
560
563
  - lib/ufo/cli/help/new/boot_hook.md
564
+ - lib/ufo/cli/help/new/hook.md
561
565
  - lib/ufo/cli/help/ps.md
562
566
  - lib/ufo/cli/help/releases.md
563
567
  - lib/ufo/cli/help/rollback.md
@@ -569,6 +573,7 @@ files:
569
573
  - lib/ufo/cli/new/boot_hook.rb
570
574
  - lib/ufo/cli/new/concerns.rb
571
575
  - lib/ufo/cli/new/helper.rb
576
+ - lib/ufo/cli/new/hook.rb
572
577
  - lib/ufo/cli/new/init.rb
573
578
  - lib/ufo/cli/new/sequence.rb
574
579
  - lib/ufo/cli/opts.rb
@@ -613,6 +618,10 @@ files:
613
618
  - lib/ufo/ext.rb
614
619
  - lib/ufo/ext/core/module.rb
615
620
  - lib/ufo/ext/core/nil_class.rb
621
+ - lib/ufo/hooks/builder.rb
622
+ - lib/ufo/hooks/concern.rb
623
+ - lib/ufo/hooks/dsl.rb
624
+ - lib/ufo/hooks/runner.rb
616
625
  - lib/ufo/iam_role/builder.rb
617
626
  - lib/ufo/iam_role/dsl.rb
618
627
  - lib/ufo/iam_role/registry.rb