lono 7.3.2 → 7.4.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 (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