lono 5.1.1 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/lono/seed.rb CHANGED
@@ -1,37 +1,48 @@
1
- require "fileutils"
2
-
3
1
  module Lono
4
2
  class Seed
5
- include Blueprint::Root
3
+ include Lono::Blueprint::Root
4
+ include Lono::Conventions
6
5
 
7
- def initialize(blueprint, options)
6
+ def initialize(blueprint, options={})
8
7
  @blueprint, @options = blueprint, options
9
- @args = options[:args] # hash
8
+ set_blueprint_root(@blueprint)
9
+ @template, @param = template_param_convention(options)
10
10
  end
11
11
 
12
- def run
13
- blueprint_root = find_blueprint_root(@blueprint)
14
- unless blueprint_root
15
- puts "ERROR: Did not find blueprint: #{@blueprint}".color(:red)
16
- puts "Are you sure you specified the right blueprint?"
17
- Blueprint::List.available
18
- exit 1
19
- end
12
+ def create
13
+ puts "Creating starter config files for #{@blueprint}"
14
+ configs_class = load_configs_class # ::Configs or Lono::Seed::Base
15
+ configs = configs_class.new(@blueprint, @options)
16
+ # The Configs class implements: variables
17
+ configs.run # setup the instance variables
18
+ end
20
19
 
20
+ private
21
+ def load_configs_class
22
+ blueprint_root = find_blueprint_root(@blueprint)
21
23
  configs_path = "#{blueprint_root}/seed/configs.rb"
22
- unless File.exist?(configs_path)
23
- puts "No #{configs_path} file found. Nothing to configure."
24
- exit
24
+
25
+ begin
26
+ loaded = load configs_path
27
+ rescue LoadError
28
+ loaded = false
25
29
  end
26
30
 
27
- require configs_path
28
- unless defined?(Configs)
29
- puts "Configs class not found.\nAre you sure #{configs_path} contains a Configs class?"
30
- exit 1
31
+ if loaded
32
+ if defined?(Lono::Seed::Configs)
33
+ configs_class = Lono::Seed::Configs # blueprint specific Configs
34
+ else
35
+ puts <<~EOL
36
+ Lono::Seed::Configs class not found.
37
+ Are you sure #{configs_path} contains a Lono::Seed::Configs class?
38
+ EOL
39
+ exit 1
40
+ end
41
+ else
42
+ configs_class = Lono::Seed::Base # Generic handling
31
43
  end
32
- configs = Configs.new(@blueprint, @options)
33
- # The Configs class implements: seed, params, and variables
34
- configs.run # setup the instance variables
44
+
45
+ configs_class
35
46
  end
36
47
  end
37
- end
48
+ end
@@ -28,19 +28,27 @@ class Lono::Template::Dsl::Builder
28
28
  }
29
29
  end
30
30
 
31
+ def content(path)
32
+ render_file(Lono.config.content_path, path)
33
+ end
34
+
31
35
  def user_data(path)
32
- path = "#{Lono.config.user_data_path}/#{path}"
36
+ render_file(Lono.config.user_data_path, path)
37
+ end
38
+
39
+ def render_file(folder, path)
40
+ path = "#{folder}/#{path}"
33
41
  if File.exist?(path)
34
42
  render_path(path)
35
43
  else
36
- message = "WARNING: user-data path #{path} not found"
44
+ message = "WARNING: path #{path} not found"
37
45
  puts message.color(:yellow)
38
46
  puts "Called from:"
39
- puts caller[1]
47
+ puts caller[2]
40
48
  message
41
49
  end
42
50
  end
43
- memoize :user_data
51
+ memoize :render_file
44
52
 
45
53
  def render_path(path)
46
54
  RenderMePretty.result(path, context: self)
@@ -7,6 +7,7 @@ class Lono::Template::Dsl
7
7
  include Helper # built-in helpers
8
8
  include Lono::Template::Evaluate
9
9
  include Syntax
10
+ extend Memoist
10
11
 
11
12
  def initialize(path, blueprint, options={})
12
13
  @path, @blueprint, @options = path, blueprint, options
@@ -16,11 +17,20 @@ class Lono::Template::Dsl
16
17
 
17
18
  def build
18
19
  load_context
19
- evaluate_template_path(@path)
20
+ evaluate_template_path(@path) # modifies @cfn
20
21
  build_template
21
22
  write_output
23
+ template
22
24
  end
23
25
 
26
+ # Useful for lono seed to get the template in memory
27
+ def template
28
+ load_context
29
+ evaluate_template_path(@path) # modifies @cfn
30
+ camelize(@cfn)
31
+ end
32
+ memoize :template
33
+
24
34
  def build_template
25
35
  @results = YAML.dump(camelize(@cfn))
26
36
  end
data/lib/lono/template.rb CHANGED
@@ -1,8 +1,5 @@
1
- require "thor"
2
- require_relative "command"
3
-
4
1
  module Lono
5
- class Template < Lono::Command
2
+ class Template < Command
6
3
  class_option :quiet, type: :boolean, desc: "silence the output"
7
4
  class_option :noop, type: :boolean, desc: "noop mode, do nothing destructive"
8
5
 
data/lib/lono/upgrade.rb CHANGED
@@ -1,18 +1,18 @@
1
- require "thor"
1
+ module Lono
2
+ class Upgrade < Command
3
+ desc "v3to4", "Upgrade from version 3 to 4."
4
+ def v3to4
5
+ Upgrade4.new(options).run
6
+ end
2
7
 
3
- class Lono::Upgrade < Lono::Command
4
- desc "v3to4", "Upgrade from version 3 to 4."
5
- def v3to4
6
- Upgrade4.new(options).run
7
- end
8
-
9
- desc "v4to4_2", "Upgrade from version 4.0 to 4.2"
10
- def v4to4_2
11
- Upgrade42.start
12
- end
8
+ desc "v4to4_2", "Upgrade from version 4.0 to 4.2"
9
+ def v4to4_2
10
+ Upgrade42.start
11
+ end
13
12
 
14
- desc "v4to5", "Upgrade from version 4.2 to 5.0"
15
- def v4to5
16
- Upgrade5.start
13
+ desc "v4to5", "Upgrade from version 4.2 to 5.0"
14
+ def v4to5
15
+ Upgrade5.start
16
+ end
17
17
  end
18
18
  end
data/lib/lono/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Lono
2
- VERSION = "5.1.1"
2
+ VERSION = "5.2.0"
3
3
  end
@@ -1,54 +1,28 @@
1
- # This class is used by `lono seed [blueprint]` to create starter config files.
1
+ # This is an optional class is used by `lono seed [blueprint]` to create starter configs.
2
2
  # Example files that get created:
3
3
  #
4
- # Variables:
4
+ # configs/BLUEPRINT/params/LONO_ENV.txt
5
+ # configs/BLUEPRINT/variables/LONO_ENV.rb
5
6
  #
6
- # configs/[blueprint]/variables/[Lono.env].rb
7
+ # The `Lono::Seed::Configs` class should implement:
7
8
  #
8
- # Params:
9
- #
10
- # configs/[blueprint]/params/[Lono.env].txt - short form
11
- # configs/[blueprint]/params/[Lono.env]/[param].txt - medium form
12
- # configs/[blueprint]/params/[Lono.env]/[template]/[param].txt - large form
13
- #
14
- # Subclasses of `Lono::Configure::Base` should implement:
15
- #
16
- # setup: Hook to perform logic at the beginning. Examples:
17
- # * Setting instance variables used in the params or variables template methods.
18
- # * Creating pre-defined IAM roles required by the template.
19
- # params: Template for generated params file. Contents of what gets created at
20
- # configs/[blueprint]/params/development/[param].txt
9
+ # setup: Hook to perform logic at the beginning. A good place to create IAM service roles.
21
10
  # variables: Template for generated variables file. Contents of what gets created at
22
11
  # configs/[blueprint]/variables/development.rb
23
12
  #
24
- class Configs < Lono::Configure::Base
13
+ # Note: There is no need to define a params method. Lono is able to generate a params config starter file by evaluating the template defintion.
14
+ #
15
+ class Lono::Seed::Configs < Lono::Seed::Base
25
16
  # Setup hook
26
- def setup
27
- # Custom setup logic
28
- # set_instance_variables
29
- end
30
-
31
- # Template for params
32
- def params
33
- <<~EOL
34
- Parameter1=StarterValue1
35
- Parameter2=StarterValue1
36
- # Optional
37
- # Parameter3=OptionalStarterValue1
38
- EOL
39
- end
17
+ # def setup
18
+ # end
40
19
 
41
- # Template for variables
20
+ # Template for variables.
21
+ # Return String with the content of the config/BLUEPRINT/variables file.
42
22
  # def variables
43
23
  # <<~EOL
44
24
  # @variable1=starter_value1
45
25
  # @variable2=starter_value2
46
26
  # EOL
47
27
  # end
48
-
49
- private
50
- # Example:
51
- # def set_instance_variables
52
- # @instance_type = "t3.micro"
53
- # end
54
28
  end
data/lono.gemspec CHANGED
@@ -47,6 +47,7 @@ Gem::Specification.new do |gem|
47
47
  gem.add_development_dependency "cli_markdown"
48
48
  gem.add_development_dependency "guard-bundler"
49
49
  gem.add_development_dependency "guard-rspec"
50
+ gem.add_development_dependency "lono-pro"
50
51
  gem.add_development_dependency "rake"
51
52
  gem.add_development_dependency "rspec"
52
53
  end
@@ -45,7 +45,7 @@ module Cfn
45
45
  end
46
46
 
47
47
  def rollback_complete?(stack)
48
- stack.stack_status == 'ROLLBACK_COMPLETE'
48
+ stack&.stack_status == 'ROLLBACK_COMPLETE'
49
49
  end
50
50
  end
51
51
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lono
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.1
4
+ version: 5.2.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: 2019-10-09 00:00:00.000000000 Z
11
+ date: 2019-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -360,6 +360,20 @@ dependencies:
360
360
  - - ">="
361
361
  - !ruby/object:Gem::Version
362
362
  version: '0'
363
+ - !ruby/object:Gem::Dependency
364
+ name: lono-pro
365
+ requirement: !ruby/object:Gem::Requirement
366
+ requirements:
367
+ - - ">="
368
+ - !ruby/object:Gem::Version
369
+ version: '0'
370
+ type: :development
371
+ prerelease: false
372
+ version_requirements: !ruby/object:Gem::Requirement
373
+ requirements:
374
+ - - ">="
375
+ - !ruby/object:Gem::Version
376
+ version: '0'
363
377
  - !ruby/object:Gem::Dependency
364
378
  name: rake
365
379
  requirement: !ruby/object:Gem::Requirement
@@ -433,8 +447,8 @@ files:
433
447
  - lib/lono/blueprint/new.rb
434
448
  - lib/lono/blueprint/root.rb
435
449
  - lib/lono/cfn.rb
436
- - lib/lono/cfn/aws_service.rb
437
450
  - lib/lono/cfn/base.rb
451
+ - lib/lono/cfn/cancel.rb
438
452
  - lib/lono/cfn/create.rb
439
453
  - lib/lono/cfn/current.rb
440
454
  - lib/lono/cfn/delete.rb
@@ -454,9 +468,6 @@ files:
454
468
  - lib/lono/completer/script.rb
455
469
  - lib/lono/completer/script.sh
456
470
  - lib/lono/completion.rb
457
- - lib/lono/configure/aws_services.rb
458
- - lib/lono/configure/base.rb
459
- - lib/lono/configure/helpers.rb
460
471
  - lib/lono/conventions.rb
461
472
  - lib/lono/core.rb
462
473
  - lib/lono/core/config.rb
@@ -465,6 +476,7 @@ files:
465
476
  - lib/lono/help.rb
466
477
  - lib/lono/help/blueprint.md
467
478
  - lib/lono/help/cfn.md
479
+ - lib/lono/help/cfn/cancel.md
468
480
  - lib/lono/help/cfn/create.md
469
481
  - lib/lono/help/cfn/current.md
470
482
  - lib/lono/help/cfn/delete.md
@@ -482,6 +494,7 @@ files:
482
494
  - lib/lono/help/param/generate.md
483
495
  - lib/lono/help/script/build.md
484
496
  - lib/lono/help/script/upload.md
497
+ - lib/lono/help/seed.md
485
498
  - lib/lono/help/summary.md
486
499
  - lib/lono/help/template.md
487
500
  - lib/lono/help/template/bashify.md
@@ -506,6 +519,7 @@ files:
506
519
  - lib/lono/script/build.rb
507
520
  - lib/lono/script/upload.rb
508
521
  - lib/lono/seed.rb
522
+ - lib/lono/seed/base.rb
509
523
  - lib/lono/sequence.rb
510
524
  - lib/lono/setting.rb
511
525
  - lib/lono/template.rb
@@ -542,7 +556,6 @@ files:
542
556
  - lib/lono/version.rb
543
557
  - lib/templates/blueprint/%blueprint_name%.gemspec.tt
544
558
  - lib/templates/blueprint/.gitignore
545
- - lib/templates/blueprint/.lono/config.yml.tt
546
559
  - lib/templates/blueprint/.meta/config.yml.tt
547
560
  - lib/templates/blueprint/CHANGELOG.md
548
561
  - lib/templates/blueprint/Gemfile
@@ -1,53 +0,0 @@
1
- require "aws-sdk-cloudformation"
2
-
3
- module Lono::Cfn::AwsService
4
- def cfn
5
- @cfn ||= Aws::CloudFormation::Client.new
6
- end
7
-
8
- def stack_exists?(stack_name)
9
- return true if testing_update?
10
- return false if @options[:noop]
11
-
12
- exist = nil
13
- begin
14
- # When the stack does not exist an exception is raised. Example:
15
- # Aws::CloudFormation::Errors::ValidationError: Stack with id blah does not exist
16
- resp = cfn.describe_stacks(stack_name: stack_name)
17
- exist = true
18
- rescue Aws::CloudFormation::Errors::ValidationError => e
19
- if e.message =~ /does not exist/
20
- exist = false
21
- elsif e.message.include?("'stackName' failed to satisfy constraint")
22
- # Example of e.message when describe_stack with invalid stack name
23
- # "1 validation error detected: Value 'instance_and_route53' at 'stackName' failed to satisfy constraint: Member must satisfy regular expression pattern: [a-zA-Z][-a-zA-Z0-9]*|arn:[-a-zA-Z0-9:/._+]*"
24
- puts "Invalid stack name: #{stack_name}"
25
- puts "Full error message: #{e.message}"
26
- exit 1
27
- else
28
- raise # re-raise exception because unsure what other errors can happen
29
- end
30
- end
31
- exist
32
- end
33
-
34
- def find_stack(stack_name)
35
- resp = cfn.describe_stacks(stack_name: stack_name)
36
- resp.stacks.first
37
- rescue Aws::CloudFormation::Errors::ValidationError => e
38
- # example: Stack with id demo-web does not exist
39
- if e.message =~ /Stack with/ && e.message =~ /does not exist/
40
- nil
41
- else
42
- raise
43
- end
44
- end
45
-
46
- def rollback_complete?(stack)
47
- stack.stack_status == 'ROLLBACK_COMPLETE'
48
- end
49
-
50
- def testing_update?
51
- ENV['TEST'] && self.class.name == "LonoCfn::Update"
52
- end
53
- end
@@ -1,18 +0,0 @@
1
- require "aws-sdk-ec2"
2
- require "aws-sdk-iam"
3
-
4
- class Lono::Configure
5
- module AwsServices
6
- def ec2
7
- @ec2 ||= Aws::EC2::Client.new
8
- end
9
-
10
- def iam
11
- @iam ||= Aws::IAM::Client.new
12
- end
13
-
14
- def sts
15
- @sts ||= Aws::STS::Client.new # part of aws-sdk-core
16
- end
17
- end
18
- end
@@ -1,94 +0,0 @@
1
- require "fileutils"
2
- require "memoist"
3
- require "yaml"
4
-
5
- # Subclasses must implement: setup, params, variables
6
- class Lono::Configure
7
- class Base
8
- include Lono::AwsServices
9
- include Helpers
10
- include Lono::Conventions
11
- extend Memoist
12
-
13
- def initialize(blueprint, options)
14
- @blueprint, @options = blueprint, options
15
-
16
- @template, @param = template_param_convention(options)
17
- @args = options[:args] || {} # hash
18
- @args.symbolize_keys!
19
-
20
- @written_files = []
21
- puts "Setting up starter values for #{@blueprint.color(:green)} blueprint"
22
- end
23
-
24
- def run
25
- setup
26
- write_configs
27
- finish
28
- final_message
29
- end
30
-
31
- # Should be implemented in subclass
32
- def setup; end
33
- def params; end
34
- def variables; end
35
-
36
- # Optionally implemented in subclasses
37
- def params_form
38
- :short # can be short, medium, or long
39
- end
40
-
41
- def finish; end
42
-
43
- protected
44
- def params_path
45
- case params_form.to_sym
46
- when :short
47
- "configs/#{@blueprint}/params/#{Lono.env}.txt"
48
- when :medium
49
- "configs/#{@blueprint}/params/#{Lono.env}/#{@param}.txt"
50
- else
51
- "configs/#{@blueprint}/params/#{Lono.env}/#{@template}/#{@param}.txt"
52
- end
53
- end
54
-
55
- def variables_path
56
- "configs/#{@blueprint}/variables/#{Lono.env}.rb"
57
- end
58
-
59
- def base_params_path
60
- params_path.sub("params/#{Lono.env}", "params/base")
61
- end
62
-
63
- def base_variables_path
64
- variables_path.sub("variables/#{Lono.env}", "variables/base")
65
- end
66
-
67
- def write_configs
68
- @params, @variables = params, variables # so it only gets called once
69
- write_file(params_path, @params) if @params
70
- write_file(variables_path, @variables) if @variables
71
- end
72
-
73
- private
74
-
75
- def write_file(path, content)
76
- FileUtils.mkdir_p(File.dirname(path))
77
- IO.write(path, content)
78
- @written_files << path
79
- end
80
-
81
- def final_message
82
- config_list = @written_files.map { |i| " * #{i}" }.join("\n")
83
-
84
- puts <<~EOL
85
- The #{@blueprint} blueprint configs are in:
86
-
87
- #{config_list}
88
-
89
- The starter values are specific to your AWS account. They meant to
90
- be starter values. Please take a look, you may want to adjust the values.
91
- EOL
92
- end
93
- end
94
- end
@@ -1,128 +0,0 @@
1
- class Lono::Configure
2
- module Helpers
3
- extend Memoist
4
-
5
- def get_input(key, default:'')
6
- value = get_seed(key, default: default, load_default: @options[:defaults])
7
- return value if value
8
-
9
- default_text = default.blank? ? '' : "(default: #{default})"
10
- print "Please provide value for #{key}#{default_text}: "
11
- value = $stdin.gets.strip
12
- value.blank? ? load_default(default) : value
13
- end
14
-
15
- # Defaults to loading the default
16
- def get_seed(key, default:, load_default: true)
17
- seed_value = from_seed(key)
18
- if seed_value
19
- puts "For #{key}, using seed value #{seed_value}"
20
- return seed_value
21
- end
22
-
23
- return load_default(default) if load_default
24
- end
25
-
26
- def load_default(default)
27
- if default.is_a?(Symbol)
28
- send(default) # IE: default_subnet
29
- else
30
- default # return the default as is
31
- end
32
- end
33
-
34
- def default_subnet
35
- subnet_ids.first
36
- end
37
-
38
- def default_vpc_id
39
- vpc = find_vpc
40
- vpc.vpc_id if vpc # default vpc might have been deleted
41
- end
42
-
43
- def default_key_name
44
- key_name
45
- end
46
-
47
- def from_seed(key)
48
- seed[key.to_s]
49
- end
50
-
51
- def seed
52
- if @options[:seed] == :convention
53
- convention_path = "seeds/#{@blueprint}/#{Lono.env}.yml"
54
- seed_file = convention_path
55
- else
56
- seed_file = @options[:seed]
57
- end
58
-
59
- unless File.exist?(seed_file)
60
- puts "WARN: unable to find seed file #{seed_file}".color(:yellow) if @options[:seed] != :convention
61
- return {}
62
- end
63
- puts "Using seed file: #{seed_file}"
64
- YAML.load_file(seed_file)
65
- end
66
- memoize :seed
67
-
68
- def key_name
69
- resp = ec2.describe_key_pairs
70
- key = resp.key_pairs.first
71
-
72
- if key
73
- key.key_name
74
- else
75
- "Please create a keypair and configure it here"
76
- end
77
- end
78
-
79
- def aws_account
80
- sts.get_caller_identity.account
81
- end
82
-
83
- def subnet_ids(vpc_id: nil, regexp: nil)
84
- vpc = find_vpc(vpc_id)
85
- unless vpc
86
- # sometimes even default VPC has been deleted
87
- abort "ERROR: Cannot find subnets because cannot find vpc #{@vpc_id} Please double check that is the right vpc".color(:red)
88
- end
89
-
90
- resp = ec2.describe_subnets(filters: [{name: 'vpc-id', values: [vpc.vpc_id]}])
91
- subnets = resp.subnets # first subnet
92
-
93
- # Assume that the subnets have a Name tag with PrivateSubnet1, PrivateSubnet2, etc
94
- # This is part of the BoltOps blueprint stack.
95
- selected_subnets = select_subnets(subnets, regexp)
96
-
97
- # if cannot find selected subnets, then keep all the subnets
98
- subnets = selected_subnets unless selected_subnets.empty?
99
- subnets.map(&:subnet_id)
100
- end
101
-
102
- def select_subnets(subnets, regexp=nil)
103
- return subnets unless regexp
104
-
105
- subnets.select do |subnet|
106
- tags = subnet.tags
107
- name_tag = tags.find { |t| t.key == "Name" }
108
- name_tag && name_tag.value =~ regexp
109
- end
110
- end
111
-
112
- # If not vpc_id is provided, it tries to find the default vpc.
113
- # If the default vpc doesnt exist, nilt is returned.
114
- def find_vpc(vpc_id=nil)
115
- if vpc_id
116
- resp = ec2.describe_vpcs(vpc_ids: [vpc_id])
117
- else
118
- resp = ec2.describe_vpcs(filters: [{name: "isDefault", values: ["true"]}])
119
- end
120
-
121
- vpcs = resp.vpcs
122
- vpcs.first
123
- rescue Aws::EC2::Errors::InvalidVpcIDNotFound
124
- nil
125
- end
126
- memoize :find_vpc
127
- end
128
- end
@@ -1,3 +0,0 @@
1
- ---
2
- blueprint_name: <%= blueprint_name %>
3
- template_type: dsl