lono 3.1.3 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/lono.rb +1 -0
- data/lib/lono/cli.rb +5 -0
- data/lib/lono/help.rb +10 -0
- data/lib/lono/importer.rb +8 -4
- data/lib/lono/inspector.rb +26 -0
- data/lib/lono/inspector/base.rb +33 -0
- data/lib/lono/inspector/depends.rb +120 -0
- data/lib/lono/inspector/help.rb +21 -0
- data/lib/lono/inspector/params.rb +28 -0
- data/lib/lono/version.rb +1 -1
- data/lib/starter_projects/json_project/.gitignore +1 -0
- data/lib/starter_projects/yaml_project/.gitignore +1 -0
- data/lono.gemspec +1 -0
- data/spec/fixtures/my_project/config/templates/base/stacks.rb +0 -2
- data/spec/lib/lono/inspect_spec.rb +20 -0
- metadata +24 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6960654946363019c9b4f49f0dbd174939c09949
|
4
|
+
data.tar.gz: 170581eadc5099100aba6146a6ed51d14c89e01a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b06de16d5ce5912eedc70f5c821f578a4a01f1a794d0ffe8369a2c8b3d0df7840962ca635b5b3f3878996cd7f15945e183a861579a71a8b05f57a511c31dc8f
|
7
|
+
data.tar.gz: 675ec16efffaf96b22dd69034ba7a636314a45f22d530a818c11f0ca32cbfe1c91c9d5c70346a350d8cfa1c5fa048e967fd1c8d2fcce6e40ee49da35cc5d9adf
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,10 @@
|
|
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
|
+
## [3.2.0]
|
7
|
+
- lono inspect depends
|
8
|
+
- lono inspect params
|
9
|
+
|
6
10
|
## [3.1.3]
|
7
11
|
- fix randomize stack name option
|
8
12
|
|
data/lib/lono.rb
CHANGED
data/lib/lono/cli.rb
CHANGED
@@ -19,6 +19,7 @@ module Lono
|
|
19
19
|
option :format, type: :string, default: "yaml", desc: "format for the final template"
|
20
20
|
option :project_root, default: ".", aliases: "-r", desc: "project root"
|
21
21
|
option :casing, default: "underscore", desc: "camelcase or underscore the template name"
|
22
|
+
option :name, default: nil, desc: "final name of downloaded template without extension"
|
22
23
|
def import(source)
|
23
24
|
Importer.new(source, options).run
|
24
25
|
end
|
@@ -56,5 +57,9 @@ module Lono
|
|
56
57
|
desc "param ACTION", "param subcommand tasks"
|
57
58
|
long_desc Help.param
|
58
59
|
subcommand "param", Lono::Param
|
60
|
+
|
61
|
+
desc "inspect ACTION", "inspect subcommand tasks"
|
62
|
+
long_desc Help.inspector
|
63
|
+
subcommand "inspect", Inspector
|
59
64
|
end
|
60
65
|
end
|
data/lib/lono/help.rb
CHANGED
data/lib/lono/importer.rb
CHANGED
@@ -12,10 +12,12 @@ class Lono::Importer
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def run
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
unless options[:noop]
|
16
|
+
download_template
|
17
|
+
template_definition_path = add_template_definition
|
18
|
+
puts "Imported raw CloudFormation template and lono-fied it!"
|
19
|
+
puts "Template definition added to #{template_definition_path}."
|
20
|
+
end
|
19
21
|
puts "Template downloaded to #{dest_path}."
|
20
22
|
end
|
21
23
|
|
@@ -51,6 +53,8 @@ class Lono::Importer
|
|
51
53
|
end
|
52
54
|
|
53
55
|
def template_name
|
56
|
+
return @options[:name] if @options[:name]
|
57
|
+
# else infer name from the original source
|
54
58
|
name = File.basename(@source, ".*")
|
55
59
|
@options[:casing] == "camelcase" ? name.camelize : name.underscore.dasherize
|
56
60
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "thor"
|
2
|
+
|
3
|
+
class Lono::Inspector < Lono::Command
|
4
|
+
autoload :Help, 'lono/inspector/help'
|
5
|
+
autoload :Base, 'lono/inspector/base'
|
6
|
+
autoload :Params, 'lono/inspector/params'
|
7
|
+
autoload :Depends, 'lono/inspector/depends'
|
8
|
+
|
9
|
+
class_option :verbose, type: :boolean
|
10
|
+
class_option :noop, type: :boolean
|
11
|
+
class_option :project_root, desc: "Project folder. Defaults to current directory", default: "."
|
12
|
+
|
13
|
+
desc "params STACK", "Prints report of CloudFormation template parameters"
|
14
|
+
option :type, type: :string, desc: "type can be: all, required, optional", default: "all"
|
15
|
+
long_desc Help.params
|
16
|
+
def params(name)
|
17
|
+
Params.new(name, options).run
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "depends STACK", "Prints dependencies tree of CloudFormation template resources"
|
21
|
+
long_desc Help.depends
|
22
|
+
option :display, type: :string, desc: "graph or text", default: "graph"
|
23
|
+
def depends(name)
|
24
|
+
Depends.new(name, options).run
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Lono::Inspector::Base
|
2
|
+
def initialize(stack_name, options)
|
3
|
+
@stack_name = stack_name
|
4
|
+
@options = options
|
5
|
+
@project_root = options[:project_root] || '.'
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate_templates
|
9
|
+
Lono::Template::DSL.new(@options.clone).run
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
generate_templates
|
14
|
+
perform
|
15
|
+
end
|
16
|
+
|
17
|
+
def data
|
18
|
+
return @data if @data
|
19
|
+
template_path = "#{@project_root}/output/#{@stack_name}.yml"
|
20
|
+
check_template_exists(template_path)
|
21
|
+
@data = YAML.load(IO.read(template_path))
|
22
|
+
end
|
23
|
+
|
24
|
+
# Check if the template exists and print friendly error message. Exits if it
|
25
|
+
# does not exist.
|
26
|
+
def check_template_exists(template_path)
|
27
|
+
unless File.exist?(template_path)
|
28
|
+
puts "The template #{template_path} does not exist. Are you sure you use the right template name? The template name does not require the extension.".colorize(:red)
|
29
|
+
exit 1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "graph"
|
3
|
+
|
4
|
+
class Lono::Inspector::Depends < Lono::Inspector::Base
|
5
|
+
def initialize(stack_name, options)
|
6
|
+
super
|
7
|
+
@nodes = [] # lookup map
|
8
|
+
end
|
9
|
+
|
10
|
+
def perform
|
11
|
+
puts "Generating dependencies tree..."
|
12
|
+
return if @options[:noop]
|
13
|
+
|
14
|
+
# First loop through top level nodes and build set depends_on property
|
15
|
+
node_list = [] # top level node list
|
16
|
+
resources = data["Resources"]
|
17
|
+
resources.each do |logical_id, resource|
|
18
|
+
node = Node.new(logical_id)
|
19
|
+
node.depends_on = normalize_depends_on(resource)
|
20
|
+
node.resource_type = normalize_resource_type(resource)
|
21
|
+
node_list << node
|
22
|
+
end
|
23
|
+
|
24
|
+
# Now that we have loop through all the top level resources once
|
25
|
+
# we can use the depends_on attribute on each node and set the
|
26
|
+
# children property since the identity nodes are in memory.
|
27
|
+
node_list.each do |node|
|
28
|
+
node.children = normalize_children(node_list, node)
|
29
|
+
end
|
30
|
+
|
31
|
+
# At this point we have a tree of nodes.
|
32
|
+
if @options[:display] == "text"
|
33
|
+
puts "CloudFormation Dependencies:"
|
34
|
+
node_list.each { |node| print_tree(node) }
|
35
|
+
else
|
36
|
+
print_graph(node_list)
|
37
|
+
puts "CloudFormation Dependencies graph generated."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# normalized DependsOn attribute to an Array of Strings
|
42
|
+
def normalize_depends_on(resource)
|
43
|
+
dependencies = resource["DependsOn"] || []
|
44
|
+
[dependencies].flatten
|
45
|
+
end
|
46
|
+
|
47
|
+
def normalize_resource_type(resource)
|
48
|
+
type = resource["Type"]
|
49
|
+
type.sub("AWS::", "") # strip out AWS to make less verbose
|
50
|
+
end
|
51
|
+
|
52
|
+
# It is possible with bad CloudFormation templates that the dependency is not
|
53
|
+
# resolved, but we wont deal with that. Users can validate their CloudFormation
|
54
|
+
# template before using this tool.
|
55
|
+
def normalize_children(node_list, node)
|
56
|
+
kids = []
|
57
|
+
node.depends_on.each do |dependent_logical_id|
|
58
|
+
node = node_list.find { |n| n.name == dependent_logical_id }
|
59
|
+
kids << node
|
60
|
+
end
|
61
|
+
kids
|
62
|
+
end
|
63
|
+
|
64
|
+
def print_tree(node, depth=0)
|
65
|
+
spacing = " " * depth
|
66
|
+
puts "#{spacing}#{node.name}"
|
67
|
+
node.children.each do |node|
|
68
|
+
print_tree(node, depth+1)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def print_graph(node_list)
|
73
|
+
check_graphviz_installed
|
74
|
+
digraph do
|
75
|
+
# graph_attribs << 'size="6,6"'
|
76
|
+
node_attribs << lightblue << filled
|
77
|
+
|
78
|
+
node_list.each do |n|
|
79
|
+
node(n.graph_name)
|
80
|
+
n.children.each do |child|
|
81
|
+
edge n.graph_name, child.graph_name
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
random = (0...8).map { (65 + rand(26)).chr }.join
|
86
|
+
path = "/tmp/cloudformation-depends-on-#{random}"
|
87
|
+
save path, "png"
|
88
|
+
# Check if open command exists and use it to open the image.
|
89
|
+
system "open #{path}.png" if system("type open > /dev/null")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Check if Graphiz is installed and prints a user friendly message if it is not installed.
|
94
|
+
# Provide instructions if on macosx.
|
95
|
+
def check_graphviz_installed
|
96
|
+
installed = system("type dot > /dev/null") # dot is a command that is part of the graphviz package
|
97
|
+
unless installed
|
98
|
+
puts "It appears that the Graphviz is not installed. Please install it to generate the graph."
|
99
|
+
if RUBY_PLATFORM =~ /darwin/
|
100
|
+
puts "You can install Graphviz with homebrew:"
|
101
|
+
puts " brew install brew install graphviz"
|
102
|
+
end
|
103
|
+
exit 1
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class Node
|
108
|
+
attr_accessor :name, :resource_type, :children, :depends_on
|
109
|
+
def initialize(name)
|
110
|
+
@name = name
|
111
|
+
@children = []
|
112
|
+
@depends_on = []
|
113
|
+
end
|
114
|
+
|
115
|
+
def graph_name
|
116
|
+
type = "(#{resource_type})" if resource_type
|
117
|
+
[name, type].compact.join("\n")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Lono::Inspector::Params < Lono::Inspector::Base
|
2
|
+
def perform
|
3
|
+
puts "Parameters Summary:"
|
4
|
+
return if @options[:noop]
|
5
|
+
|
6
|
+
print_parameters("Required", required_parameters)
|
7
|
+
print_parameters("Optional", optional_parameters)
|
8
|
+
end
|
9
|
+
|
10
|
+
def print_parameters(label, parameters)
|
11
|
+
puts "#{label}:"
|
12
|
+
if parameters.empty?
|
13
|
+
puts " There are no #{label.downcase} parameters"
|
14
|
+
else
|
15
|
+
parameters.each do |logical_id, p|
|
16
|
+
puts " #{logical_id}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def required_parameters
|
22
|
+
data["Parameters"].select { |logical_id, p| p["Default"] }
|
23
|
+
end
|
24
|
+
|
25
|
+
def optional_parameters
|
26
|
+
data["Parameters"].reject { |logical_id, p| p["Default"] }
|
27
|
+
end
|
28
|
+
end
|
data/lib/lono/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
/output
|
@@ -0,0 +1 @@
|
|
1
|
+
/output
|
data/lono.gemspec
CHANGED
@@ -28,6 +28,7 @@ Gem::Specification.new do |gem|
|
|
28
28
|
gem.add_dependency "hashie"
|
29
29
|
gem.add_dependency "aws-sdk", '~> 3'
|
30
30
|
gem.add_dependency "activesupport"
|
31
|
+
gem.add_dependency "graph" # lono inspect depends
|
31
32
|
# gem.add_dependency "plissken" # dependency for vendor/lono-params
|
32
33
|
# using the vendor fork version: https://github.com/tongueroo/plissken
|
33
34
|
# until https://github.com/futurechimp/plissken/pull/6 gets merged
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative "../../spec_helper"
|
2
|
+
|
3
|
+
describe Lono::Inspector do
|
4
|
+
before(:all) do
|
5
|
+
@args = "--noop --project-root spec/fixtures/my_project"
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "lono inspect" do
|
9
|
+
it "depends" do
|
10
|
+
out = execute("bin/lono inspect depends my-stack #{@args}")
|
11
|
+
expect(out).to include("Generating dependencies tree")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "params" do
|
15
|
+
out = execute("bin/lono inspect params my-stack #{@args}")
|
16
|
+
expect(out).to include("Parameters Summary")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lono
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tung Nguyen
|
@@ -150,6 +150,20 @@ dependencies:
|
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: graph
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
153
167
|
- !ruby/object:Gem::Dependency
|
154
168
|
name: byebug
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -262,6 +276,11 @@ files:
|
|
262
276
|
- lib/lono/env.rb
|
263
277
|
- lib/lono/help.rb
|
264
278
|
- lib/lono/importer.rb
|
279
|
+
- lib/lono/inspector.rb
|
280
|
+
- lib/lono/inspector/base.rb
|
281
|
+
- lib/lono/inspector/depends.rb
|
282
|
+
- lib/lono/inspector/help.rb
|
283
|
+
- lib/lono/inspector/params.rb
|
265
284
|
- lib/lono/new.rb
|
266
285
|
- lib/lono/param.rb
|
267
286
|
- lib/lono/param/generator.rb
|
@@ -277,6 +296,7 @@ files:
|
|
277
296
|
- lib/lono/template/template.rb
|
278
297
|
- lib/lono/template/upload.rb
|
279
298
|
- lib/lono/version.rb
|
299
|
+
- lib/starter_projects/json_project/.gitignore
|
280
300
|
- lib/starter_projects/json_project/Gemfile
|
281
301
|
- lib/starter_projects/json_project/Guardfile
|
282
302
|
- lib/starter_projects/json_project/config/templates/base/blog.rb
|
@@ -290,6 +310,7 @@ files:
|
|
290
310
|
- lib/starter_projects/json_project/templates/user_data/db2.sh
|
291
311
|
- lib/starter_projects/json_project/templates/user_data/ruby_script.rb
|
292
312
|
- lib/starter_projects/json_project/templates/web.json
|
313
|
+
- lib/starter_projects/yaml_project/.gitignore
|
293
314
|
- lib/starter_projects/yaml_project/Gemfile
|
294
315
|
- lib/starter_projects/yaml_project/Guardfile
|
295
316
|
- lib/starter_projects/yaml_project/config/templates/base/blog.rb
|
@@ -322,6 +343,7 @@ files:
|
|
322
343
|
- spec/fixtures/params/overlay/params/prod/network.txt
|
323
344
|
- spec/fixtures/raw_templates/aws-waf-security-automations.template
|
324
345
|
- spec/lib/lono/cfn_spec.rb
|
346
|
+
- spec/lib/lono/inspect_spec.rb
|
325
347
|
- spec/lib/lono/new_spec.rb
|
326
348
|
- spec/lib/lono/param/generator_spec.rb
|
327
349
|
- spec/lib/lono/param_spec.rb
|
@@ -380,6 +402,7 @@ test_files:
|
|
380
402
|
- spec/fixtures/params/overlay/params/prod/network.txt
|
381
403
|
- spec/fixtures/raw_templates/aws-waf-security-automations.template
|
382
404
|
- spec/lib/lono/cfn_spec.rb
|
405
|
+
- spec/lib/lono/inspect_spec.rb
|
383
406
|
- spec/lib/lono/new_spec.rb
|
384
407
|
- spec/lib/lono/param/generator_spec.rb
|
385
408
|
- spec/lib/lono/param_spec.rb
|