terraspace 0.3.4 → 0.3.5
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +1 -1
- data/lib/terraspace/all/preview.rb +1 -1
- data/lib/terraspace/compiler/dependencies/helpers.rb +34 -0
- data/lib/terraspace/compiler/dsl/syntax/helpers/common.rb +0 -26
- data/lib/terraspace/compiler/dsl/syntax/tfvar.rb +1 -0
- data/lib/terraspace/compiler/erb/context.rb +1 -1
- data/lib/terraspace/compiler/erb/helpers.rb +6 -0
- data/lib/terraspace/dependency/helper/base.rb +7 -0
- data/lib/terraspace/dependency/helper/depends_on.rb +12 -0
- data/lib/terraspace/dependency/helper/output.rb +11 -0
- data/lib/terraspace/terraform/remote_state/fetcher.rb +13 -4
- data/lib/terraspace/terraform/remote_state/marker/output.rb +3 -1
- data/lib/terraspace/terraform/remote_state/null_object.rb +40 -0
- data/lib/terraspace/terraform/remote_state/output_proxy.rb +18 -14
- data/lib/terraspace/version.rb +1 -1
- data/spec/fixtures/dependencies/app/stacks/a1/tfvars/dev.tfvars +1 -0
- data/spec/fixtures/fetcher/c1.json +4 -0
- data/spec/terraspace/compiler/erb/render_spec.rb +15 -0
- data/spec/terraspace/dependency/helper/depends_on_spec.rb +27 -0
- data/spec/terraspace/dependency/helper/output_spec.rb +29 -0
- data/spec/terraspace/terraform/remote_state/fetcher_spec.rb +108 -27
- data/spec/terraspace/terraform/remote_state/marker/output_spec.rb +36 -0
- data/spec/terraspace/terraform/remote_state/output_proxy_spec.rb +69 -0
- metadata +20 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7bb02485a9ee2b429e36b562fc8ba36946472776c1cabd234db2d0fd210c830b
|
|
4
|
+
data.tar.gz: 972a0074d2528352bfcb596f608e883fb47a673202db1a00ef6de25d6d63408f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 06c10d199374f6d9b1ceac52f89fddc1b3b57402037e212e357622e7647c37a31959098cde5ecbee9f42b501f792bab85b702641bbb3ae692fe86b8e96fbdb07
|
|
7
|
+
data.tar.gz: 8b8e1cf28734fc14ac8e4aa27ba626bb82f5f685ac39688f737ceacfdf6fcfef59ac7a4198292ce41b314d3b73faed166c50bc22ebb00a05d0b305d195160053
|
data/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
|
|
5
5
|
|
|
6
|
+
## [0.3.5]
|
|
7
|
+
* #43 rename `terraform_output` helper to `output`. Keep `terraform_output` for backwards compatibility
|
|
8
|
+
* to_ruby natural interface to access output with full power of Ruby
|
|
9
|
+
* output formatters removed in favor for `.to_ruby` method.
|
|
10
|
+
|
|
6
11
|
## [0.3.4]
|
|
7
12
|
* #42 update cli docs and bug fixes
|
|
8
13
|
* fix console by using system instead of popen3
|
data/README.md
CHANGED
|
@@ -81,7 +81,7 @@ To choose multiple stacks to deploy
|
|
|
81
81
|
|
|
82
82
|
terraspace all up instance vpc
|
|
83
83
|
|
|
84
|
-
When you use the all command, the dependency graph is calculated and the stacks are deployed in the right order. To learn more: [Deploy Multiple Stacks](https://terraspace.cloud/docs/
|
|
84
|
+
When you use the all command, the dependency graph is calculated and the stacks are deployed in the right order. To learn more: [Deploy Multiple Stacks](https://terraspace.cloud/docs/intro/deploy-all/).
|
|
85
85
|
|
|
86
86
|
## Features
|
|
87
87
|
|
|
@@ -22,7 +22,7 @@ module Terraspace::All
|
|
|
22
22
|
@batches.map do |batch|
|
|
23
23
|
i += 1
|
|
24
24
|
batch.map do |stack|
|
|
25
|
-
command = "
|
|
25
|
+
command = " terraspace #{@command}"
|
|
26
26
|
ljust = command.size + max_name_size + 1
|
|
27
27
|
command = "#{command} #{stack.name}"
|
|
28
28
|
command.ljust(ljust, ' ') + " # batch #{i}"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Terraspace::Compiler::Dependencies
|
|
2
|
+
# This is a separate module specifically because the DSL also has an output method.
|
|
3
|
+
# The module allows us to include dependency related methods only within tfvars context for the DSL.
|
|
4
|
+
#
|
|
5
|
+
# 1. Only include this module to DSL tfvars context.
|
|
6
|
+
# So the output method works in tfvars .rb files works.
|
|
7
|
+
# At the same time, the DSL usage of output also works for normal main.tf files.
|
|
8
|
+
# Passing specs prove this.
|
|
9
|
+
# 2. For ERB, there's currently only one ERB context. So this module is included in all contexts.
|
|
10
|
+
# The builder only processes dependencies from tfvars, so these helpers are only respected there.
|
|
11
|
+
#
|
|
12
|
+
# Where the module is included in the code:
|
|
13
|
+
#
|
|
14
|
+
# 1. lib/terraspace/compiler/dsl/syntax/tfvar.rb
|
|
15
|
+
# 2. lib/terraspace/compiler/erb/helpers.rb
|
|
16
|
+
#
|
|
17
|
+
module Helpers
|
|
18
|
+
def output(identifier, options={})
|
|
19
|
+
Terraspace::Dependency::Helper::Output.new(@mod, identifier, options).result
|
|
20
|
+
end
|
|
21
|
+
alias_method :terraform_output, :output # backwards compatibility
|
|
22
|
+
|
|
23
|
+
def depends_on(*child_names, **options)
|
|
24
|
+
child_names.flatten!
|
|
25
|
+
child_names.map do |child_name|
|
|
26
|
+
each_depends_on(child_name, options)
|
|
27
|
+
end.join("\n")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def each_depends_on(child_name, options={})
|
|
31
|
+
Terraspace::Dependency::Helper::DependsOn.new(@mod, child_name, options).result
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
module Terraspace::Compiler::Dsl::Syntax::Helpers
|
|
2
2
|
module Common
|
|
3
3
|
extend Memoist
|
|
4
|
-
Fetcher = Terraspace::Terraform::RemoteState::Fetcher
|
|
5
|
-
Marker = Terraspace::Terraform::RemoteState::Marker
|
|
6
4
|
Meta = Terraspace::Compiler::Dsl::Meta
|
|
7
5
|
|
|
8
6
|
def var
|
|
@@ -25,29 +23,5 @@ module Terraspace::Compiler::Dsl::Syntax::Helpers
|
|
|
25
23
|
command = ["terraspace"] + args
|
|
26
24
|
command.join(separator)
|
|
27
25
|
end
|
|
28
|
-
|
|
29
|
-
def terraform_output(identifier, options={})
|
|
30
|
-
if @mod.resolved # dependencies have been resolved
|
|
31
|
-
Fetcher.new(@mod, identifier, options).output
|
|
32
|
-
else
|
|
33
|
-
Marker::Output.new(@mod, identifier, options).build
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def depends_on(*child_names, **options)
|
|
38
|
-
child_names.flatten!
|
|
39
|
-
child_names.map do |child_name|
|
|
40
|
-
each_depends_on(child_name, options)
|
|
41
|
-
end.join("\n")
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def each_depends_on(child_name, options={})
|
|
45
|
-
if @mod.resolved # dependencies have been resolved
|
|
46
|
-
# Note: A generated line is not really needed. Dependencies are stored in memory. Added to assist users with debugging
|
|
47
|
-
"# #{@mod.name} depends on #{child_name}"
|
|
48
|
-
else
|
|
49
|
-
Marker::Output.new(@mod, child_name, options).build
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
26
|
end
|
|
53
27
|
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Terraspace::Dependency::Helper
|
|
2
|
+
class DependsOn < Base
|
|
3
|
+
def result
|
|
4
|
+
if @mod.resolved # dependencies have been resolved
|
|
5
|
+
# Note: A generated line is not really needed. Dependencies are stored in memory. Added to assist users with debugging
|
|
6
|
+
"# #{@mod.name} depends on #{@identifier}" # raw String value
|
|
7
|
+
else
|
|
8
|
+
Terraspace::Terraform::RemoteState::Marker::Output.new(@mod, @identifier, @options).build # Returns OutputProxy which defaults to json
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Terraspace::Dependency::Helper
|
|
2
|
+
class Output < Base
|
|
3
|
+
def result
|
|
4
|
+
if @mod.resolved # dependencies have been resolved
|
|
5
|
+
Terraspace::Terraform::RemoteState::Fetcher.new(@mod, @identifier, @options).output # Returns OutputProxy which defaults to json
|
|
6
|
+
else
|
|
7
|
+
Terraspace::Terraform::RemoteState::Marker::Output.new(@mod, @identifier, @options).build # Returns OutputProxy is NullObject when unresolved
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -8,6 +8,7 @@ module Terraspace::Terraform::RemoteState
|
|
|
8
8
|
@parent, @identifier, @options = parent, identifier, options
|
|
9
9
|
child_name, @output_key = identifier.split('.')
|
|
10
10
|
@child = Terraspace::Mod.new(child_name)
|
|
11
|
+
@child.resolved = @parent.resolved
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
def run
|
|
@@ -16,16 +17,24 @@ module Terraspace::Terraform::RemoteState
|
|
|
16
17
|
load
|
|
17
18
|
end
|
|
18
19
|
|
|
20
|
+
# Returns OutputProxy
|
|
19
21
|
def output
|
|
20
22
|
run
|
|
21
23
|
if pull_success?
|
|
22
|
-
|
|
23
|
-
error = output_error(:key_not_found) unless @outputs.key?(@output_key)
|
|
24
|
-
OutputProxy.new(value, @options.merge(error: error))
|
|
24
|
+
pull_success_output
|
|
25
25
|
else
|
|
26
26
|
@error_type ||= :state_not_found # could be set to :bucket_not_found by bucket_not_found_error
|
|
27
27
|
error = output_error(@error_type)
|
|
28
|
-
OutputProxy.new(nil, @options.merge(error: error))
|
|
28
|
+
OutputProxy.new(@child, nil, @options.merge(error: error))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def pull_success_output
|
|
33
|
+
if @outputs.key?(@output_key)
|
|
34
|
+
OutputProxy.new(@child, output_value, @options)
|
|
35
|
+
else
|
|
36
|
+
error = output_error(:key_not_found)
|
|
37
|
+
OutputProxy.new(@child, nil, @options.merge(error: error))
|
|
29
38
|
end
|
|
30
39
|
end
|
|
31
40
|
|
|
@@ -8,6 +8,7 @@ module Terraspace::Terraform::RemoteState::Marker
|
|
|
8
8
|
@child_name, @output_key = @identifier.split('.')
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
# Returns OutputProxy
|
|
11
12
|
def build
|
|
12
13
|
if valid?
|
|
13
14
|
Terraspace::Dependency::Registry.register(@parent_name, @child_name)
|
|
@@ -16,7 +17,7 @@ module Terraspace::Terraform::RemoteState::Marker
|
|
|
16
17
|
end
|
|
17
18
|
# MARKER for debugging. Only appears on 1st pass. Will not see unless changing Terraspace code for debugging.
|
|
18
19
|
marker = "MARKER:terraform_output('#{@identifier}')"
|
|
19
|
-
Terraspace::Terraform::RemoteState::OutputProxy.new(marker, @options)
|
|
20
|
+
Terraspace::Terraform::RemoteState::OutputProxy.new(@mod, marker, @options)
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
def valid?
|
|
@@ -26,6 +27,7 @@ module Terraspace::Terraform::RemoteState::Marker
|
|
|
26
27
|
def warning
|
|
27
28
|
logger.warn "WARN: The #{@child_name} stack does not exist".color(:yellow)
|
|
28
29
|
caller_line = caller.find { |l| l.include?('.tfvars') }
|
|
30
|
+
return unless caller_line # specs dont have a tfvars file
|
|
29
31
|
source_code = PrettyTracer.new(caller_line).source_code
|
|
30
32
|
logger.info source_code
|
|
31
33
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Terraspace::Terraform::RemoteState
|
|
2
|
+
class NullObject
|
|
3
|
+
def to_a
|
|
4
|
+
[]
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def to_ary
|
|
8
|
+
[]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_s
|
|
12
|
+
"(unresolved)" # always returned as part of first unresolved processing pass
|
|
13
|
+
end
|
|
14
|
+
alias_method :to_str, :to_s # ERB requires to_str
|
|
15
|
+
|
|
16
|
+
def to_f
|
|
17
|
+
0.0
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def to_i
|
|
21
|
+
0
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def nil?
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def inspect
|
|
29
|
+
format("#<%s:0x%x>", self.class, object_id)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def method_missing(*_args, &_block)
|
|
33
|
+
self
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def respond_to?(_message, _include_private = false)
|
|
37
|
+
true
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
module Terraspace::Terraform::RemoteState
|
|
2
2
|
class OutputProxy
|
|
3
3
|
# raw: can be anything: String, Array, Hash, etc
|
|
4
|
-
# options: original options passed by user
|
|
4
|
+
# options: original options passed by user from the output helper in tfvars
|
|
5
5
|
attr_reader :raw, :options
|
|
6
|
-
def initialize(raw, options={})
|
|
7
|
-
@raw, @options = raw, options
|
|
6
|
+
def initialize(mod, raw, options={})
|
|
7
|
+
@mod, @raw, @options = mod, raw, options
|
|
8
8
|
@format = @options[:format]
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
# Should always return a String
|
|
12
12
|
def to_s
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
if @mod.resolved
|
|
14
|
+
# Dont use NullObject wrapper because Integer get changed to Strings.
|
|
15
|
+
# Want raw value to be used for the to_json call
|
|
16
|
+
value = @raw.nil? ? mock_or_error : @raw
|
|
17
|
+
value.to_json
|
|
18
|
+
else
|
|
19
|
+
NullObject.new # to_s => (unresolved)
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
def
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
def to_ruby
|
|
24
|
+
data = @raw.nil? ? mock_or_error : @raw
|
|
25
|
+
@mod.resolved ? data : NullObject.new
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
def mock_or_error
|
|
30
|
+
@options[:mock] || @options[:error]
|
|
27
31
|
end
|
|
28
32
|
end
|
|
29
33
|
end
|
data/lib/terraspace/version.rb
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
length = <%= output('b1.length') %>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
describe Terraspace::Compiler::Erb::Render do
|
|
2
|
+
let(:render) { described_class.new(mod, src_path) }
|
|
3
|
+
let(:mod) { Terraspace::Mod.new("a1") }
|
|
4
|
+
|
|
5
|
+
# Only testing mod unresolved as a sanity check and its worth the ROI.
|
|
6
|
+
# The resolved would the Fetcher. We have unit tests to cover those other changes.
|
|
7
|
+
context "a1" do
|
|
8
|
+
let(:src_path) { fixture("dependencies/app/stacks/a1/tfvars/dev.tfvars") }
|
|
9
|
+
it "build" do
|
|
10
|
+
allow(Terraspace::Terraform::RemoteState::Marker::Output).to receive(:stack_names).and_return("b1")
|
|
11
|
+
result = render.build
|
|
12
|
+
expect(result).to eq "length = (unresolved)"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
describe Terraspace::Dependency::Helper::DependsOn do
|
|
2
|
+
let(:depends_on) do
|
|
3
|
+
described_class.new(mod, identifier, options)
|
|
4
|
+
end
|
|
5
|
+
let (:mod) { Terraspace::Mod.new("a1") }
|
|
6
|
+
# follow args dont matter for spec
|
|
7
|
+
let (:identifier) { "b1" }
|
|
8
|
+
let (:options) { {} }
|
|
9
|
+
|
|
10
|
+
context "unresolved" do
|
|
11
|
+
before(:each) { mod.resolved = false }
|
|
12
|
+
it "result calls Marker::Output" do
|
|
13
|
+
allow(Terraspace::Terraform::RemoteState::Marker::Output).to receive(:new).and_return(double(:marker_output).as_null_object)
|
|
14
|
+
result = depends_on.result
|
|
15
|
+
expect(result).to be_a(RSpec::Mocks::Double)
|
|
16
|
+
expect(result.instance_variable_get(:@name)).to eq :marker_output
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context "resolved" do
|
|
21
|
+
before(:each) { mod.resolved = true }
|
|
22
|
+
it "return an raw String" do
|
|
23
|
+
result = depends_on.result
|
|
24
|
+
expect(result).to eq "# a1 depends on b1"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
describe Terraspace::Dependency::Helper::Output do
|
|
2
|
+
let(:output) do
|
|
3
|
+
described_class.new(mod, identifier, options)
|
|
4
|
+
end
|
|
5
|
+
let (:mod) { Terraspace::Mod.new("foo") }
|
|
6
|
+
# doesnt matter for spec
|
|
7
|
+
let (:identifier) { nil }
|
|
8
|
+
let (:options) { nil }
|
|
9
|
+
|
|
10
|
+
context "unresolved" do
|
|
11
|
+
before(:each) { mod.resolved = false }
|
|
12
|
+
it "result calls Marker::Output" do
|
|
13
|
+
allow(Terraspace::Terraform::RemoteState::Marker::Output).to receive(:new).and_return(double(:marker_output).as_null_object)
|
|
14
|
+
result = output.result
|
|
15
|
+
expect(result).to be_a(RSpec::Mocks::Double)
|
|
16
|
+
expect(result.instance_variable_get(:@name)).to eq :marker_output
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context "resolved" do
|
|
21
|
+
before(:each) { mod.resolved = true }
|
|
22
|
+
it "result calls Fetcher" do
|
|
23
|
+
allow(Terraspace::Terraform::RemoteState::Fetcher).to receive(:new).and_return(double(:fetcher_output).as_null_object)
|
|
24
|
+
result = output.result
|
|
25
|
+
expect(result).to be_a(RSpec::Mocks::Double)
|
|
26
|
+
expect(result.instance_variable_get(:@name)).to eq :fetcher_output
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -11,41 +11,122 @@ describe Terraspace::Terraform::RemoteState::Fetcher do
|
|
|
11
11
|
double("c1").as_null_object
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
context "
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
context "to_s uses to_json by default" do
|
|
15
|
+
context "pull success" do
|
|
16
|
+
let(:state_path) { "spec/fixtures/fetcher/c1.json" }
|
|
17
|
+
let(:pull_success) { true }
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
context "c1.length" do
|
|
20
|
+
let(:identifier) { "c1.length" }
|
|
21
|
+
it "fetched found attribute" do
|
|
22
|
+
expect(fetcher.output.to_s).to eq '1' # Integer as json matches spec/fixtures/fetcher/c1.json outputs.length.value
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context "c1.complex" do
|
|
27
|
+
let(:identifier) { "c1.complex" }
|
|
28
|
+
it "fetched found attribute" do
|
|
29
|
+
expect(fetcher.output.to_s).to eq ["a","b"].to_json # matches spec/fixtures/fetcher/c1.json outputs.complex.value
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "c1.does-not-exist" do
|
|
34
|
+
let(:identifier) { "c1.does-not-exist" }
|
|
35
|
+
it "fetched missing output" do
|
|
36
|
+
output_proxy = fetcher.output
|
|
37
|
+
expect(output_proxy.raw).to be nil
|
|
38
|
+
value = output_proxy.to_s
|
|
39
|
+
# (Output length9 was not found for the b1 tfvars file. Either c1 stack has not been deployed yet or it does not have this output: length9)
|
|
40
|
+
expect(value).to include "not found"
|
|
41
|
+
end
|
|
22
42
|
end
|
|
23
43
|
end
|
|
24
44
|
|
|
25
|
-
context "
|
|
26
|
-
let(:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
45
|
+
context "pull fail" do
|
|
46
|
+
let(:state_path) { nil }
|
|
47
|
+
let(:pull_success) { false }
|
|
48
|
+
|
|
49
|
+
context "stack needs to be deployed" do
|
|
50
|
+
let(:identifier) { "c1.length" }
|
|
51
|
+
it "fetched" do
|
|
52
|
+
output_proxy = fetcher.output
|
|
53
|
+
expect(output_proxy.raw).to be nil
|
|
54
|
+
# (Output length could not be looked up for the b1 tfvars file. c1 stack needs to be deployed)
|
|
55
|
+
value = output_proxy.to_s
|
|
56
|
+
expect(value).to include "stack needs to be deployed"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context "bucket does not exist" do
|
|
61
|
+
let(:identifier) { "c1.length" }
|
|
62
|
+
it "fetched" do
|
|
63
|
+
fetcher.bucket_not_found_error # fake it!
|
|
64
|
+
output_proxy = fetcher.output
|
|
65
|
+
expect(output_proxy.raw).to be nil
|
|
66
|
+
# (Output length could not be looked up for the b1 tfvars file. c1 stack needs to be deployed)
|
|
67
|
+
value = output_proxy.to_s
|
|
68
|
+
expect(value).to include "bucket for the backend could not be found"
|
|
69
|
+
end
|
|
33
70
|
end
|
|
34
71
|
end
|
|
35
72
|
end
|
|
36
73
|
|
|
37
|
-
context "
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
74
|
+
context "to_ruby" do
|
|
75
|
+
context "pull success" do
|
|
76
|
+
let(:state_path) { "spec/fixtures/fetcher/c1.json" }
|
|
77
|
+
let(:pull_success) { true }
|
|
78
|
+
|
|
79
|
+
context "c1.length" do
|
|
80
|
+
let(:identifier) { "c1.length" }
|
|
81
|
+
it "fetched found attribute" do
|
|
82
|
+
expect(fetcher.output.to_ruby).to eq 1 # raw Integer
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context "c1.complex" do
|
|
87
|
+
let(:identifier) { "c1.complex" }
|
|
88
|
+
it "fetched found attribute" do
|
|
89
|
+
expect(fetcher.output.to_ruby).to eq ["a","b"] # raw Array
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
context "c1.does-not-exist" do
|
|
94
|
+
let(:identifier) { "c1.does-not-exist" }
|
|
95
|
+
it "fetched missing output" do
|
|
96
|
+
output_proxy = fetcher.output
|
|
97
|
+
expect(output_proxy.raw).to be nil
|
|
98
|
+
value = output_proxy.to_ruby
|
|
99
|
+
# (Output length9 was not found for the b1 tfvars file. Either c1 stack has not been deployed yet or it does not have this output: length9)
|
|
100
|
+
expect(value).to include "not found"
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
context "pull fail" do
|
|
106
|
+
let(:state_path) { nil }
|
|
107
|
+
let(:pull_success) { false }
|
|
108
|
+
|
|
109
|
+
context "stack needs to be deployed" do
|
|
110
|
+
let(:identifier) { "c1.length" }
|
|
111
|
+
it "fetched" do
|
|
112
|
+
output_proxy = fetcher.output
|
|
113
|
+
expect(output_proxy.raw).to be nil
|
|
114
|
+
# (Output length could not be looked up for the b1 tfvars file. c1 stack needs to be deployed)
|
|
115
|
+
value = output_proxy.to_s
|
|
116
|
+
expect(value).to include "stack needs to be deployed"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
context "bucket does not exist" do
|
|
121
|
+
let(:identifier) { "c1.length" }
|
|
122
|
+
it "fetched" do
|
|
123
|
+
fetcher.bucket_not_found_error # fake it!
|
|
124
|
+
output_proxy = fetcher.output
|
|
125
|
+
expect(output_proxy.raw).to be nil
|
|
126
|
+
# (Output length could not be looked up for the b1 tfvars file. c1 stack needs to be deployed)
|
|
127
|
+
value = output_proxy.to_s
|
|
128
|
+
expect(value).to include "bucket for the backend could not be found"
|
|
129
|
+
end
|
|
49
130
|
end
|
|
50
131
|
end
|
|
51
132
|
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
describe Terraspace::Terraform::RemoteState::Marker::Output do
|
|
2
|
+
let(:output) do
|
|
3
|
+
output = described_class.new(mod, identifier, options)
|
|
4
|
+
allow(output).to receive(:warning) # supress warning messaging about missing child stack
|
|
5
|
+
output
|
|
6
|
+
end
|
|
7
|
+
let (:mod) { Terraspace::Mod.new("a1") }
|
|
8
|
+
let (:options) { {} }
|
|
9
|
+
|
|
10
|
+
before(:each) do
|
|
11
|
+
Terraspace::Dependency::Registry.class_variable_set("@@data", Set.new)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# markers are always only called during unresolved stage
|
|
15
|
+
context "child stack found" do
|
|
16
|
+
let(:identifier) { "b1.length" }
|
|
17
|
+
it "registers dependency and always return a OutputProxy" do
|
|
18
|
+
allow(output).to receive(:valid?).and_return(true) # child stack found
|
|
19
|
+
result = output.build
|
|
20
|
+
expect(result).to be_a(Terraspace::Terraform::RemoteState::OutputProxy)
|
|
21
|
+
set = Terraspace::Dependency::Registry.data
|
|
22
|
+
expect(set).not_to be_empty
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context "child stack not found" do
|
|
27
|
+
let(:identifier) { "b1.length" }
|
|
28
|
+
it "does not registers dependency and always return a OutputProxy" do
|
|
29
|
+
allow(output).to receive(:valid?).and_return(false) # child stack not found
|
|
30
|
+
result = output.build
|
|
31
|
+
expect(result).to be_a(Terraspace::Terraform::RemoteState::OutputProxy)
|
|
32
|
+
set = Terraspace::Dependency::Registry.data
|
|
33
|
+
expect(set).to be_empty
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
NullObject = Terraspace::Terraform::RemoteState::NullObject
|
|
2
|
+
|
|
3
|
+
describe Terraspace::Terraform::RemoteState::OutputProxy do
|
|
4
|
+
let(:proxy) do
|
|
5
|
+
described_class.new(mod, raw, options)
|
|
6
|
+
end
|
|
7
|
+
let (:mod) { Terraspace::Mod.new("foo") }
|
|
8
|
+
let (:raw) { nil }
|
|
9
|
+
let (:options) { {} }
|
|
10
|
+
|
|
11
|
+
context "unresolved" do
|
|
12
|
+
before(:each) { mod.resolved = false }
|
|
13
|
+
it "always return NullObject" do
|
|
14
|
+
value = proxy.to_s
|
|
15
|
+
expect(value).to be_a(NullObject)
|
|
16
|
+
expect(value.to_str).to eq "(unresolved)"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Resolved value should always return a String because ERB requires string.
|
|
21
|
+
# Always use to_json.
|
|
22
|
+
context "resolved with mock" do
|
|
23
|
+
before(:each) { mod.resolved = true }
|
|
24
|
+
let (:raw) { nil }
|
|
25
|
+
let (:options) { {mock: "mock value"} }
|
|
26
|
+
|
|
27
|
+
it "return to_json String with mock value" do
|
|
28
|
+
value = proxy.to_s
|
|
29
|
+
expect(value).to be_a(String)
|
|
30
|
+
expect(value.to_str).to eq '"mock value"' # note double quotes from the to_json
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "resolved with errors" do
|
|
35
|
+
before(:each) { mod.resolved = true }
|
|
36
|
+
let (:raw) { nil }
|
|
37
|
+
let (:options) { {error: "error message"} }
|
|
38
|
+
|
|
39
|
+
it "return to_json String with error message" do
|
|
40
|
+
value = proxy.to_s
|
|
41
|
+
expect(value).to be_a(String)
|
|
42
|
+
expect(value.to_str).to eq '"error message"' # note double quotes from the to_json
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context "to_ruby resolved with mock" do
|
|
47
|
+
before(:each) { mod.resolved = true }
|
|
48
|
+
let (:raw) { nil }
|
|
49
|
+
let (:options) { {mock: "mock value"} }
|
|
50
|
+
|
|
51
|
+
it "return to_json String with mock value" do
|
|
52
|
+
value = proxy.to_ruby
|
|
53
|
+
expect(value).to be_a(String)
|
|
54
|
+
expect(value.to_str).to eq "mock value"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "to_ruby resolved with errors" do
|
|
59
|
+
before(:each) { mod.resolved = true }
|
|
60
|
+
let (:raw) { nil }
|
|
61
|
+
let (:options) { {error: "error message"} }
|
|
62
|
+
|
|
63
|
+
it "return to_json String with error message" do
|
|
64
|
+
value = proxy.to_ruby
|
|
65
|
+
expect(value).to be_a(String)
|
|
66
|
+
expect(value.to_str).to eq "error message"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: terraspace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tung Nguyen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-09-
|
|
11
|
+
date: 2020-09-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -561,6 +561,7 @@ files:
|
|
|
561
561
|
- lib/terraspace/compiler/cleaner.rb
|
|
562
562
|
- lib/terraspace/compiler/cleaner/backend_change.rb
|
|
563
563
|
- lib/terraspace/compiler/commands_concern.rb
|
|
564
|
+
- lib/terraspace/compiler/dependencies/helpers.rb
|
|
564
565
|
- lib/terraspace/compiler/dirs_concern.rb
|
|
565
566
|
- lib/terraspace/compiler/dsl/base.rb
|
|
566
567
|
- lib/terraspace/compiler/dsl/meta/local.rb
|
|
@@ -581,6 +582,7 @@ files:
|
|
|
581
582
|
- lib/terraspace/compiler/dsl/syntax/tfvar/common.rb
|
|
582
583
|
- lib/terraspace/compiler/dsl/tfvars.rb
|
|
583
584
|
- lib/terraspace/compiler/erb/context.rb
|
|
585
|
+
- lib/terraspace/compiler/erb/helpers.rb
|
|
584
586
|
- lib/terraspace/compiler/erb/render.rb
|
|
585
587
|
- lib/terraspace/compiler/expander.rb
|
|
586
588
|
- lib/terraspace/compiler/strategy/abstract_base.rb
|
|
@@ -600,6 +602,9 @@ files:
|
|
|
600
602
|
- lib/terraspace/completer/script.sh
|
|
601
603
|
- lib/terraspace/core.rb
|
|
602
604
|
- lib/terraspace/dependency/graph.rb
|
|
605
|
+
- lib/terraspace/dependency/helper/base.rb
|
|
606
|
+
- lib/terraspace/dependency/helper/depends_on.rb
|
|
607
|
+
- lib/terraspace/dependency/helper/output.rb
|
|
603
608
|
- lib/terraspace/dependency/node.rb
|
|
604
609
|
- lib/terraspace/dependency/registry.rb
|
|
605
610
|
- lib/terraspace/ext.rb
|
|
@@ -655,6 +660,7 @@ files:
|
|
|
655
660
|
- lib/terraspace/terraform/remote_state/fetcher.rb
|
|
656
661
|
- lib/terraspace/terraform/remote_state/marker/output.rb
|
|
657
662
|
- lib/terraspace/terraform/remote_state/marker/pretty_tracer.rb
|
|
663
|
+
- lib/terraspace/terraform/remote_state/null_object.rb
|
|
658
664
|
- lib/terraspace/terraform/remote_state/output_proxy.rb
|
|
659
665
|
- lib/terraspace/terraform/runner.rb
|
|
660
666
|
- lib/terraspace/tester.rb
|
|
@@ -667,6 +673,7 @@ files:
|
|
|
667
673
|
- lib/terraspace/version.rb
|
|
668
674
|
- spec/cli_spec.rb
|
|
669
675
|
- spec/fixtures/cache_dir/variables.tf
|
|
676
|
+
- spec/fixtures/dependencies/app/stacks/a1/tfvars/dev.tfvars
|
|
670
677
|
- spec/fixtures/fetcher/c1.json
|
|
671
678
|
- spec/fixtures/initialized/modules.json
|
|
672
679
|
- spec/fixtures/orphans/config/backend.rb
|
|
@@ -780,13 +787,18 @@ files:
|
|
|
780
787
|
- spec/terraspace/compiler/dsl/resource_spec.rb
|
|
781
788
|
- spec/terraspace/compiler/dsl/terraform_spec.rb
|
|
782
789
|
- spec/terraspace/compiler/dsl/variable_spec.rb
|
|
790
|
+
- spec/terraspace/compiler/erb/render_spec.rb
|
|
783
791
|
- spec/terraspace/dependency/graph_spec.rb
|
|
792
|
+
- spec/terraspace/dependency/helper/depends_on_spec.rb
|
|
793
|
+
- spec/terraspace/dependency/helper/output_spec.rb
|
|
784
794
|
- spec/terraspace/provider/expander/generic_spec.rb
|
|
785
795
|
- spec/terraspace/seeder/content_spec.rb
|
|
786
796
|
- spec/terraspace/seeder_spec.rb
|
|
787
797
|
- spec/terraspace/terraform/args/custom_spec.rb
|
|
788
798
|
- spec/terraspace/terraform/hooks/builder_spec.rb
|
|
789
799
|
- spec/terraspace/terraform/remote_state/fetcher_spec.rb
|
|
800
|
+
- spec/terraspace/terraform/remote_state/marker/output_spec.rb
|
|
801
|
+
- spec/terraspace/terraform/remote_state/output_proxy_spec.rb
|
|
790
802
|
- terraspace.gemspec
|
|
791
803
|
homepage: https://github.com/boltops-tools/terraspace
|
|
792
804
|
licenses:
|
|
@@ -814,6 +826,7 @@ summary: 'Terraspace: The Terraspace Framework'
|
|
|
814
826
|
test_files:
|
|
815
827
|
- spec/cli_spec.rb
|
|
816
828
|
- spec/fixtures/cache_dir/variables.tf
|
|
829
|
+
- spec/fixtures/dependencies/app/stacks/a1/tfvars/dev.tfvars
|
|
817
830
|
- spec/fixtures/fetcher/c1.json
|
|
818
831
|
- spec/fixtures/initialized/modules.json
|
|
819
832
|
- spec/fixtures/orphans/config/backend.rb
|
|
@@ -927,10 +940,15 @@ test_files:
|
|
|
927
940
|
- spec/terraspace/compiler/dsl/resource_spec.rb
|
|
928
941
|
- spec/terraspace/compiler/dsl/terraform_spec.rb
|
|
929
942
|
- spec/terraspace/compiler/dsl/variable_spec.rb
|
|
943
|
+
- spec/terraspace/compiler/erb/render_spec.rb
|
|
930
944
|
- spec/terraspace/dependency/graph_spec.rb
|
|
945
|
+
- spec/terraspace/dependency/helper/depends_on_spec.rb
|
|
946
|
+
- spec/terraspace/dependency/helper/output_spec.rb
|
|
931
947
|
- spec/terraspace/provider/expander/generic_spec.rb
|
|
932
948
|
- spec/terraspace/seeder/content_spec.rb
|
|
933
949
|
- spec/terraspace/seeder_spec.rb
|
|
934
950
|
- spec/terraspace/terraform/args/custom_spec.rb
|
|
935
951
|
- spec/terraspace/terraform/hooks/builder_spec.rb
|
|
936
952
|
- spec/terraspace/terraform/remote_state/fetcher_spec.rb
|
|
953
|
+
- spec/terraspace/terraform/remote_state/marker/output_spec.rb
|
|
954
|
+
- spec/terraspace/terraform/remote_state/output_proxy_spec.rb
|