auster 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +13 -0
  3. data/.gitignore +9 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +41 -0
  6. data/.travis.yml +5 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +3 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +152 -0
  11. data/Rakefile +6 -0
  12. data/auster.gemspec +37 -0
  13. data/bin/auster +8 -0
  14. data/bin/console +8 -0
  15. data/example-repo/.auster.yaml +0 -0
  16. data/example-repo/cfer-helpers/.keep +0 -0
  17. data/example-repo/config/.keep +0 -0
  18. data/example-repo/config/schema.yaml +10 -0
  19. data/example-repo/config/us-west-2/dev-ed1.yaml +7 -0
  20. data/example-repo/config/validator.rb +5 -0
  21. data/example-repo/steps/.keep +0 -0
  22. data/example-repo/steps/00.bootstrap/.keep +0 -0
  23. data/example-repo/steps/00.bootstrap/cfer/defs/s3.rb +3 -0
  24. data/example-repo/steps/00.bootstrap/cfer/outputs.rb +1 -0
  25. data/example-repo/steps/00.bootstrap/cfer/parameters.rb +0 -0
  26. data/example-repo/steps/00.bootstrap/cfer/require.rb +0 -0
  27. data/example-repo/steps/00.bootstrap/on-create.d/00-debug.rb +4 -0
  28. data/example-repo/steps/00.bootstrap/on-destroy.d/00-debug.rb +4 -0
  29. data/example-repo/steps/00.bootstrap/post-converge.d/00-debug.rb +5 -0
  30. data/example-repo/steps/00.bootstrap/pre-converge.d/00-debug.rb +4 -0
  31. data/example-repo/steps/01.dependent/.keep +0 -0
  32. data/example-repo/steps/01.dependent/cfer/defs/s3.rb +3 -0
  33. data/example-repo/steps/01.dependent/cfer/outputs.rb +1 -0
  34. data/example-repo/steps/01.dependent/cfer/parameters.rb +0 -0
  35. data/example-repo/steps/01.dependent/cfer/require.rb +0 -0
  36. data/example-repo/steps/01.dependent/on-create.d/00-debug.rb +4 -0
  37. data/example-repo/steps/01.dependent/on-destroy.d/00-debug.rb +4 -0
  38. data/example-repo/steps/01.dependent/post-converge.d/00-debug.rb +7 -0
  39. data/example-repo/steps/01.dependent/pre-converge.d/00-debug.rb +5 -0
  40. data/lib/cfer/auster/cfer_evaluator.rb +125 -0
  41. data/lib/cfer/auster/cfer_helpers.rb +71 -0
  42. data/lib/cfer/auster/cli/_shared.rb +49 -0
  43. data/lib/cfer/auster/cli/destroy.rb +34 -0
  44. data/lib/cfer/auster/cli/generate/repo.rb +27 -0
  45. data/lib/cfer/auster/cli/generate/step.rb +27 -0
  46. data/lib/cfer/auster/cli/generate.rb +35 -0
  47. data/lib/cfer/auster/cli/json.rb +44 -0
  48. data/lib/cfer/auster/cli/nuke.rb +62 -0
  49. data/lib/cfer/auster/cli/run.rb +34 -0
  50. data/lib/cfer/auster/cli.rb +60 -0
  51. data/lib/cfer/auster/config.rb +70 -0
  52. data/lib/cfer/auster/logging.rb +32 -0
  53. data/lib/cfer/auster/param_validator.rb +22 -0
  54. data/lib/cfer/auster/repo.rb +158 -0
  55. data/lib/cfer/auster/script_executor.rb +57 -0
  56. data/lib/cfer/auster/step.rb +181 -0
  57. data/lib/cfer/auster/version.rb +5 -0
  58. data/lib/cfer/auster.rb +22 -0
  59. metadata +270 -0
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+ module Cfer
3
+ module Auster
4
+ class Repo
5
+ include Cfer::Auster::Logging::Mixin
6
+
7
+ REPO_FILE = ".auster.yaml"
8
+ STEP_REGEX = /(?<count>[0-9]{2})\.(?<tag>[a-z0-9][a-z0-9\-]*[a-z0-9])/
9
+ INT_REGEX = /[0-9]+/
10
+
11
+ attr_reader :root
12
+ attr_reader :options
13
+
14
+ attr_reader :steps
15
+ attr_reader :config_sets
16
+
17
+ attr_reader :param_validator
18
+
19
+ def initialize(root)
20
+ raise "root must be a String." unless root.is_a?(String)
21
+ @root = File.expand_path(root).freeze
22
+
23
+ logger.debug "Repo location: #{@root}"
24
+
25
+ options_file = File.expand_path(REPO_FILE, @root)
26
+ logger.debug "Loading options file..."
27
+ raise "#{options_file} does not exist." unless File.file?(options_file)
28
+ @options = YAML.load_file(options_file)
29
+
30
+ @cfg_root = File.join(@root, "config").freeze
31
+ raise "#{@cfg_root} does not exist." unless File.directory?(@cfg_root)
32
+ @step_root = File.join(@root, "steps").freeze
33
+ raise "#{@step_root} does not exist." unless File.directory?(@step_root)
34
+
35
+ logger.debug "Enumerating steps..."
36
+ steps = build_steps
37
+ step_tags = steps.map(&:tag)
38
+ step_counts = steps.map(&:count)
39
+
40
+ raise "Multiple steps with the same tag found. Can't continue." \
41
+ if step_tags.uniq.length != steps.length
42
+ raise "Multiple steps with the same count found. Can't continue." \
43
+ if step_counts.uniq.length != steps.length
44
+
45
+ @steps = steps.map { |step| [step.count, step] }.to_h.freeze
46
+ @steps_by_tag = steps.map { |step| [step.tag, step.count] }.to_h.freeze
47
+
48
+ logger.debug "Enumerating config sets..."
49
+ @config_sets = find_config_sets
50
+
51
+ logger.debug "Loading param validator..."
52
+ @param_validator = load_param_validator
53
+ end
54
+
55
+ def step_by_tag(tag)
56
+ raise "Couldn't find a step with tag '#{tag}'." unless @steps_by_tag.key?(tag)
57
+ @steps[@steps_by_tag[tag]]
58
+ end
59
+
60
+ def step_by_count(count)
61
+ @steps[count.to_i]
62
+ end
63
+
64
+ def step_by_count_or_tag(value)
65
+ if INT_REGEX.match(value)
66
+ step_by_count(value)
67
+ else
68
+ step_by_tag(value)
69
+ end
70
+ end
71
+
72
+ def ordered_steps
73
+ @steps.sort.map(&:last)
74
+ end
75
+
76
+ def config_set(id)
77
+ raise "Config set not found with id '#{id}'." unless @config_sets.include?(id)
78
+
79
+ tokens = id.split("/")
80
+
81
+ name = tokens[1]
82
+ region = tokens[0]
83
+
84
+ filename = File.join(@cfg_root, "#{id}.yaml")
85
+
86
+ schema_file = File.join(@cfg_root, "schema.yaml")
87
+ schema_file = nil unless File.file?(schema_file)
88
+
89
+ Cfer::Auster::Config.from_file(name: name, aws_region: region,
90
+ schema_file: schema_file, data_file: filename)
91
+ end
92
+
93
+ def nuke(config_set)
94
+ raise "config_set must be a Cfer::Auster::Config." unless config_set.is_a?(Cfer::Auster::Config)
95
+
96
+ logger.info "Nuking '#{config_set.full_name}'."
97
+
98
+ ordered_steps.reverse.each { |step| step.destroy(config_set) }
99
+ end
100
+
101
+ private
102
+
103
+ def build_steps
104
+ Dir[File.join(@step_root, "*")].map do |step_dir|
105
+ step_name = File.basename(step_dir)
106
+ match = STEP_REGEX.match(step_name)
107
+
108
+ if match.nil?
109
+ logger.warn "Unrecognized directory '#{step_name}' in steps, skipping."
110
+ nil
111
+ else
112
+ logger.debug "Step found: #{match[:count]}.#{match[:tag]}"
113
+ Cfer::Auster::Step.new(repo: self, count: match[:count], tag: match[:tag], directory: step_dir)
114
+ end
115
+ end.reject(&:nil?)
116
+ end
117
+
118
+ def find_config_sets
119
+ Dir[File.join(@cfg_root, "**/*.yaml")].map do |cfgset_file|
120
+ if File.dirname(cfgset_file) == @cfg_root
121
+ nil # because it's not inside an AWS region
122
+ else
123
+ # this could probably be cleaner.
124
+ cfgset_file.gsub(@cfg_root, "").gsub(".yaml", "")[1..-1]
125
+ end
126
+ end.reject(&:nil?)
127
+ end
128
+
129
+ def load_param_validator
130
+ validator_path = File.join(@cfg_root, "validator.rb")
131
+
132
+ if File.file?(validator_path)
133
+ validator_rb = IO.read(validator_path)
134
+ validator = instance_eval(validator_rb, validator_path)
135
+
136
+ raise "#{validator_path} error: must return a Cfer::Auster::ParamValidator." \
137
+ unless validator.is_a?(Cfer::Auster::ParamValidator)
138
+
139
+ validator
140
+ else
141
+ Cfer::Auster::ParamValidator.new { |_, _| }
142
+ end
143
+ end
144
+
145
+ class << self
146
+ def discover_from_cwd
147
+ require "search_up"
148
+
149
+ repo_file = SearchUp.search(Dir.pwd, REPO_FILE) { |f| File.file?(f) }.first
150
+
151
+ raise "No repo found (signaled by #{REPO_FILE}) from pwd to root." if repo_file.nil?
152
+
153
+ Cfer::Auster::Repo.new File.dirname(repo_file)
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,57 @@
1
+ module Cfer
2
+ module Auster
3
+ class ScriptExecutor
4
+ attr_reader :logger
5
+
6
+ def initialize(consts)
7
+ raise "consts must be a Hash" unless consts.is_a?(Hash)
8
+
9
+ vars = []
10
+ consts.each_pair do |k, v|
11
+ key_name = k.downcase.to_sym
12
+ vars << key_name
13
+ define_singleton_method(key_name) { v }
14
+ end
15
+
16
+ define_singleton_method(:vars) { vars }
17
+ end
18
+
19
+ def run(filename)
20
+ @logger = Logger.new(Cfer::Auster::Logging.logdev)
21
+ @logger.level = Cfer::Auster::Logging.logger.level
22
+
23
+ basename = File.basename(filename)
24
+ standard_formatter = Logger::Formatter.new
25
+
26
+ logger.formatter = proc do |severity, datetime, progname, msg|
27
+ standard_formatter.call(severity, datetime, progname, "> #{basename}: #{msg}")
28
+ end
29
+
30
+ instance_eval IO.read(filename), filename
31
+ end
32
+
33
+ private
34
+
35
+ def exports(export_plan_id = nil)
36
+ export_plan_id ||= plan_id
37
+
38
+ cfn_client = Aws::CloudFormation::Client.new(region: config_set.aws_region)
39
+
40
+ # this call isn't super fast, so we cache a little bit.
41
+ @exports ||= {}
42
+ @exports[export_plan_id] ||=
43
+ cfn_client.list_exports.exports.map do |cfn_export|
44
+ tokens = cfn_export.name.split("--", 2)
45
+
46
+ if tokens.length != 2 || tokens[0] != export_plan_id
47
+ nil
48
+ else
49
+ [tokens[1].to_sym, cfn_export.value]
50
+ end
51
+ end.reject(&:nil?).to_h
52
+
53
+ @exports[export_plan_id]
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "semantic"
4
+
5
+ module Cfer
6
+ module Auster
7
+ class Step
8
+ include Cfer::Auster::Logging::Mixin
9
+
10
+ attr_reader :repo
11
+
12
+ attr_reader :count
13
+ attr_reader :tag
14
+ attr_reader :directory
15
+
16
+ def initialize(repo:, count:, tag:, directory:)
17
+ raise "directory '#{directory}' does not exist." unless File.directory?(directory)
18
+ @repo = repo
19
+
20
+ @count = count.to_i
21
+ @tag = tag.dup.freeze
22
+
23
+ @directory = directory.dup.freeze
24
+
25
+ @cfer_directory = File.join(@directory, "cfer")
26
+ raise "directory '#{@cfer_directory}' does not exist." unless File.directory?(directory)
27
+ end
28
+
29
+ def json(config_set)
30
+ raise "config_set must be a Cfer::Auster::Config." unless config_set.is_a?(Cfer::Auster::Config)
31
+
32
+ with_cfer(config_set) do |cfer|
33
+ cfer.generate_json
34
+ end
35
+ end
36
+
37
+ def cfn_stack_name(config_set)
38
+ "#{config_set.name}-step#{count.to_s.rjust(2, '0')}"
39
+ end
40
+
41
+ def cfn_stack(config_set)
42
+ cfn_client = Aws::CloudFormation::Resource.new(region: config_set.aws_region)
43
+ cfn_client.stack(cfn_stack_name(config_set))
44
+ end
45
+
46
+ def cfn_data(config_set)
47
+ stack = cfn_stack(config_set)
48
+
49
+ if !stack.exists?
50
+ nil
51
+ else
52
+ cfn_parameters = stack.parameters.map { |p| [p.parameter_key, p.parameter_value] }.to_h
53
+ cfn_outputs = stack.outputs.map { |o| [o.output_key, o.output_value] }.to_h
54
+
55
+ cfn_combined = cfn_parameters.merge(cfn_outputs)
56
+
57
+ {
58
+ inputs: cfn_parameters.symbolize_keys,
59
+ outputs: cfn_outputs.symbolize_keys,
60
+ combined: cfn_combined.symbolize_keys
61
+ }
62
+ end
63
+ end
64
+
65
+ def run(config_set)
66
+ raise "config_set must be a Cfer::Auster::Config." unless config_set.is_a?(Cfer::Auster::Config)
67
+
68
+ with_cfer(config_set) do |cfer|
69
+ do_on_create(config_set) unless cfn_stack(config_set).exists?
70
+ do_pre_converge(config_set)
71
+
72
+ logger.info "Converging Cfer stack as '#{cfn_stack_name(config_set)}'."
73
+ cfer.converge!(block: true)
74
+
75
+ do_post_converge(config_set, cfn_data(config_set))
76
+ end
77
+ end
78
+
79
+ def destroy(config_set)
80
+ raise "config_set must be a Cfer::Auster::Config." unless config_set.is_a?(Cfer::Auster::Config)
81
+
82
+ stack_name = cfn_stack_name(config_set)
83
+ stack = cfn_stack(config_set)
84
+
85
+ if !stack.exists?
86
+ logger.warn "No underlying CloudFormation stack '#{stack_name}' exists."
87
+ else
88
+ logger.info "Deleting CloudFormation stack '#{stack_name}'."
89
+ with_cfer(config_set) do |cfer|
90
+ cfer.destroy!(block: true)
91
+ end
92
+
93
+ do_on_destroy(config_set)
94
+ end
95
+ end
96
+
97
+ private
98
+
99
+ def do_on_create(config_set)
100
+ run_scripts("on-create", config_set)
101
+ end
102
+
103
+ def do_on_destroy(config_set)
104
+ run_scripts("on-destroy", config_set)
105
+ end
106
+
107
+ def do_pre_converge(config_set)
108
+ run_scripts("pre-converge", config_set)
109
+ end
110
+
111
+ def do_post_converge(config_set, cfn_data)
112
+ run_scripts("post-converge", config_set, cfn_data: cfn_data)
113
+ end
114
+
115
+ def with_cfer(config_set, &block)
116
+ parameters = config_set.data
117
+ validation_errors = repo.param_validator.validate(parameters)
118
+
119
+ unless validation_errors.empty?
120
+ logger.error "Config set '#{config_set.full_name}' failed to validate with the following errors:"
121
+ validation_errors.each do |e|
122
+ logger.error " - #{e}"
123
+ end
124
+
125
+ raise "Validation of config set '#{config_set.full_name}' failed during Cfer build."
126
+ end
127
+
128
+ cfer = CferEvaluator.new(path: @cfer_directory, stack_name: cfn_stack_name(config_set),
129
+ parameters: parameters, metadata: stack_metadata)
130
+
131
+ block.call(cfer)
132
+ end
133
+
134
+ def stack_metadata
135
+ {
136
+ Version: Semantic::Version.new(Cfer::Auster::VERSION).to_h.reject { |k, v| v.nil? }
137
+ }
138
+ end
139
+
140
+ def converge_cfn(config_set)
141
+ end
142
+
143
+ def run_scripts(event_type, config_set, rb_vars = {})
144
+ logger.info "Running scripts for #{event_type}"
145
+ env_vars = config_set.env_vars_for_shell
146
+
147
+ injected_vars = env_vars.merge(rb_vars).merge(
148
+ repo: repo,
149
+ step: self,
150
+ config_set: config_set
151
+ )
152
+
153
+ scripts_for_event(event_type).each do |script_name|
154
+ case File.extname(script_name)
155
+ when ".rb"
156
+ logger.debug "Executing #{script_name} in-process."
157
+ Cfer::Auster::ScriptExecutor.new(injected_vars).run(script_name)
158
+ else
159
+ logger.debug "Executing #{script_name} through system()."
160
+ system(env_vars, script_name)
161
+
162
+ raise "#{script_name} failed with exit code #{$?.exitstatus}." unless $?.success?
163
+ end
164
+ end
165
+ end
166
+
167
+ def scripts_for_event(event_type)
168
+ dir = File.join(directory, "#{event_type}.d")
169
+
170
+ raise "#{dir} exists, but it isn't a directory.'" \
171
+ if File.exist?(dir) && !File.directory?(dir)
172
+
173
+ if !File.directory?(dir)
174
+ []
175
+ else
176
+ Dir[File.join(dir, "*")].select { |f| File.executable?(f) }
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,5 @@
1
+ module Cfer
2
+ module Auster
3
+ VERSION = "0.2.2".freeze
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ require "cfer/auster/version"
3
+
4
+ require "yaml"
5
+
6
+ require "active_support/all"
7
+ require "aws-sdk"
8
+ require "ice_nine"
9
+
10
+ module Cfer
11
+ module Auster
12
+ autoload :CferEvaluator, "cfer/auster/cfer_evaluator"
13
+ autoload :CferHelpers, "cfer/auster/cfer_helpers"
14
+ autoload :CLI, "cfer/auster/cli"
15
+ autoload :Config, "cfer/auster/config"
16
+ autoload :Logging, "cfer/auster/logging"
17
+ autoload :ParamValidator, "cfer/auster/param_validator"
18
+ autoload :Repo, "cfer/auster/repo"
19
+ autoload :ScriptExecutor, "cfer/auster/script_executor"
20
+ autoload :Step, "cfer/auster/step"
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,270 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: auster
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Ed Ropple
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: cri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.8.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.8.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: search_up
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.0.2
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.0.2
97
+ - !ruby/object:Gem::Dependency
98
+ name: activesupport
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 5.0.2
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 5.0.2
111
+ - !ruby/object:Gem::Dependency
112
+ name: ice_nine
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.11.2
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.11.2
125
+ - !ruby/object:Gem::Dependency
126
+ name: kwalify
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.7.2
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 0.7.2
139
+ - !ruby/object:Gem::Dependency
140
+ name: cfer
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.5.0
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.5.0
153
+ - !ruby/object:Gem::Dependency
154
+ name: semantic
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 1.6.0
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 1.6.0
167
+ - !ruby/object:Gem::Dependency
168
+ name: aws-sdk
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 2.9.11
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 2.9.11
181
+ description:
182
+ email:
183
+ - ed+auster@edropple.com
184
+ executables:
185
+ - auster
186
+ extensions: []
187
+ extra_rdoc_files: []
188
+ files:
189
+ - ".editorconfig"
190
+ - ".gitignore"
191
+ - ".rspec"
192
+ - ".rubocop.yml"
193
+ - ".travis.yml"
194
+ - CODE_OF_CONDUCT.md
195
+ - Gemfile
196
+ - LICENSE.txt
197
+ - README.md
198
+ - Rakefile
199
+ - auster.gemspec
200
+ - bin/auster
201
+ - bin/console
202
+ - example-repo/.auster.yaml
203
+ - example-repo/cfer-helpers/.keep
204
+ - example-repo/config/.keep
205
+ - example-repo/config/schema.yaml
206
+ - example-repo/config/us-west-2/dev-ed1.yaml
207
+ - example-repo/config/validator.rb
208
+ - example-repo/steps/.keep
209
+ - example-repo/steps/00.bootstrap/.keep
210
+ - example-repo/steps/00.bootstrap/cfer/defs/s3.rb
211
+ - example-repo/steps/00.bootstrap/cfer/outputs.rb
212
+ - example-repo/steps/00.bootstrap/cfer/parameters.rb
213
+ - example-repo/steps/00.bootstrap/cfer/require.rb
214
+ - example-repo/steps/00.bootstrap/on-create.d/00-debug.rb
215
+ - example-repo/steps/00.bootstrap/on-destroy.d/00-debug.rb
216
+ - example-repo/steps/00.bootstrap/post-converge.d/00-debug.rb
217
+ - example-repo/steps/00.bootstrap/pre-converge.d/00-debug.rb
218
+ - example-repo/steps/01.dependent/.keep
219
+ - example-repo/steps/01.dependent/cfer/defs/s3.rb
220
+ - example-repo/steps/01.dependent/cfer/outputs.rb
221
+ - example-repo/steps/01.dependent/cfer/parameters.rb
222
+ - example-repo/steps/01.dependent/cfer/require.rb
223
+ - example-repo/steps/01.dependent/on-create.d/00-debug.rb
224
+ - example-repo/steps/01.dependent/on-destroy.d/00-debug.rb
225
+ - example-repo/steps/01.dependent/post-converge.d/00-debug.rb
226
+ - example-repo/steps/01.dependent/pre-converge.d/00-debug.rb
227
+ - lib/cfer/auster.rb
228
+ - lib/cfer/auster/cfer_evaluator.rb
229
+ - lib/cfer/auster/cfer_helpers.rb
230
+ - lib/cfer/auster/cli.rb
231
+ - lib/cfer/auster/cli/_shared.rb
232
+ - lib/cfer/auster/cli/destroy.rb
233
+ - lib/cfer/auster/cli/generate.rb
234
+ - lib/cfer/auster/cli/generate/repo.rb
235
+ - lib/cfer/auster/cli/generate/step.rb
236
+ - lib/cfer/auster/cli/json.rb
237
+ - lib/cfer/auster/cli/nuke.rb
238
+ - lib/cfer/auster/cli/run.rb
239
+ - lib/cfer/auster/config.rb
240
+ - lib/cfer/auster/logging.rb
241
+ - lib/cfer/auster/param_validator.rb
242
+ - lib/cfer/auster/repo.rb
243
+ - lib/cfer/auster/script_executor.rb
244
+ - lib/cfer/auster/step.rb
245
+ - lib/cfer/auster/version.rb
246
+ homepage: https://github.com/eropple/auster
247
+ licenses:
248
+ - MIT
249
+ metadata: {}
250
+ post_install_message:
251
+ rdoc_options: []
252
+ require_paths:
253
+ - lib
254
+ required_ruby_version: !ruby/object:Gem::Requirement
255
+ requirements:
256
+ - - ">="
257
+ - !ruby/object:Gem::Version
258
+ version: '0'
259
+ required_rubygems_version: !ruby/object:Gem::Requirement
260
+ requirements:
261
+ - - ">="
262
+ - !ruby/object:Gem::Version
263
+ version: '0'
264
+ requirements: []
265
+ rubyforge_project:
266
+ rubygems_version: 2.5.1
267
+ signing_key:
268
+ specification_version: 4
269
+ summary: Best-practices tooling for CloudFormation and AWS.
270
+ test_files: []