auster 0.2.2

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 (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: []