lono 7.3.2 → 7.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/lib/lono.rb +1 -0
  4. data/lib/lono/app_file/build.rb +22 -34
  5. data/lib/lono/app_file/build/lambda_layer/ruby_packager.rb +2 -33
  6. data/lib/lono/app_file/registry/item.rb +18 -45
  7. data/lib/lono/app_file/upload.rb +1 -25
  8. data/lib/lono/cfn/base.rb +8 -2
  9. data/lib/lono/cfn/create.rb +3 -2
  10. data/lib/lono/cfn/opts.rb +8 -0
  11. data/lib/lono/cfn/preview/changeset.rb +1 -0
  12. data/lib/lono/cfn/update.rb +1 -0
  13. data/lib/lono/configset.rb +1 -1
  14. data/lib/lono/configset/combiner.rb +40 -13
  15. data/lib/lono/configset/generator.rb +6 -1
  16. data/lib/lono/configset/list.rb +1 -1
  17. data/lib/lono/configset/register/dsl.rb +3 -3
  18. data/lib/lono/configset/resolver.rb +9 -5
  19. data/lib/lono/configset/s3_file/build.rb +33 -0
  20. data/lib/lono/configset/s3_file/item.rb +30 -0
  21. data/lib/lono/configset/s3_file/registry.rb +12 -0
  22. data/lib/lono/configset/s3_file/upload.rb +12 -0
  23. data/lib/lono/configset/strategy/base.rb +21 -1
  24. data/lib/lono/configset/strategy/dsl.rb +9 -6
  25. data/lib/lono/configset/strategy/erb.rb +6 -1
  26. data/lib/lono/configset/strategy/helpers/dsl.rb +8 -0
  27. data/lib/lono/configset/strategy/helpers/dsl/auth.rb +37 -0
  28. data/lib/lono/configset/strategy/{dsl/helpers → helpers/dsl}/core.rb +6 -1
  29. data/lib/lono/configset/strategy/helpers/dsl/package.rb +40 -0
  30. data/lib/lono/configset/strategy/helpers/dsl/syntax.rb +74 -0
  31. data/lib/lono/configset/strategy/{erb/helpers.rb → helpers/erb.rb} +2 -2
  32. data/lib/lono/extension/list.rb +2 -1
  33. data/lib/lono/extensions/loader.rb +2 -1
  34. data/lib/lono/file_uploader.rb +3 -109
  35. data/lib/lono/finder/base.rb +1 -1
  36. data/lib/lono/finder/blueprint/configset.rb +3 -3
  37. data/lib/lono/generate.rb +11 -1
  38. data/lib/lono/jade/registry.rb +10 -1
  39. data/lib/lono/jadespec.rb +4 -2
  40. data/lib/lono/registration/temp.rb +4 -2
  41. data/lib/lono/s3/uploader.rb +94 -0
  42. data/lib/lono/seed/base.rb +2 -1
  43. data/lib/lono/template/configset_injector.rb +6 -4
  44. data/lib/lono/template/generator.rb +1 -9
  45. data/lib/lono/template/helper.rb +2 -3
  46. data/lib/lono/template/post_processor.rb +9 -1
  47. data/lib/lono/template/strategy/dsl/builder/helpers.rb +1 -0
  48. data/lib/lono/template/strategy/dsl/builder/helpers/ec2_helper.rb +27 -0
  49. data/lib/lono/template/strategy/dsl/builder/helpers/s3_helper.rb +1 -0
  50. data/lib/lono/template/upload.rb +4 -98
  51. data/lib/lono/utils/item/file_methods.rb +29 -0
  52. data/lib/lono/utils/item/zip.rb +42 -0
  53. data/lib/lono/utils/rsync.rb +36 -0
  54. data/lib/lono/version.rb +1 -1
  55. data/lib/templates/blueprint/.gitignore +4 -7
  56. data/lib/templates/configset/%configset_name%.gemspec.tt +1 -1
  57. data/lib/templates/configset/.gitignore +2 -4
  58. data/lib/templates/extension/%extension_name%.gemspec.tt +2 -1
  59. data/lib/templates/extension/.gitignore +11 -17
  60. data/lib/templates/extension/lib/%extension_name%.rb.tt +3 -0
  61. data/lib/templates/extension/lib/%extension_name%/autoloader.rb.tt +23 -0
  62. data/lono.gemspec +1 -0
  63. metadata +32 -6
  64. data/lib/lono/configset/strategy/dsl/helpers.rb +0 -5
  65. data/lib/lono/configset/strategy/dsl/syntax.rb +0 -32
@@ -26,7 +26,12 @@ class Lono::Configset
26
26
  # Dsl.new(options).build
27
27
  generator_class = "Lono::Configset::Strategy::#{strategy.camelize}"
28
28
  generator_class = Object.const_get(generator_class)
29
- generator_class.new(@options.merge(root: configset_root)).build
29
+ full = generator_class.new(@options.merge(root: configset_root)).build
30
+ if @options[:cli]
31
+ full["Metadata"] # contains AWS::CloudFormation::Init and optional AWS::CloudFormation::Authentication
32
+ else
33
+ full # Combiner uses full metadata structure
34
+ end
30
35
  end
31
36
 
32
37
  def strategy
@@ -41,7 +41,7 @@ class Lono::Configset
41
41
  table = Text::Table.new
42
42
  table.head = ["Name", "Path", "Type", "From"]
43
43
  @final.each do |spec|
44
- pretty_root = spec.root.sub("#{Lono.root}/",'')
44
+ pretty_root = spec.root.sub("#{Lono.root}/",'').sub(ENV["HOME"], "~")
45
45
  table.rows << [spec.name, pretty_root, spec.source_type, spec.from]
46
46
  end
47
47
 
@@ -7,8 +7,8 @@ module Lono::Configset::Register
7
7
  end
8
8
 
9
9
  # DSL
10
- def source(v)
11
- self.class.source = v
12
- end
10
+ # def source(v)
11
+ # self.class.source = v
12
+ # end
13
13
  end
14
14
  end
@@ -32,11 +32,15 @@ class Lono::Configset
32
32
  # jade like jade.resource_from_parent.
33
33
  registry = jade.registry
34
34
  registry.resource = jade.resource_from_parent
35
- if jade.type == "blueprint/configset"
36
- Register::Blueprint.prepend(registry)
37
- elsif jade.type == "configset"
38
- Register::Project.prepend(registry)
39
- end
35
+
36
+ # Always prepend to Register::Blueprint.configsets to ensure they are run before any other configset.
37
+ # Leaving old code in place for now. Possibly revisit this approach.
38
+ Register::Blueprint.prepend(registry)
39
+ # if jade.type == "blueprint/configset"
40
+ # Register::Blueprint.prepend(registry)
41
+ # elsif jade.type == "configset"
42
+ # Register::Project.prepend(registry)
43
+ # end
40
44
  end
41
45
  end
42
46
  end
@@ -0,0 +1,33 @@
1
+ module Lono::Configset::S3File
2
+ class Build < Lono::AbstractBase
3
+ include Lono::Utils::Rsync
4
+ include Lono::Utils::Item::Zip
5
+
6
+ def run
7
+ Lono::Configset::S3File::Registry.items.each do |item|
8
+ build(item)
9
+ end
10
+ end
11
+
12
+ def build(item)
13
+ copy_to_output(item)
14
+ compress_output
15
+ end
16
+
17
+ def copy_to_output(item)
18
+ src = "#{item.root}/lib/files/#{item.name}"
19
+ dest = "#{Lono.config.output_path}/#{@blueprint}/configsets/#{item.configset}/files/#{item.name}"
20
+ rsync(src, dest)
21
+ end
22
+
23
+ def compress_output
24
+ Registry.items.each do |item|
25
+ if item.exist?
26
+ zip(item)
27
+ else
28
+ puts "WARN: #{item.src_path} does not exist. Double check that the path is correct in the s3_key call.".color(:yellow)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ module Lono::Configset::S3File
2
+ # Holds metadata about the item in the regsitry.
3
+ class Item
4
+ include Lono::Utils::Item::FileMethods
5
+
6
+ attr_reader :name, :configset, :root
7
+ def initialize(name, options={})
8
+ @name, @options = name, options
9
+ @blueprint = options[:blueprint]
10
+ @configset = options[:configset]
11
+ @root = options[:root]
12
+ @type = options[:type] || 'file'
13
+ end
14
+
15
+ def src_path
16
+ "#{@root}/lib/files"
17
+ end
18
+
19
+ def output_path
20
+ "#{Lono.config.output_path}/#{@blueprint}/configsets/#{@configset}/files/#{@name}"
21
+ end
22
+
23
+ def replacement_value
24
+ aws_data = AwsData.new
25
+ # "https://s3.amazonaws.com/#{Lono::S3::Bucket.name}/#{s3_path}"
26
+ # "https://lono-bucket-12di8xz5sy72z.s3-us-west-2.amazonaws.com/stuff/s3-antivirus.tgz"
27
+ "https://#{Lono::S3::Bucket.name}.s3-#{aws_data.region}.amazonaws.com/#{s3_path}"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,12 @@
1
+ module Lono::Configset::S3File
2
+ class Registry
3
+ cattr_reader :items
4
+ @@items = []
5
+
6
+ class << self
7
+ def register(name, options)
8
+ @@items << Item.new(name, options) unless @@items.detect { |i| i.name == name }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Lono::Configset::S3File
2
+ class Upload < Lono::AbstractBase
3
+ def upload
4
+ return unless Registry.items.size > 0
5
+ puts "Uploading configset files..."
6
+
7
+ Registry.items.each do |item|
8
+ Lono::S3::Uploader.new(item.zip_file_path).upload
9
+ end
10
+ end
11
+ end
12
+ end
@@ -13,6 +13,18 @@ module Lono::Configset::Strategy
13
13
  extend Memoist
14
14
  include Lono::Configset::EvaluateFile
15
15
 
16
+ # All Lono DSL Helpers and Fn - so configsets have access to instrinic functions like ref
17
+ # Not including the Lono::Template::Strategy::Dsl::Builder::Syntax since dont need those methods
18
+ #
19
+ # Interesting note: must include these modules here so load_project_predefined_variables works.
20
+ # Since load_project_predefined_variables calls evaluate_file / instance eval which seems to only be
21
+ # able to access methods from the direct class, not inherited classes like Dsl.
22
+ #
23
+ # This allows methods like ref and sub to work in variables files.
24
+ #
25
+ include Lono::Template::Strategy::Dsl::Builder::Helpers
26
+ include Lono::Template::Strategy::Dsl::Builder::Fn
27
+
16
28
  def initialize(options={})
17
29
  @options = options
18
30
  @configset = options[:configset]
@@ -25,10 +37,18 @@ module Lono::Configset::Strategy
25
37
  @evaluation_path = find_evaluation_path # implemented by subclass
26
38
  copy_instance_variables
27
39
  load_configset_helpers
28
- load # implemented by subclass
40
+ init = load # implemented by subclass
41
+ finish_full_structure(init)
29
42
  end
30
43
  memoize :build
31
44
 
45
+ def finish_full_structure(init)
46
+ full = {"Metadata" => {}}
47
+ full["Metadata"]["AWS::CloudFormation::Init"] = init["AWS::CloudFormation::Init"]
48
+ full["Metadata"]["AWS::CloudFormation::Authentication"] = authentication if authentication # only on dsl
49
+ full.deep_stringify_keys!
50
+ end
51
+
32
52
  def copy_instance_variables
33
53
  load_blueprint_predefined_variables
34
54
  load_project_predefined_variables
@@ -1,13 +1,16 @@
1
1
  module Lono::Configset::Strategy
2
2
  class Dsl < Base
3
- include Helpers
4
- include Syntax
3
+ # Configset helpers take higher precedence than Lono DSL Helpers. IE: s3_key is overwritten but s3_bucket is the same
4
+ include Helpers::Dsl
5
5
 
6
6
  def initialize(options={})
7
7
  super
8
- @structure = {} # holds in memory the configset hash structure
8
+ @structure = {} # holds in memory the configset hash structure to build AWS::CloudFormation::Init
9
9
  @current = "main" # current configset
10
+ @command_counts = Hash.new(0)
10
11
  @tracked = []
12
+ # Also support ability to add AWS::CloudFormation::Authentication
13
+ @authentication = nil # holds IAM policy info to build AWS::CloudFormation::Authentication
11
14
  end
12
15
 
13
16
  def find_evaluation_path
@@ -18,9 +21,9 @@ module Lono::Configset::Strategy
18
21
  evaluate_file(@evaluation_path)
19
22
  configsets = @configsets || @tracked.uniq
20
23
  configsets = ["main"] if configsets.empty?
21
- init = {"configSets" => {"default" => configsets}}.merge(@structure)
22
- full_structure = { "AWS::CloudFormation::Init" => init }
23
- full_structure.deep_stringify_keys!
24
+ configsets_structure = {"configSets" => {"default" => configsets}}.merge(@structure)
25
+ full = { "AWS::CloudFormation::Init" => configsets_structure }
26
+ full.deep_stringify_keys!
24
27
  end
25
28
  end
26
29
  end
@@ -2,7 +2,7 @@ require "json"
2
2
 
3
3
  module Lono::Configset::Strategy
4
4
  class Erb < Base
5
- include Helpers
5
+ include Helpers::Erb
6
6
 
7
7
  def find_evaluation_path
8
8
  paths = %w[configset.yml configset.json].map { |p| "#{@root}/lib/#{p}" }
@@ -11,6 +11,7 @@ module Lono::Configset::Strategy
11
11
 
12
12
  def load
13
13
  content = RenderMePretty.result(@evaluation_path, context: self)
14
+ # init structure
14
15
  if File.extname(@evaluation_path) == ".yml"
15
16
  load_yaml(content)
16
17
  else
@@ -18,6 +19,10 @@ module Lono::Configset::Strategy
18
19
  end
19
20
  end
20
21
 
22
+ def authentication
23
+ # noop
24
+ end
25
+
21
26
  def load_yaml(content)
22
27
  # Write to file so can use Yamler::Validator
23
28
  path = "/tmp/lono/configset.yml"
@@ -0,0 +1,8 @@
1
+ module Lono::Configset::Strategy::Helpers
2
+ module Dsl
3
+ include Auth
4
+ include Core
5
+ include Package
6
+ include Syntax
7
+ end
8
+ end
@@ -0,0 +1,37 @@
1
+ module Lono::Configset::Strategy::Helpers::Dsl
2
+ module Auth
3
+ def authentication(data=nil, force: false)
4
+ if data.nil?
5
+ authentication_reader
6
+ else
7
+ authentication_setter(data, force)
8
+ end
9
+ end
10
+
11
+ # data can be either:
12
+ #
13
+ # 1. logical id - String
14
+ # 2. Full AWS::CloudFormation::Authentication value structure
15
+ #
16
+ def authentication_reader
17
+ # AWS::CloudFormation::Authentication
18
+ case @authentication
19
+ when String
20
+ logical_id = @authentication
21
+ {
22
+ rolebased: {
23
+ type: "S3",
24
+ buckets: [lono_bucket_name],
25
+ roleName: {Ref: logical_id}, # currently ref meth is not available
26
+ }
27
+ }
28
+ when Hash
29
+ @authentication
30
+ end
31
+ end
32
+
33
+ def authentication_setter(data, force=false)
34
+ @authentication = data unless @authentication || force
35
+ end
36
+ end
37
+ end
@@ -1,4 +1,4 @@
1
- module Lono::Configset::Strategy::Dsl::Helpers
1
+ module Lono::Configset::Strategy::Helpers::Dsl
2
2
  module Core
3
3
  def content_file(path)
4
4
  content_path = "#{@root}/lib/content"
@@ -9,5 +9,10 @@ module Lono::Configset::Strategy::Dsl::Helpers
9
9
  "File not found: #{file}"
10
10
  end
11
11
  end
12
+
13
+ def s3_key(name)
14
+ Lono::Configset::S3File::Registry.register(name, blueprint: @blueprint, configset: @configset, root: @root)
15
+ "file://configset/#{@configset}/#{name}"
16
+ end
12
17
  end
13
18
  end
@@ -0,0 +1,40 @@
1
+ module Lono::Configset::Strategy::Helpers::Dsl
2
+ module Package
3
+ # In recent versions of the AmazonLinux2 cfnbootstrap, , the package command doesnt work with updated versions of rubygems.
4
+ # Get this error
5
+ #
6
+ # invalid option: --no-ri
7
+ #
8
+ # More details: https://gist.github.com/tongueroo/569878afdc7eb904490b9ee8b03f304f
9
+ #
10
+ # Found the cfnbootstrap version by looking at the source on 2020-03-21 in
11
+ #
12
+ # $ cat /usr/lib/python2.7/site-packages/cfnbootstrap/public_constants.py
13
+ # _release = '31'
14
+ # _version = '1.4-' + _release
15
+ #
16
+ # There is no way to get the version from the /opt/aws/bin/cfn-init command.
17
+ #
18
+ # We work around this be using the command instruction and use the gem install and list commands.
19
+ #
20
+ # $ gem list tilt -e -i -v 1.4.0
21
+ # false # also $? is 1
22
+ # $ gem list tilt -e -i -v 1.4.1
23
+ # true # also $? is 0
24
+ # $
25
+ #
26
+ def gem_package(name, version=nil)
27
+ unless_clause = "gem list #{name} -e -i "
28
+ unless_clause += "-v #{version}" if version
29
+ command("#{name}-gem-install",
30
+ command: "gem install #{name} #{version}",
31
+ unless: unless_clause
32
+ )
33
+ end
34
+
35
+ def yum_package(name, version=nil)
36
+ versions = [version].compact
37
+ package("yum", name => versions)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,74 @@
1
+ module Lono::Configset::Strategy::Helpers::Dsl
2
+ module Syntax
3
+ extend Memoist
4
+
5
+ %w[package group user file service].each do |meth|
6
+ section = meth.pluralize
7
+ define_method(meth) do |k, props={}|
8
+ init_empty(@current, section)
9
+ current_structure(@current)[section].deep_merge!(k => props)
10
+ end
11
+ end
12
+
13
+ # Add extra conveniences to command method
14
+ def command(key, props={})
15
+ init_empty(@current, "commands")
16
+
17
+ # order commands automatically
18
+ if key !~ /^\d+_/
19
+ c = @command_counts[@current] += 1 # IE: @command_counts["main"]
20
+ padded_c = "%03d" % c
21
+ key = "#{padded_c}_#{key}"
22
+ end
23
+
24
+ # if syntax support
25
+ if props.key?(:if)
26
+ if_clause = props.delete(:if)
27
+ props[:test] = "if #{if_clause} ; then true ; else false ; fi"
28
+ # returns true - will run command
29
+ # returns false - will not run command
30
+ end
31
+
32
+ # unless syntax support
33
+ if props.key?(:unless)
34
+ unless_clause = props.delete(:unless)
35
+ props[:test] = "if #{unless_clause} ; then false ; else true ; fi"
36
+ # returns true - will run command
37
+ # returns false - will not run command
38
+ end
39
+
40
+ current_structure(@current)["commands"].deep_merge!(key => props)
41
+ end
42
+
43
+ # Source has a different signature than the other native methods
44
+ def source(*args)
45
+ if args.first.is_a?(Hash)
46
+ item = args.first
47
+ else # 2 args form: first element is k, second is
48
+ k, v, _ = args
49
+ item = {k => v}
50
+ end
51
+
52
+ init_empty(@current, "sources")
53
+ current_structure(@current)["sources"].deep_merge!(item)
54
+ end
55
+
56
+ def configset(current)
57
+ @tracked << current
58
+ previous, @current = @current, current
59
+ yield
60
+ @current = previous
61
+ end
62
+
63
+ private
64
+ def current_structure(configset)
65
+ @structure[configset] ||= {}
66
+ end
67
+ memoize :current_structure
68
+
69
+ def init_empty(configset, section)
70
+ current = current_structure(configset)
71
+ current[section] ||= {}
72
+ end
73
+ end
74
+ end
@@ -1,5 +1,5 @@
1
- class Lono::Configset::Strategy::Erb
2
- module Helpers
1
+ module Lono::Configset::Strategy::Helpers
2
+ module Erb
3
3
  def indent(text, indentation_amount)
4
4
  text.split("\n").map do |line|
5
5
  " " * indentation_amount + line
@@ -26,7 +26,8 @@ class Lono::Extension
26
26
  presenter.header = %w[Name Path Type]
27
27
  jadespecs.each do |j|
28
28
  if tracked_extension_names.include?(j.name)
29
- presenter.rows << [j.name, j.root, j.source_type]
29
+ pretty_path = j.root.sub("#{Lono.root}/",'').sub(ENV["HOME"], "~")
30
+ presenter.rows << [j.name, pretty_path, j.source_type]
30
31
  end
31
32
  end
32
33
  presenter.show