kitchen-pulumi 0.1.0.pre.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +4 -0
- data/lib/kitchen/driver/pulumi.rb +170 -0
- data/lib/kitchen/provisioner/pulumi.rb +24 -0
- data/lib/kitchen/pulumi.rb +8 -0
- data/lib/kitchen/pulumi/command.rb +11 -0
- data/lib/kitchen/pulumi/command/input.rb +33 -0
- data/lib/kitchen/pulumi/command/output.rb +33 -0
- data/lib/kitchen/pulumi/config_attribute.rb +12 -0
- data/lib/kitchen/pulumi/config_attribute/backend.rb +34 -0
- data/lib/kitchen/pulumi/config_attribute/color.rb +34 -0
- data/lib/kitchen/pulumi/config_attribute/config.rb +35 -0
- data/lib/kitchen/pulumi/config_attribute/config_file.rb +34 -0
- data/lib/kitchen/pulumi/config_attribute/directory.rb +34 -0
- data/lib/kitchen/pulumi/config_attribute/fail_fast.rb +34 -0
- data/lib/kitchen/pulumi/config_attribute/plugins.rb +34 -0
- data/lib/kitchen/pulumi/config_attribute/refresh_config.rb +34 -0
- data/lib/kitchen/pulumi/config_attribute/secrets.rb +35 -0
- data/lib/kitchen/pulumi/config_attribute/stack.rb +33 -0
- data/lib/kitchen/pulumi/config_attribute/stack_evolution.rb +37 -0
- data/lib/kitchen/pulumi/config_attribute/systems.rb +33 -0
- data/lib/kitchen/pulumi/config_attribute_cacher.rb +28 -0
- data/lib/kitchen/pulumi/config_attribute_definer.rb +39 -0
- data/lib/kitchen/pulumi/config_schemas.rb +11 -0
- data/lib/kitchen/pulumi/config_schemas/array_of_hashes.rb +12 -0
- data/lib/kitchen/pulumi/config_schemas/boolean.rb +12 -0
- data/lib/kitchen/pulumi/config_schemas/config_evolution_array.rb +40 -0
- data/lib/kitchen/pulumi/config_schemas/error_messages.yml +21 -0
- data/lib/kitchen/pulumi/config_schemas/hash.rb +12 -0
- data/lib/kitchen/pulumi/config_schemas/stack_settings_hash.rb +20 -0
- data/lib/kitchen/pulumi/config_schemas/string.rb +12 -0
- data/lib/kitchen/pulumi/config_schemas/system.rb +577 -0
- data/lib/kitchen/pulumi/config_schemas/systems.rb +20 -0
- data/lib/kitchen/pulumi/configurable.rb +27 -0
- data/lib/kitchen/pulumi/error.rb +10 -0
- data/lib/kitchen/pulumi/file_path_config_attribute_definer.rb +25 -0
- data/lib/kitchen/pulumi/inspec.rb +66 -0
- data/lib/kitchen/pulumi/inspec_options_mapper.rb +69 -0
- data/lib/kitchen/pulumi/inspec_with_hosts.rb +40 -0
- data/lib/kitchen/pulumi/inspec_without_hosts.rb +34 -0
- data/lib/kitchen/pulumi/kitchen_instance.rb +12 -0
- data/lib/kitchen/pulumi/shell_out.rb +40 -0
- data/lib/kitchen/pulumi/system.rb +130 -0
- data/lib/kitchen/pulumi/system_attrs_resolver.rb +59 -0
- data/lib/kitchen/pulumi/system_hosts_resolver.rb +34 -0
- data/lib/kitchen/pulumi/version.rb +5 -0
- data/lib/kitchen/verifier/pulumi.rb +177 -0
- metadata +323 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kitchen/pulumi'
|
4
|
+
require 'kitchen/pulumi/config_schemas/string'
|
5
|
+
require 'kitchen/pulumi/config_attribute_cacher'
|
6
|
+
require 'kitchen/pulumi/file_path_config_attribute_definer'
|
7
|
+
|
8
|
+
module Kitchen
|
9
|
+
module Pulumi
|
10
|
+
module ConfigAttribute
|
11
|
+
# Attribute used to specify the directory containing a project's
|
12
|
+
# Pulumi.yaml file
|
13
|
+
module Directory
|
14
|
+
def self.included(plugin_class)
|
15
|
+
definer = FilePathConfigAttributeDefiner.new(
|
16
|
+
attribute: self,
|
17
|
+
schema: ConfigSchemas::String,
|
18
|
+
)
|
19
|
+
definer.define(plugin_class: plugin_class)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.to_sym
|
23
|
+
:directory
|
24
|
+
end
|
25
|
+
|
26
|
+
extend ConfigAttributeCacher
|
27
|
+
|
28
|
+
def config_directory_default_value
|
29
|
+
'.'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kitchen/pulumi'
|
4
|
+
require 'kitchen/pulumi/config_schemas/boolean'
|
5
|
+
require 'kitchen/pulumi/config_attribute_cacher'
|
6
|
+
require 'kitchen/pulumi/config_attribute_definer'
|
7
|
+
|
8
|
+
module Kitchen
|
9
|
+
module Pulumi
|
10
|
+
module ConfigAttribute
|
11
|
+
# Attribute used to determine if Kitchen should halt on the
|
12
|
+
# first error during verification.
|
13
|
+
module FailFast
|
14
|
+
def self.included(plugin_class)
|
15
|
+
definer = ConfigAttributeDefiner.new(
|
16
|
+
attribute: self,
|
17
|
+
schema: ConfigSchemas::Boolean,
|
18
|
+
)
|
19
|
+
definer.define(plugin_class: plugin_class)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.to_sym
|
23
|
+
:fail_fast
|
24
|
+
end
|
25
|
+
|
26
|
+
extend ConfigAttributeCacher
|
27
|
+
|
28
|
+
def config_fail_fast_default_value
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kitchen/pulumi/config_attribute'
|
4
|
+
require 'kitchen/pulumi/config_schemas/array_of_hashes'
|
5
|
+
require 'kitchen/pulumi/config_attribute_cacher'
|
6
|
+
require 'kitchen/pulumi/config_attribute_definer'
|
7
|
+
|
8
|
+
module Kitchen
|
9
|
+
module Pulumi
|
10
|
+
module ConfigAttribute
|
11
|
+
# Module used for specifying any required plugins that a project
|
12
|
+
# will need to provision its resources.
|
13
|
+
module Plugins
|
14
|
+
def self.included(plugin)
|
15
|
+
definer = ConfigAttributeDefiner.new(
|
16
|
+
attribute: self,
|
17
|
+
schema: ConfigSchemas::ArrayOfHashes,
|
18
|
+
)
|
19
|
+
definer.define(plugin_class: plugin)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.to_sym
|
23
|
+
:plugins
|
24
|
+
end
|
25
|
+
|
26
|
+
extend ConfigAttributeCacher
|
27
|
+
|
28
|
+
def config_plugins_default_value
|
29
|
+
[]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kitchen/pulumi'
|
4
|
+
require 'kitchen/pulumi/config_schemas/boolean'
|
5
|
+
require 'kitchen/pulumi/config_attribute_cacher'
|
6
|
+
require 'kitchen/pulumi/config_attribute_definer'
|
7
|
+
|
8
|
+
module Kitchen
|
9
|
+
module Pulumi
|
10
|
+
module ConfigAttribute
|
11
|
+
# Attribute used to determine if the stack config should be
|
12
|
+
# refreshed from the remote before every `pulumi up` command
|
13
|
+
module RefreshConfig
|
14
|
+
def self.included(plugin_class)
|
15
|
+
definer = ConfigAttributeDefiner.new(
|
16
|
+
attribute: self,
|
17
|
+
schema: ConfigSchemas::Boolean,
|
18
|
+
)
|
19
|
+
definer.define(plugin_class: plugin_class)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.to_sym
|
23
|
+
:refresh_config
|
24
|
+
end
|
25
|
+
|
26
|
+
extend ConfigAttributeCacher
|
27
|
+
|
28
|
+
def config_refresh_config_default_value
|
29
|
+
false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kitchen/pulumi/config_attribute'
|
4
|
+
require 'kitchen/pulumi/config_schemas/stack_settings_hash'
|
5
|
+
require 'kitchen/pulumi/config_attribute_cacher'
|
6
|
+
require 'kitchen/pulumi/config_attribute_definer'
|
7
|
+
|
8
|
+
module Kitchen
|
9
|
+
module Pulumi
|
10
|
+
module ConfigAttribute
|
11
|
+
# Module used for the 'config' instance var on an
|
12
|
+
# instance driver. The driver will set the Pulumi stack
|
13
|
+
# configs for each of the namespaces provided.
|
14
|
+
module Secrets
|
15
|
+
def self.included(plugin)
|
16
|
+
definer = ConfigAttributeDefiner.new(
|
17
|
+
attribute: self,
|
18
|
+
schema: ConfigSchemas::StackSettingsHash,
|
19
|
+
)
|
20
|
+
definer.define(plugin_class: plugin)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.to_sym
|
24
|
+
:secrets
|
25
|
+
end
|
26
|
+
|
27
|
+
extend ConfigAttributeCacher
|
28
|
+
|
29
|
+
def config_secrets_default_value
|
30
|
+
{}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kitchen/pulumi'
|
4
|
+
require 'kitchen/pulumi/config_schemas/string'
|
5
|
+
require 'kitchen/pulumi/config_attribute_cacher'
|
6
|
+
require 'kitchen/pulumi/config_attribute_definer'
|
7
|
+
|
8
|
+
module Kitchen
|
9
|
+
module Pulumi
|
10
|
+
module ConfigAttribute
|
11
|
+
# Attribute used to specify the stack to use for a specific instance
|
12
|
+
module Stack
|
13
|
+
def self.included(plugin_class)
|
14
|
+
definer = ConfigAttributeDefiner.new(
|
15
|
+
attribute: self,
|
16
|
+
schema: ConfigSchemas::String,
|
17
|
+
)
|
18
|
+
definer.define(plugin_class: plugin_class)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.to_sym
|
22
|
+
:stack
|
23
|
+
end
|
24
|
+
|
25
|
+
extend ConfigAttributeCacher
|
26
|
+
|
27
|
+
def config_stack_default_value
|
28
|
+
''
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kitchen/pulumi/config_attribute'
|
4
|
+
require 'kitchen/pulumi/config_schemas/config_evolution_array'
|
5
|
+
require 'kitchen/pulumi/config_attribute_cacher'
|
6
|
+
require 'kitchen/pulumi/config_attribute_definer'
|
7
|
+
|
8
|
+
module Kitchen
|
9
|
+
module Pulumi
|
10
|
+
module ConfigAttribute
|
11
|
+
# Module used for the 'config_evolution' instance var on an
|
12
|
+
# instance driver. The driver will set the Pulumi stack
|
13
|
+
# configs for each config in the array and then call `pulumi up`
|
14
|
+
# between each item in the evolution list. This has the effect of
|
15
|
+
# testing a user's stack configuration changes over time.
|
16
|
+
module StackEvolution
|
17
|
+
def self.included(plugin)
|
18
|
+
definer = ConfigAttributeDefiner.new(
|
19
|
+
attribute: self,
|
20
|
+
schema: ConfigSchemas::ConfigEvolutionArray,
|
21
|
+
)
|
22
|
+
definer.define(plugin_class: plugin)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.to_sym
|
26
|
+
:stack_evolution
|
27
|
+
end
|
28
|
+
|
29
|
+
extend ConfigAttributeCacher
|
30
|
+
|
31
|
+
def config_stack_evolution_default_value
|
32
|
+
[]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kitchen/pulumi/config_attribute'
|
4
|
+
require 'kitchen/pulumi/config_schemas/systems'
|
5
|
+
|
6
|
+
module Kitchen
|
7
|
+
module Pulumi
|
8
|
+
module ConfigAttribute
|
9
|
+
# {include:Kitchen::Pulumi::ConfigSchemas::Systems}
|
10
|
+
#
|
11
|
+
# If the +systems+ key is omitted then no tests will be executed.
|
12
|
+
module Systems
|
13
|
+
def self.included(plugin_class)
|
14
|
+
definer = ConfigAttributeDefiner.new(
|
15
|
+
attribute: self,
|
16
|
+
schema: ConfigSchemas::Systems,
|
17
|
+
)
|
18
|
+
definer.define(plugin_class: plugin_class)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.to_sym
|
22
|
+
:systems
|
23
|
+
end
|
24
|
+
|
25
|
+
extend ConfigAttributeCacher
|
26
|
+
|
27
|
+
def config_systems_default_value
|
28
|
+
[]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen
|
4
|
+
module Pulumi
|
5
|
+
# Namespace for the config attribute retrieval cache. Allows plugins that
|
6
|
+
# include ConfigAttributes to refer to config values by instance variables
|
7
|
+
# of the form 'config_<attribute name>'
|
8
|
+
module ConfigAttributeCacher
|
9
|
+
# Defines an attribute cache for a config attribute extending this module
|
10
|
+
def self.extended(config_attribute)
|
11
|
+
config_attribute.define_cache
|
12
|
+
end
|
13
|
+
|
14
|
+
# Sets an instance variable for a config attribute extending this module
|
15
|
+
def define_cache(attribute: to_sym)
|
16
|
+
attr = "config_#{attribute}"
|
17
|
+
|
18
|
+
define_method(attr) do
|
19
|
+
if instance_variable_defined?("@#{attr}")
|
20
|
+
instance_variable_get("@#{attr}")
|
21
|
+
else
|
22
|
+
instance_variable_set("@#{attr}", config.fetch(attribute))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kitchen/pulumi'
|
4
|
+
|
5
|
+
module Kitchen
|
6
|
+
module Pulumi
|
7
|
+
# This class defines attributes consumed from .kitchen.yml and
|
8
|
+
# used in the Test Kitchen plugins.
|
9
|
+
class ConfigAttributeDefiner
|
10
|
+
def initialize(attribute:, schema:)
|
11
|
+
@attribute = attribute.to_sym
|
12
|
+
@schema = schema
|
13
|
+
end
|
14
|
+
|
15
|
+
def define(plugin_class:)
|
16
|
+
plugin_class.required_config(@attribute) do |_attribute, value, _plugin|
|
17
|
+
schema_messages = @schema.call(value: value).messages
|
18
|
+
process_schema_messages(messages: schema_messages,
|
19
|
+
plugin_class: plugin_class)
|
20
|
+
end
|
21
|
+
|
22
|
+
plugin_class.default_config(@attribute) do |plugin|
|
23
|
+
plugin.send "config_#{@attribute}_default_value"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def process_schema_messages(messages:, plugin_class:)
|
30
|
+
return true if messages.empty?
|
31
|
+
|
32
|
+
raise(
|
33
|
+
::Kitchen::UserError,
|
34
|
+
"#{plugin_class} config: #{@attribute} #{messages}",
|
35
|
+
)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry-validation'
|
4
|
+
require 'kitchen/pulumi/config_schemas'
|
5
|
+
|
6
|
+
module Kitchen
|
7
|
+
module Pulumi
|
8
|
+
ConfigSchemas::ConfigEvolutionArray = ::Dry::Validation.Schema do
|
9
|
+
configure do
|
10
|
+
config.messages_file = "#{__dir__}/error_messages.yml"
|
11
|
+
|
12
|
+
def config_evolution_items_valid_types?(value)
|
13
|
+
return false unless value.is_a?(Hash)
|
14
|
+
|
15
|
+
config_file = value.fetch(:config_file, '')
|
16
|
+
conf = value.fetch(:config, {})
|
17
|
+
secrets = value.fetch(:secrets, {})
|
18
|
+
|
19
|
+
config_file.is_a?(String) && conf.is_a?(Hash) && secrets.is_a?(Hash)
|
20
|
+
end
|
21
|
+
|
22
|
+
def config_evolution_array_item_valid?(value)
|
23
|
+
c_file = value.fetch(:config_file, '')
|
24
|
+
config = value.fetch(:config, {})
|
25
|
+
secrets = value.fetch(:secrets, {})
|
26
|
+
|
27
|
+
c_file_ok = c_file.empty? || File.file?(File.expand_path(c_file))
|
28
|
+
config_valid = config.all? { |_, nested| nested.is_a?(Hash) }
|
29
|
+
secrets_valid = secrets.all? { |_, nested| nested.is_a?(Hash) }
|
30
|
+
c_file_ok && config_valid && secrets_valid
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
required(:value).each(
|
35
|
+
:config_evolution_items_valid_types?,
|
36
|
+
:config_evolution_array_item_valid?,
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
errors:
|
4
|
+
stack_settings_hash?: >
|
5
|
+
Invalid stack settings map - config/secrets maps should be a map of maps.
|
6
|
+
The top-level map keys represent Pulumi namespaces on which the key-value pairs
|
7
|
+
in that namespace's nested map are set.
|
8
|
+
|
9
|
+
config_evolution_items_valid_types?: >
|
10
|
+
Invalid stack evolution list - Stack evolutions must be a list whose map-type items contain at
|
11
|
+
least one of three values --- 1. 'config_file' - String specifying path to config file to use for this update.
|
12
|
+
2. 'config' - A map of maps in which the top-level map keys represent Pulumi namespaces on which the key-value pairs
|
13
|
+
in that namespace's nested map are set. 3. 'secrets' -- A map with the same structure as 'config', but whose values
|
14
|
+
will be set as secrets on your stack.
|
15
|
+
|
16
|
+
config_evolution_array_item_valid?: >
|
17
|
+
Invalid stack evolution list - Stack evolutions must be a list whose map-type items contain at
|
18
|
+
least one of three values --- 1. 'config_file' - String specifying path to config file to use for this update.
|
19
|
+
2. 'config' - A map of maps in which the top-level map keys represent Pulumi namespaces on which the key-value pairs
|
20
|
+
in that namespace's nested map are set. 3. 'secrets' -- A map with the same structure as 'config', but but whose values
|
21
|
+
will be set as secrets on your stack.
|