terraspace 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f265061c3973d32dcbea50e12b291ee22041dc2e5bc2cf2521907dd4d74b0703
4
- data.tar.gz: 97e6064b47fe37f11660fe05512e1750b23f96cd7bc7ea1bef0aa512884922de
3
+ metadata.gz: cfdfafd180a61f7e43131770457ffa446c8bae59d3db9e68c9b9a8930fa6ca88
4
+ data.tar.gz: 684480a5c4454ee457c5e236574ace9424a514d0822c2693190de41354aea40d
5
5
  SHA512:
6
- metadata.gz: bb0ccae4efe36fae839a755561e9b6829b998c4ec653f7a9a24c8a67a6e9da9ff9e5b81ad1134018edceed75b5859e12cce280819e2792a203da7a65f4997087
7
- data.tar.gz: '0269f857a01274f4c9b64b051c724fff030582e2d62b9222da04ae0828e7770160645a4dee01a0a0c791921197d08ce87f420e5fa24678e961e76fb267c9377b'
6
+ metadata.gz: 73bef840c84345011a8246128537d81d76fee4c73215ac3856e43814e04304bfcf16d54213eee2fb940650f3fe4c13df249d1476805090cc0fbd7524f00fed00
7
+ data.tar.gz: a4b3f901aa19c01de17a059bd907197d4b2f8276a72de4ea29381ee803291ea9e4f33cc8c9667358247868297fb3b784dab1f0b127c7a04a98f37a56c4e2a773
data/CHANGELOG.md CHANGED
@@ -3,6 +3,9 @@
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
+ ## [1.0.5] - 2022-01-23
7
+ - [#194](https://github.com/boltops-tools/terraspace/pull/194) ability to allow and deny envs, regions, and stacks
8
+
6
9
  ## [1.0.4] - 2022-01-21
7
10
  - [#193](https://github.com/boltops-tools/terraspace/pull/193) improve all include_stacks and exclude_stacks option
8
11
 
@@ -0,0 +1,12 @@
1
+ class Terraspace::App::CallableOption
2
+ module Concern
3
+ def callable_option(options={})
4
+ callable_option = Terraspace::App::CallableOption.new(
5
+ config_name: options[:config_name],
6
+ config_value: options[:config_value],
7
+ passed_args: options[:passed_args],
8
+ )
9
+ callable_option.object
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,58 @@
1
+ # Class represents a terraspace option that is possibly callable. Examples:
2
+ #
3
+ # config.allow.envs
4
+ # config.allow.regions
5
+ # config.deny.envs
6
+ # config.deny.regions
7
+ # config.all.include_stacks
8
+ # config.all.exclude_stacks
9
+ #
10
+ # Abstraction is definitely obtuse. Using it to get rid of duplication.
11
+ #
12
+ class Terraspace::App
13
+ class CallableOption
14
+ include Terraspace::Util::Logging
15
+
16
+ def initialize(options={})
17
+ @options = options
18
+ # Example:
19
+ # config_name: config.allow.envs
20
+ # config_value: ["dev"]
21
+ # args: [@stack_name] # passed to object.call
22
+ @config_name = options[:config_name]
23
+ @config_value = options[:config_value]
24
+ @passed_args = options[:passed_args]
25
+ end
26
+
27
+ # Returns either an Array or nil
28
+ def object
29
+ case @config_value
30
+ when nil
31
+ return nil
32
+ when Array
33
+ return @config_value
34
+ when -> (c) { c.respond_to?(:public_instance_methods) && c.public_instance_methods.include?(:call) }
35
+ object= @config_value.new
36
+ when -> (c) { c.respond_to?(:call) }
37
+ object = @config_value
38
+ else
39
+ raise "Invalid option for #{@config_name}"
40
+ end
41
+
42
+ if object
43
+ result = @passed_args.empty? ? object.call : object.call(*@passed_args)
44
+ unless result.is_a?(Array) || result.is_a?(NilClass)
45
+ message = "ERROR: The #{@config_name} needs to return an Array or nil"
46
+ logger.info message.color(:yellow)
47
+ logger.info <<~EOL
48
+ The #{@config_name} when assigned a class, object, or proc must implement
49
+ the call method and return an Array or nil.
50
+ The current return value is a #{result.class}
51
+ EOL
52
+ raise message
53
+ end
54
+ end
55
+ result
56
+ end
57
+ end
58
+ end
@@ -12,16 +12,26 @@ module Terraspace
12
12
 
13
13
  def defaults
14
14
  config = ActiveSupport::OrderedOptions.new
15
+
15
16
  config.all = ActiveSupport::OrderedOptions.new
16
17
  config.all.concurrency = 5
17
18
  config.all.exit_on_fail = ActiveSupport::OrderedOptions.new
18
19
  config.all.exit_on_fail.down = true
19
20
  config.all.exit_on_fail.up = true
20
- config.all.ignore_stacks = nil
21
- config.all.include_stacks = nil
21
+
22
22
  config.allow = ActiveSupport::OrderedOptions.new
23
23
  config.allow.envs = nil
24
24
  config.allow.regions = nil
25
+ config.allow.stacks = nil
26
+ config.deny = ActiveSupport::OrderedOptions.new
27
+ config.deny.envs = nil
28
+ config.deny.regions = nil
29
+ config.deny.stacks = nil
30
+
31
+ config.all.exclude_stacks = nil
32
+ config.all.include_stacks = nil
33
+ config.all.consider_allow_deny_stacks = true
34
+
25
35
  config.auto_create_backend = true
26
36
  config.build = ActiveSupport::OrderedOptions.new
27
37
  config.build.cache_dir = ":CACHE_ROOT/:REGION/:ENV/:BUILD_DIR"
@@ -0,0 +1,59 @@
1
+ class Terraspace::Builder::Allow
2
+ class Base
3
+ include Terraspace::App::CallableOption::Concern
4
+
5
+ def initialize(mod)
6
+ @mod = mod # Only Region subclass uses @mod but keeping interface same for Env for simplicity
7
+ @stack_name = mod.name
8
+ end
9
+
10
+ def check!
11
+ messages = []
12
+ unless allowed?
13
+ messages << message # message is interface method
14
+ end
15
+ unless messages.empty?
16
+ puts "ERROR: The configs do not allow this.".color(:red)
17
+ puts messages
18
+ exit 1
19
+ end
20
+ end
21
+
22
+ def allowed?
23
+ if allows.nil? && denys.nil?
24
+ true
25
+ elsif denys.nil?
26
+ allows.include?(check_value)
27
+ elsif allows.nil?
28
+ !denys.include?(check_value)
29
+ else
30
+ allows.include?(check_value) && !denys.include?(check_value)
31
+ end
32
+ end
33
+
34
+ def allows
35
+ callable_option(
36
+ config_name: "config.allow.#{config_name}",
37
+ config_value: config.dig(:allow, config_name),
38
+ passed_args: [@stack_name],
39
+ )
40
+ end
41
+
42
+ def denys
43
+ callable_option(
44
+ config_name: "config.deny.#{config_name}",
45
+ config_value: config.dig(:deny, config_name),
46
+ passed_args: [@stack_name],
47
+ )
48
+ end
49
+
50
+ private
51
+ def config
52
+ Terraspace.config
53
+ end
54
+
55
+ def config_name
56
+ self.class.to_s.split('::').last.underscore.pluralize.to_sym # ActiveSuport::HashWithIndifferentAccess#dig requires symbol
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,17 @@
1
+ class Terraspace::Builder::Allow
2
+ class Env < Base
3
+ # interface method
4
+ def message
5
+ messages = []
6
+ messages << "This env is not allowed to be used: TS_ENV=#{Terraspace.env}"
7
+ messages << "Allow envs: #{allows.join(', ')}" if allows
8
+ messages << "Deny envs: #{denys.join(', ')}" if denys
9
+ messages.join("\n")
10
+ end
11
+
12
+ # interface method
13
+ def check_value
14
+ Terraspace.env
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,31 @@
1
+ class Terraspace::Builder::Allow
2
+ class Region < Base
3
+ # interface method
4
+ def message
5
+ messages = []
6
+ word = config_name.to_s # IE: regions or locations
7
+ messages << "This #{word.singularize} is not allowed to be used: Detected current #{word.singularize}=#{current_region}"
8
+ messages << "Allow #{word}: #{allows.join(', ')}" if allows
9
+ messages << "Deny #{word}: #{denys.join(', ')}" if denys
10
+ messages.join("\n")
11
+ end
12
+
13
+ # interface method
14
+ def check_value
15
+ current_region
16
+ end
17
+
18
+ def current_region
19
+ expander = Terraspace::Compiler::Expander.autodetect(@mod).expander
20
+ expander.region
21
+ end
22
+
23
+ def config_name
24
+ if config.allow.locations || config.deny.locations
25
+ :locations # ActiveSuport::HashWithIndifferentAccess#dig requires symbol
26
+ else
27
+ super # :regions
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,17 @@
1
+ class Terraspace::Builder::Allow
2
+ class Stack < Base
3
+ # interface method
4
+ def message
5
+ messages = []
6
+ messages << "This stack is not allowed to be used for TS_ENV=#{Terraspace.env}"
7
+ messages << "Allow stacks: #{allows.join(', ')}" if allows
8
+ messages << "Deny stacks: #{denys.join(', ')}" if denys
9
+ messages.join("\n")
10
+ end
11
+
12
+ # interface method
13
+ def check_value
14
+ @mod.name
15
+ end
16
+ end
17
+ end
@@ -5,39 +5,9 @@ class Terraspace::Builder
5
5
  end
6
6
 
7
7
  def check!
8
- messages = []
9
- unless env_allowed?
10
- messages << "This env is not allowed to be used: TS_ENV=#{Terraspace.env}"
11
- messages << "Allowed envs: #{config.allow.envs.join(', ')}"
12
- end
13
- unless region_allowed?
14
- messages << "This region is not allowed to be used: Detected current region=#{current_region}"
15
- messages << "Allowed regions: #{config.allow.regions.join(', ')}"
16
- end
17
- unless messages.empty?
18
- puts "ERROR: The configs do not allow this.".color(:red)
19
- puts messages
20
- exit 1
21
- end
22
- end
23
-
24
- def env_allowed?
25
- return true unless config.allow.envs
26
- config.allow.envs.include?(Terraspace.env)
27
- end
28
-
29
- def region_allowed?
30
- return true unless config.allow.regions
31
- config.allow.regions.include?(current_region)
32
- end
33
-
34
- def current_region
35
- expander = Terraspace::Compiler::Expander.autodetect(@mod).expander
36
- expander.region
37
- end
38
-
39
- def config
40
- Terraspace.config
8
+ Env.new(@mod).check!
9
+ Stack.new(@mod).check!
10
+ Region.new(@mod).check!
41
11
  end
42
12
  end
43
13
  end
@@ -1,5 +1,6 @@
1
1
  module Terraspace::Compiler
2
2
  class Select
3
+ include Terraspace::App::CallableOption::Concern
3
4
  include Terraspace::Util::Logging
4
5
 
5
6
  def initialize(path)
@@ -22,48 +23,42 @@ module Terraspace::Compiler
22
23
  end
23
24
 
24
25
  def include_stacks
25
- include_option(:include_stacks)
26
+ if config.all.include_stacks
27
+ config_name = "config.all.include_stacks"
28
+ config_value = config.dig(:all, :include_stacks)
29
+ elsif config.all.consider_allow_deny_stacks
30
+ config_name = "config.allow.stacks"
31
+ config_value = config.dig(:allow, :stacks)
32
+ else
33
+ return
34
+ end
35
+ callable_option(
36
+ config_name: config_name,
37
+ config_value: config_value,
38
+ passed_args: [@stack_name],
39
+ )
26
40
  end
27
41
 
28
42
  def exclude_stacks
29
- include_option(:exclude_stacks)
30
- end
31
-
32
- def include_option(name)
33
- option = all[name] # IE: include_stacks or exclude_stacks
34
- option ||= all[:ignore_stacks] if name == :exclude_stacks
35
- case option
36
- when nil
37
- return nil
38
- when Array
39
- return option
40
- when -> (c) { c.respond_to?(:public_instance_methods) && c.public_instance_methods.include?(:call) }
41
- object= option.new
42
- when -> (c) { c.respond_to?(:call) }
43
- object = option
43
+ if config.all.exclude_stacks
44
+ config_name = "config.all.exclude_stacks"
45
+ config_value = config.dig(:all, :exclude_stacks)
46
+ elsif config.all.consider_allow_deny_stacks
47
+ config_name = "config.deny.stacks"
48
+ config_value = config.dig(:deny, :stacks)
44
49
  else
45
- raise "Invalid option for config.all.#{name}"
46
- end
47
-
48
- if object
49
- result = object.call(@stack_name)
50
- unless result.is_a?(Array) || result.is_a?(NilClass)
51
- message = "ERROR: The config.all.#{name} needs to return an Array or nil"
52
- logger.info message.color(:yellow)
53
- logger.info <<~EOL
54
- The config.all.#{name} when assigned a class, object, or proc must implement
55
- the call method and return an Array or nil.
56
- The current return value is a #{result.class}
57
- EOL
58
- raise message
59
- end
50
+ return
60
51
  end
61
- result
52
+ callable_option(
53
+ config_name: config_name,
54
+ config_value: config_value,
55
+ passed_args: [@stack_name],
56
+ )
62
57
  end
63
58
 
64
59
  private
65
- def all
66
- Terraspace.config.all
60
+ def config
61
+ Terraspace.config
67
62
  end
68
63
 
69
64
  def extract_stack_name(path)
@@ -72,7 +67,7 @@ module Terraspace::Compiler
72
67
 
73
68
  @@ignore_stacks_deprecation_warning = nil
74
69
  def ignore_stacks_deprecation_warning
75
- return unless all.ignore_stacks
70
+ return unless config.all.ignore_stacks
76
71
  return if @@ignore_stacks_deprecation_warning
77
72
  puts <<~EOL.color(:yellow)
78
73
  DEPRECATED: config.all.ignore_stacks
@@ -1,3 +1,3 @@
1
1
  module Terraspace
2
- VERSION = "1.0.4"
2
+ VERSION = "1.0.5"
3
3
  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: 1.0.4
4
+ version: 1.0.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: 2022-01-21 00:00:00.000000000 Z
11
+ date: 2022-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -478,12 +478,18 @@ files:
478
478
  - lib/terraspace/all/runner.rb
479
479
  - lib/terraspace/all/summary.rb
480
480
  - lib/terraspace/app.rb
481
+ - lib/terraspace/app/callable_option.rb
482
+ - lib/terraspace/app/callable_option/concern.rb
481
483
  - lib/terraspace/app/inits.rb
482
484
  - lib/terraspace/autodetect.rb
483
485
  - lib/terraspace/autoloader.rb
484
486
  - lib/terraspace/booter.rb
485
487
  - lib/terraspace/builder.rb
486
488
  - lib/terraspace/builder/allow.rb
489
+ - lib/terraspace/builder/allow/base.rb
490
+ - lib/terraspace/builder/allow/env.rb
491
+ - lib/terraspace/builder/allow/region.rb
492
+ - lib/terraspace/builder/allow/stack.rb
487
493
  - lib/terraspace/bundle.rb
488
494
  - lib/terraspace/cli.rb
489
495
  - lib/terraspace/cli/all.rb