humidifier 4.1.1 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +1 -1
- data/.rubocop.yml +15 -1
- data/CHANGELOG.md +12 -1
- data/CloudFormationResourceSpecification.json +104326 -35227
- data/Gemfile +1 -1
- data/Gemfile.lock +31 -31
- data/README.md +5 -0
- data/Rakefile +11 -11
- data/exe/humidifier +5 -5
- data/humidifier.gemspec +29 -29
- data/lib/humidifier/cli.rb +30 -22
- data/lib/humidifier/config/mapper.rb +1 -1
- data/lib/humidifier/config/mapping.rb +2 -2
- data/lib/humidifier/config.rb +1 -1
- data/lib/humidifier/directory.rb +5 -5
- data/lib/humidifier/loader.rb +104 -48
- data/lib/humidifier/output.rb +3 -3
- data/lib/humidifier/parameter.rb +2 -2
- data/lib/humidifier/props.rb +73 -51
- data/lib/humidifier/ref.rb +1 -1
- data/lib/humidifier/resource.rb +3 -3
- data/lib/humidifier/serializer.rb +2 -2
- data/lib/humidifier/stack.rb +6 -6
- data/lib/humidifier/upgrade.rb +10 -10
- data/lib/humidifier/version.rb +1 -1
- data/lib/humidifier.rb +31 -31
- metadata +6 -6
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
humidifier (4.
|
4
|
+
humidifier (4.2.0)
|
5
5
|
aws-sdk-cloudformation (~> 1.25)
|
6
6
|
aws-sdk-s3 (~> 1.48)
|
7
7
|
fast_underscore (~> 0.3)
|
@@ -14,52 +14,50 @@ GEM
|
|
14
14
|
specs:
|
15
15
|
ast (2.4.2)
|
16
16
|
aws-eventstream (1.2.0)
|
17
|
-
aws-partitions (1.
|
18
|
-
aws-sdk-cloudformation (1.
|
19
|
-
aws-sdk-core (~> 3, >= 3.
|
17
|
+
aws-partitions (1.592.0)
|
18
|
+
aws-sdk-cloudformation (1.69.0)
|
19
|
+
aws-sdk-core (~> 3, >= 3.127.0)
|
20
20
|
aws-sigv4 (~> 1.1)
|
21
|
-
aws-sdk-core (3.
|
21
|
+
aws-sdk-core (3.131.1)
|
22
22
|
aws-eventstream (~> 1, >= 1.0.2)
|
23
23
|
aws-partitions (~> 1, >= 1.525.0)
|
24
24
|
aws-sigv4 (~> 1.1)
|
25
|
-
jmespath (~> 1.
|
26
|
-
aws-sdk-kms (1.
|
27
|
-
aws-sdk-core (~> 3, >= 3.
|
25
|
+
jmespath (~> 1, >= 1.6.1)
|
26
|
+
aws-sdk-kms (1.56.0)
|
27
|
+
aws-sdk-core (~> 3, >= 3.127.0)
|
28
28
|
aws-sigv4 (~> 1.1)
|
29
|
-
aws-sdk-s3 (1.
|
30
|
-
aws-sdk-core (~> 3, >= 3.
|
29
|
+
aws-sdk-s3 (1.114.0)
|
30
|
+
aws-sdk-core (~> 3, >= 3.127.0)
|
31
31
|
aws-sdk-kms (~> 1)
|
32
32
|
aws-sigv4 (~> 1.4)
|
33
|
-
aws-sigv4 (1.
|
33
|
+
aws-sigv4 (1.5.0)
|
34
34
|
aws-eventstream (~> 1, >= 1.0.2)
|
35
35
|
docile (1.4.0)
|
36
36
|
fast_underscore (0.3.3)
|
37
37
|
hollaback (0.1.1)
|
38
|
-
jmespath (1.
|
39
|
-
|
40
|
-
|
41
|
-
nokogiri (1.12.5)
|
42
|
-
mini_portile2 (~> 2.6.1)
|
38
|
+
jmespath (1.6.1)
|
39
|
+
minitest (5.15.0)
|
40
|
+
nokogiri (1.13.6-x86_64-darwin)
|
43
41
|
racc (~> 1.4)
|
44
|
-
parallel (1.
|
45
|
-
parser (3.
|
42
|
+
parallel (1.22.1)
|
43
|
+
parser (3.1.2.0)
|
46
44
|
ast (~> 2.4.1)
|
47
45
|
racc (1.6.0)
|
48
|
-
rainbow (3.
|
46
|
+
rainbow (3.1.1)
|
49
47
|
rake (13.0.6)
|
50
|
-
regexp_parser (2.
|
48
|
+
regexp_parser (2.5.0)
|
51
49
|
rexml (3.2.5)
|
52
|
-
rubocop (1.
|
50
|
+
rubocop (1.30.1)
|
53
51
|
parallel (~> 1.10)
|
54
|
-
parser (>= 3.
|
52
|
+
parser (>= 3.1.0.0)
|
55
53
|
rainbow (>= 2.2.2, < 4.0)
|
56
54
|
regexp_parser (>= 1.8, < 3.0)
|
57
|
-
rexml
|
58
|
-
rubocop-ast (>= 1.
|
55
|
+
rexml (>= 3.2.5, < 4.0)
|
56
|
+
rubocop-ast (>= 1.18.0, < 2.0)
|
59
57
|
ruby-progressbar (~> 1.7)
|
60
58
|
unicode-display_width (>= 1.4.0, < 3.0)
|
61
|
-
rubocop-ast (1.
|
62
|
-
parser (>= 3.
|
59
|
+
rubocop-ast (1.18.0)
|
60
|
+
parser (>= 3.1.1.0)
|
63
61
|
ruby-progressbar (1.11.0)
|
64
62
|
simplecov (0.21.2)
|
65
63
|
docile (~> 1.1)
|
@@ -67,12 +65,14 @@ GEM
|
|
67
65
|
simplecov_json_formatter (~> 0.1)
|
68
66
|
simplecov-html (0.12.3)
|
69
67
|
simplecov_json_formatter (0.1.3)
|
70
|
-
thor (1.1
|
71
|
-
thor-hollaback (0.2.
|
72
|
-
hollaback (~> 0.1
|
68
|
+
thor (1.2.1)
|
69
|
+
thor-hollaback (0.2.1)
|
70
|
+
hollaback (~> 0.1)
|
73
71
|
thor (>= 0.19.1)
|
74
72
|
unicode-display_width (2.1.0)
|
75
|
-
|
73
|
+
webrick (1.7.0)
|
74
|
+
yard (0.9.28)
|
75
|
+
webrick (~> 1.7.0)
|
76
76
|
|
77
77
|
PLATFORMS
|
78
78
|
ruby
|
@@ -82,7 +82,7 @@ DEPENDENCIES
|
|
82
82
|
humidifier!
|
83
83
|
minitest (~> 5.13)
|
84
84
|
rake (~> 13.0)
|
85
|
-
rubocop (~> 1.
|
85
|
+
rubocop (~> 1.24)
|
86
86
|
simplecov (~> 0.17)
|
87
87
|
yard (~> 0.9)
|
88
88
|
|
data/README.md
CHANGED
@@ -25,6 +25,7 @@ Humidifier is a ruby tool for managing [AWS CloudFormation](https://aws.amazon.c
|
|
25
25
|
- [`upgrade`](#upgrade)
|
26
26
|
- [`upload [?stack]`](#upload-stack)
|
27
27
|
- [`validate [?stack]`](#validate-stack)
|
28
|
+
- [`version`](#version)
|
28
29
|
- [Parameters](#parameters)
|
29
30
|
- [Shortcuts](#shortcuts)
|
30
31
|
- [Automatic id properties](#automatic-id-properties)
|
@@ -272,6 +273,10 @@ Upload one or all stacks in the repo to S3 for reference later. Note that this m
|
|
272
273
|
|
273
274
|
Validate that one or all stacks in the repo are properly configured and using values that CloudFormation understands.
|
274
275
|
|
276
|
+
#### `version`
|
277
|
+
|
278
|
+
Output the version of `Humidifier` as well as the version of the CloudFormation resource specification that you are using.
|
279
|
+
|
275
280
|
### Parameters
|
276
281
|
|
277
282
|
CloudFormation template parameters can be specified by having a special `parameters.yml` file in your stack directory. This file should contain a YAML-encoded object whose keys are the names of the parameters and whose values are the parameter configuration (using the same underscore paradigm as `humidifier` resources for specifying configuration).
|
data/Rakefile
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "fileutils"
|
5
|
+
require "rake/testtask"
|
6
|
+
require "yard"
|
7
7
|
|
8
8
|
Rake::TestTask.new(:test) do |t|
|
9
|
-
t.libs <<
|
10
|
-
t.libs <<
|
11
|
-
t.test_files = FileList[
|
9
|
+
t.libs << "test"
|
10
|
+
t.libs << "lib"
|
11
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
12
12
|
t.warning = false
|
13
13
|
end
|
14
14
|
|
15
15
|
task default: :test
|
16
16
|
|
17
17
|
YARD::Rake::YardocTask.new(:yard) do |t|
|
18
|
-
filepath = File.join(
|
18
|
+
filepath = File.join("lib", "humidifier", "magic.rb")
|
19
19
|
|
20
|
-
t.stats_options = [
|
20
|
+
t.stats_options = ["--list-undoc"]
|
21
21
|
t.before = lambda do
|
22
|
-
require
|
23
|
-
require_relative
|
22
|
+
require "humidifier"
|
23
|
+
require_relative "yard/dynamic"
|
24
24
|
Dynamic.generate(filepath)
|
25
25
|
end
|
26
26
|
t.after = -> { FileUtils.rm(filepath) }
|
data/exe/humidifier
CHANGED
@@ -3,13 +3,13 @@
|
|
3
3
|
|
4
4
|
# If there is a `bin/humidifier` file, then swap out execution of this default
|
5
5
|
# CLI with the custom CLI instead.
|
6
|
-
if File.file?(File.join(
|
7
|
-
exec(File.join(
|
6
|
+
if File.file?(File.join("bin", "humidifier"))
|
7
|
+
exec(File.join("bin", "humidifier"))
|
8
8
|
end
|
9
9
|
|
10
|
-
require
|
10
|
+
require "bundler/setup"
|
11
11
|
|
12
|
-
$LOAD_PATH.unshift File.expand_path(File.join(
|
13
|
-
require
|
12
|
+
$LOAD_PATH.unshift File.expand_path(File.join("..", "lib"), __dir__)
|
13
|
+
require "humidifier"
|
14
14
|
|
15
15
|
Humidifier::CLI.start(ARGV)
|
data/humidifier.gemspec
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "lib/humidifier/version"
|
4
4
|
|
5
5
|
version = Humidifier::VERSION
|
6
|
-
repository =
|
6
|
+
repository = "https://github.com/kddnewton/humidifier"
|
7
7
|
|
8
8
|
Gem::Specification.new do |spec|
|
9
|
-
spec.name =
|
9
|
+
spec.name = "humidifier"
|
10
10
|
spec.version = version
|
11
|
-
spec.authors = [
|
12
|
-
spec.email = [
|
11
|
+
spec.authors = ["Kevin Newton"]
|
12
|
+
spec.email = ["kddnewton@gmail.com"]
|
13
13
|
|
14
|
-
spec.summary =
|
15
|
-
spec.description =
|
16
|
-
|
14
|
+
spec.summary = "CloudFormation made easy"
|
15
|
+
spec.description = "Programmatically generate and manage AWS " \
|
16
|
+
"CloudFormation templates, stacks, and change sets."
|
17
17
|
spec.homepage = repository
|
18
|
-
spec.license =
|
18
|
+
spec.license = "MIT"
|
19
19
|
|
20
20
|
spec.metadata = {
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
"bug_tracker_uri" => "#{repository}/issues",
|
22
|
+
"changelog_uri" => "#{repository}/blob/v#{version}/CHANGELOG.md",
|
23
|
+
"source_code_uri" => repository,
|
24
|
+
"rubygems_mfa_required" => "true"
|
25
25
|
}
|
26
26
|
|
27
27
|
spec.files = Dir.chdir(__dir__) do
|
@@ -30,21 +30,21 @@ Gem::Specification.new do |spec|
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
spec.bindir =
|
33
|
+
spec.bindir = "exe"
|
34
34
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
35
|
-
spec.require_paths = [
|
36
|
-
|
37
|
-
spec.add_dependency
|
38
|
-
spec.add_dependency
|
39
|
-
spec.add_dependency
|
40
|
-
spec.add_dependency
|
41
|
-
spec.add_dependency
|
42
|
-
spec.add_dependency
|
43
|
-
|
44
|
-
spec.add_development_dependency
|
45
|
-
spec.add_development_dependency
|
46
|
-
spec.add_development_dependency
|
47
|
-
spec.add_development_dependency
|
48
|
-
spec.add_development_dependency
|
49
|
-
spec.add_development_dependency
|
35
|
+
spec.require_paths = ["lib"]
|
36
|
+
|
37
|
+
spec.add_dependency "aws-sdk-cloudformation", "~> 1.25"
|
38
|
+
spec.add_dependency "aws-sdk-s3", "~> 1.48"
|
39
|
+
spec.add_dependency "fast_underscore", "~> 0.3"
|
40
|
+
spec.add_dependency "nokogiri", "~> 1.10"
|
41
|
+
spec.add_dependency "thor", "~> 1.0"
|
42
|
+
spec.add_dependency "thor-hollaback", "~> 0.2"
|
43
|
+
|
44
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
45
|
+
spec.add_development_dependency "minitest", "~> 5.13"
|
46
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
47
|
+
spec.add_development_dependency "rubocop", "~> 1.24"
|
48
|
+
spec.add_development_dependency "simplecov", "~> 0.17"
|
49
|
+
spec.add_development_dependency "yard", "~> 0.9"
|
50
50
|
end
|
data/lib/humidifier/cli.rb
CHANGED
@@ -4,13 +4,13 @@ module Humidifier
|
|
4
4
|
# A CLI for running commands to manipulate the stacks that Humidifier knows
|
5
5
|
# about.
|
6
6
|
class CLI < Thor
|
7
|
-
class_option :aws_profile, desc:
|
8
|
-
aliases: [
|
7
|
+
class_option :aws_profile, desc: "The AWS profile to authenticate with",
|
8
|
+
aliases: ["-p"]
|
9
9
|
|
10
|
-
class_option :debug, desc:
|
10
|
+
class_option :debug, desc: "Sets up debug mode", aliases: ["-d"]
|
11
11
|
class_around :safe_execute
|
12
12
|
|
13
|
-
desc
|
13
|
+
desc "change [?stack]", "Create changesets for one or all stacks"
|
14
14
|
def change(name = nil)
|
15
15
|
authorize
|
16
16
|
|
@@ -22,10 +22,10 @@ module Humidifier
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
desc
|
26
|
-
option :wait, desc:
|
25
|
+
desc "deploy [?stack] [*parameters]", "Update one or all stacks"
|
26
|
+
option :wait, desc: "Wait for the stack to create/update",
|
27
27
|
type: :boolean, default: false
|
28
|
-
option :prefix, desc:
|
28
|
+
option :prefix, desc: "The prefix to use for the stack"
|
29
29
|
def deploy(name = nil, *parameters)
|
30
30
|
authorize
|
31
31
|
|
@@ -37,8 +37,8 @@ module Humidifier
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
desc
|
41
|
-
|
40
|
+
desc "display [stack] [?pattern]",
|
41
|
+
"Display the CloudFormation JSON for a given stack"
|
42
42
|
def display(name, pattern = nil)
|
43
43
|
directory = Directory.new(name, pattern: pattern && /#{pattern}/i)
|
44
44
|
|
@@ -46,21 +46,21 @@ module Humidifier
|
|
46
46
|
puts directory.to_cf
|
47
47
|
end
|
48
48
|
|
49
|
-
desc
|
49
|
+
desc "stacks", "List the stacks known to Humidifier"
|
50
50
|
def stacks
|
51
|
-
puts
|
51
|
+
puts "🗒 Listing stacks"
|
52
52
|
puts Humidifier.config.stack_names.sort.map { |name| "- #{name}" }
|
53
53
|
end
|
54
54
|
|
55
|
-
desc
|
55
|
+
desc "upgrade", "Download the latest CloudFormation resource specification"
|
56
56
|
def upgrade
|
57
|
-
print
|
57
|
+
print "💾 Downloading..."
|
58
58
|
|
59
59
|
version = Upgrade.perform
|
60
60
|
puts " upgraded to v#{version}"
|
61
61
|
end
|
62
62
|
|
63
|
-
desc
|
63
|
+
desc "upload [?stack]", "Upload one or all stacks to S3"
|
64
64
|
def upload(name = nil)
|
65
65
|
authorize
|
66
66
|
|
@@ -72,22 +72,30 @@ module Humidifier
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
-
desc
|
76
|
-
|
75
|
+
desc "validate [?stack]",
|
76
|
+
"Validate that one or all stacks are valid with CloudFormation"
|
77
77
|
def validate(name = nil)
|
78
78
|
authorize
|
79
79
|
|
80
|
-
print
|
80
|
+
print "🔍 Validating... "
|
81
81
|
|
82
82
|
valid =
|
83
83
|
stack_names_from(name).all? do |stack_name|
|
84
84
|
Directory.new(stack_name).valid?
|
85
85
|
end
|
86
86
|
|
87
|
-
puts valid ?
|
87
|
+
puts valid ? "Valid." : "Invalid."
|
88
88
|
end
|
89
89
|
|
90
|
-
|
90
|
+
desc "version", "Display the version of Humidifier"
|
91
|
+
def version
|
92
|
+
filepath = File.expand_path("../../#{SPECIFICATION}", __dir__)
|
93
|
+
version = JSON.parse(File.read(filepath))["ResourceSpecificationVersion"]
|
94
|
+
|
95
|
+
puts "📦 CloudFormation specification v#{version}"
|
96
|
+
end
|
97
|
+
|
98
|
+
no_commands do
|
91
99
|
def authorize
|
92
100
|
return unless options[:aws_profile]
|
93
101
|
|
@@ -97,14 +105,14 @@ module Humidifier
|
|
97
105
|
|
98
106
|
def parameters_from(opts)
|
99
107
|
opts.map do |opt|
|
100
|
-
key, value = opt.split(
|
108
|
+
key, value = opt.split("=")
|
101
109
|
{ parameter_key: key, parameter_value: value }
|
102
110
|
end
|
103
111
|
end
|
104
112
|
|
105
113
|
def prelude
|
106
114
|
command = @_invocations.values.dig(0, 0)
|
107
|
-
command = command ? "#{command} " :
|
115
|
+
command = command ? "#{command} " : ""
|
108
116
|
puts "\033[1mhumidifier #{command}v#{VERSION}\033[0m"
|
109
117
|
end
|
110
118
|
|
@@ -118,7 +126,7 @@ module Humidifier
|
|
118
126
|
puts error.message
|
119
127
|
exit 1
|
120
128
|
else
|
121
|
-
puts
|
129
|
+
puts "✨ Done in %.2fs." % (Time.now.to_f - start)
|
122
130
|
end
|
123
131
|
|
124
132
|
def stack_names_from(name)
|
@@ -83,7 +83,7 @@ module Humidifier
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
def mapped_from(clazz, key, value)
|
86
|
+
def mapped_from(clazz, key, value)
|
87
87
|
if self.class.attribute_methods.include?(key.to_sym)
|
88
88
|
# The given attribute name has been defined using the `::attribute`
|
89
89
|
# DSL method, so send the given value to that method and return the
|
@@ -10,7 +10,7 @@ module Humidifier
|
|
10
10
|
raise Error, "Invalid resource: #{opts[:to].inspect}" if @clazz.nil?
|
11
11
|
|
12
12
|
if opts[:using] && block_given?
|
13
|
-
raise Error,
|
13
|
+
raise Error, "Cannot specify :using and provide an anonymous mapper"
|
14
14
|
end
|
15
15
|
|
16
16
|
@mapper = mapper_from(opts, &block)
|
@@ -33,7 +33,7 @@ module Humidifier
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def normalized(name)
|
36
|
-
name.start_with?(
|
36
|
+
name.start_with?("AWS") ? name : "AWS::#{name}"
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
data/lib/humidifier/config.rb
CHANGED
data/lib/humidifier/directory.rb
CHANGED
@@ -82,7 +82,7 @@ module Humidifier
|
|
82
82
|
begin
|
83
83
|
parameter_filepath =
|
84
84
|
Humidifier.config.files_for(name).detect do |filepath|
|
85
|
-
File.basename(filepath,
|
85
|
+
File.basename(filepath, ".yml") == "parameters"
|
86
86
|
end
|
87
87
|
|
88
88
|
parameter_filepath ? parameters_from(parameter_filepath) : {}
|
@@ -94,7 +94,7 @@ module Humidifier
|
|
94
94
|
return {} unless loaded
|
95
95
|
|
96
96
|
loaded.each_with_object({}) do |(name, opts), params|
|
97
|
-
opts = opts.
|
97
|
+
opts = opts.to_h { |key, value| [key.to_sym, value] }
|
98
98
|
params[name] = Parameter.new(opts)
|
99
99
|
end
|
100
100
|
end
|
@@ -109,7 +109,7 @@ module Humidifier
|
|
109
109
|
loaded.each_with_object({}) do |(name, attributes), resources|
|
110
110
|
next if pattern && name !~ pattern
|
111
111
|
|
112
|
-
attribute = attributes.delete(
|
112
|
+
attribute = attributes.delete("export")
|
113
113
|
exports << Export.new(name, attribute) if attribute
|
114
114
|
|
115
115
|
resources[name] = mapping.resource_for(name, attributes)
|
@@ -120,10 +120,10 @@ module Humidifier
|
|
120
120
|
filepaths = Humidifier.config.files_for(name)
|
121
121
|
|
122
122
|
filepaths.each_with_object({}) do |filepath, resources|
|
123
|
-
basename = File.basename(filepath,
|
123
|
+
basename = File.basename(filepath, ".yml")
|
124
124
|
|
125
125
|
# Explicitly skip past parameters so we can pull them out later
|
126
|
-
next if basename ==
|
126
|
+
next if basename == "parameters"
|
127
127
|
|
128
128
|
resources.merge!(parse(filepath, basename))
|
129
129
|
end
|