kitchen-pulumi 0.1.0.pre.beta → 0.1.0
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/README.md +71 -2
- data/lib/kitchen/driver/pulumi.rb +193 -34
- data/lib/kitchen/provisioner/pulumi.rb +13 -3
- data/lib/kitchen/pulumi.rb +25 -0
- data/lib/kitchen/pulumi/config_attribute/backend.rb +1 -1
- data/lib/kitchen/pulumi/config_attribute/preserve_config.rb +35 -0
- data/lib/kitchen/pulumi/config_attribute/{stack.rb → secrets_provider.rb} +4 -4
- data/lib/kitchen/pulumi/config_attribute/test_stack_name.rb +34 -0
- data/lib/kitchen/pulumi/config_schemas/system.rb +2 -2
- data/lib/kitchen/pulumi/deep_merge.rb +8 -0
- data/lib/kitchen/pulumi/inspec_options_mapper.rb +1 -1
- data/lib/kitchen/pulumi/shell_out.rb +2 -2
- data/lib/kitchen/pulumi/system_attrs_resolver.rb +5 -9
- data/lib/kitchen/pulumi/version.rb +1 -1
- data/lib/kitchen/verifier/pulumi.rb +20 -4
- metadata +105 -27
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d6c0ce9de8379c66a261cbc65cf916a72cc46f44b1dd1fa75351807a9a38d828
|
|
4
|
+
data.tar.gz: 7e346277daebaa03ca622ca61a694004d412d6a0b6f2fc1badea8d8f752b33f9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 88631c7633e26c60539e22deefb778bf44e5f438d2af53101ea5645a02d3633997358ef04747f85f3f12a405ad797e76a96b469eceb262850bd0b4e275eec0d5
|
|
7
|
+
data.tar.gz: b1ec83259b24dad3c038c77f471655ee34ead9b3478cbf5db9942f5c8db4c264d801fae99e14bc889e9f13a4a0b1d9eaeaebb820a1de779d4b13d1b7f8719fd9
|
data/README.md
CHANGED
|
@@ -1,4 +1,73 @@
|
|
|
1
|
+
# Kitchen-Pulumi
|
|
2
|
+
|
|
3
|
+
[](https://rubygems.org/gems/kitchen-pulumi/)
|
|
4
|
+
[](https://rubygems.org/gems/kitchen-pulumi/)
|
|
5
|
+
[](https://rubygems.org/gems/kitchen-pulumi/)
|
|
1
6
|
[](https://circleci.com/gh/jacoblearned/kitchen-pulumi/tree/master)
|
|
7
|
+
[](https://codeclimate.com/github/jacoblearned/kitchen-pulumi/test_coverage)
|
|
8
|
+
[](https://codeclimate.com/github/jacoblearned/kitchen-pulumi/maintainability)
|
|
9
|
+
|
|
10
|
+
Kitchen-Pulumi is a collection of [Test-Kitchen](https://kitchen.ci/) plugins for developing test-driven [Pulumi](https://www.pulumi.com/)-based cloud infrastructure projects.
|
|
11
|
+
With Kitchen-Pulumi you can provision ephemeral test stacks, verify they are in a desired state using [InSpec](https://www.inspec.io/), and tear them down to gain
|
|
12
|
+
confidence in your infrastructure code before it hits production.
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
Kitchen-Pulumi provides a Kitchen [driver](https://kitchen.ci/docs/drivers/), [provisioner](https://kitchen.ci/docs/provisioners/),
|
|
17
|
+
and [verifier](https://kitchen.ci/docs/verifiers/) which collectively support the following features:
|
|
18
|
+
|
|
19
|
+
* **Language-agnostic**: Create and test Pulumi stacks in any of their [supported languages](https://www.pulumi.com/docs/reference/languages/).
|
|
20
|
+
* **Backend-agnostic**: Use the Pulumi SaaS backend, a local backend, or your organization's internal backend.
|
|
21
|
+
* **Configurable**: Easily define/override stack config values in your `.kitchen.yml` file for flexible testing across environments or scenarios.
|
|
22
|
+
* **Test changes over time**: Simulate changes in stack config values over time to test how your infrastructure reacts to ever-shifting user-provided values.
|
|
23
|
+
* **Custom state verification**: Code any validation logic you desire, provided it can be ran within an [InSpec profile](https://www.inspec.io/docs/reference/profiles/).
|
|
24
|
+
|
|
25
|
+
If there's a feature you would like to see in Kitchen-Pulumi, please create an issue with the suggested feature and its intended use case.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
Kitchen-Pulumi is compatible with Ruby 2.6 and above. Add this line to your application's Gemfile:
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
# Gemfile
|
|
33
|
+
|
|
34
|
+
gem 'kitchen-pulumi', require: false
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
And then execute:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
$ bundle
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or install it yourself as:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
$ gem install kitchen-pulumi
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Quick Start / Tutorial
|
|
50
|
+
|
|
51
|
+
Check out the [serverless-rest-api-lambda example](examples/aws/serverless-rest-api-lambda) and follow the instructions in its `README`.
|
|
52
|
+
|
|
53
|
+
## Usage
|
|
54
|
+
|
|
55
|
+
TODO: Write usage instructions here
|
|
56
|
+
|
|
57
|
+
## Development
|
|
58
|
+
|
|
59
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
60
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
61
|
+
|
|
62
|
+
## Contributing
|
|
63
|
+
|
|
64
|
+
Bug reports and pull requests are always welcome on GitHub at https://github.com/jacoblearned/kitchen-pulumi. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
|
65
|
+
|
|
66
|
+
## License
|
|
67
|
+
|
|
68
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
69
|
+
|
|
70
|
+
## Code of Conduct
|
|
71
|
+
|
|
72
|
+
Everyone interacting in the Kitchen-Pulumi’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jacoblearned/kitchen-pulumi/blob/master/CODE_OF_CONDUCT.md).
|
|
2
73
|
|
|
3
|
-
# kitchen-pulumi
|
|
4
|
-
Test-Kitchen plugins for Pulumi projects
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'yaml'
|
|
3
4
|
require 'kitchen'
|
|
4
5
|
require 'kitchen/driver/base'
|
|
5
6
|
require 'kitchen/pulumi/error'
|
|
6
7
|
require 'kitchen/pulumi/shell_out'
|
|
8
|
+
require 'kitchen/pulumi/deep_merge'
|
|
7
9
|
require 'kitchen/pulumi/configurable'
|
|
8
10
|
require 'kitchen/pulumi/command/input'
|
|
9
11
|
require 'kitchen/pulumi/command/output'
|
|
@@ -13,17 +15,25 @@ require 'kitchen/pulumi/config_attribute/directory'
|
|
|
13
15
|
require 'kitchen/pulumi/config_attribute/plugins'
|
|
14
16
|
require 'kitchen/pulumi/config_attribute/backend'
|
|
15
17
|
require 'kitchen/pulumi/config_attribute/secrets'
|
|
16
|
-
require 'kitchen/pulumi/config_attribute/
|
|
18
|
+
require 'kitchen/pulumi/config_attribute/test_stack_name'
|
|
17
19
|
require 'kitchen/pulumi/config_attribute/stack_evolution'
|
|
18
20
|
require 'kitchen/pulumi/config_attribute/refresh_config'
|
|
21
|
+
require 'kitchen/pulumi/config_attribute/secrets_provider'
|
|
22
|
+
require 'kitchen/pulumi/config_attribute/preserve_config'
|
|
19
23
|
|
|
20
24
|
module Kitchen
|
|
25
|
+
# This namespace is defined by Kitchen.
|
|
26
|
+
#
|
|
27
|
+
# @see https://www.rubydoc.info/gems/test-kitchen/Kitchen/Driver
|
|
21
28
|
module Driver
|
|
22
29
|
# Driver class implementing the CLI equivalency between Kitchen and Pulumi
|
|
30
|
+
#
|
|
31
|
+
# @author Jacob Learned
|
|
23
32
|
class Pulumi < ::Kitchen::Driver::Base
|
|
24
33
|
kitchen_driver_api_version 2
|
|
25
34
|
|
|
26
35
|
include ::Kitchen::Pulumi::Configurable
|
|
36
|
+
include ::Kitchen::Logging
|
|
27
37
|
|
|
28
38
|
# Include config attributes consumable via .kitchen.yml
|
|
29
39
|
include ::Kitchen::Pulumi::ConfigAttribute::Config
|
|
@@ -32,47 +42,107 @@ module Kitchen
|
|
|
32
42
|
include ::Kitchen::Pulumi::ConfigAttribute::Plugins
|
|
33
43
|
include ::Kitchen::Pulumi::ConfigAttribute::Backend
|
|
34
44
|
include ::Kitchen::Pulumi::ConfigAttribute::Secrets
|
|
35
|
-
include ::Kitchen::Pulumi::ConfigAttribute::
|
|
45
|
+
include ::Kitchen::Pulumi::ConfigAttribute::TestStackName
|
|
36
46
|
include ::Kitchen::Pulumi::ConfigAttribute::StackEvolution
|
|
37
47
|
include ::Kitchen::Pulumi::ConfigAttribute::RefreshConfig
|
|
48
|
+
include ::Kitchen::Pulumi::ConfigAttribute::SecretsProvider
|
|
49
|
+
include ::Kitchen::Pulumi::ConfigAttribute::PreserveConfig
|
|
38
50
|
|
|
51
|
+
# Initializes a stack via `pulumi stack init`
|
|
52
|
+
#
|
|
53
|
+
# @param _state [::Hash] the current kitchen state
|
|
54
|
+
# @return [void]
|
|
39
55
|
def create(_state)
|
|
40
56
|
dir = "-C #{config_directory}"
|
|
41
|
-
stack = config_stack.empty? ? instance.suite.name : config_stack
|
|
42
|
-
conf_file = config_file
|
|
43
|
-
|
|
44
57
|
login
|
|
45
58
|
initialize_stack(stack, dir)
|
|
46
|
-
configure(config_config, stack, dir, conf_file)
|
|
47
|
-
configure(config_secrets, stack, dir, conf_file, is_secret: true)
|
|
48
59
|
end
|
|
49
60
|
|
|
50
|
-
|
|
61
|
+
# Sets stack config values via `pulumi config` and updates the stack via `pulumi up`
|
|
62
|
+
#
|
|
63
|
+
# @param _state [::Hash] the current kitchen state
|
|
64
|
+
# @param config_only [Boolean] specify true to update the stack config without
|
|
65
|
+
# applying changes to the stack via `pulumi up`
|
|
66
|
+
#
|
|
67
|
+
# for block {|temp_conf_file| ...}
|
|
68
|
+
# @yield [temp_conf_file] provides the path to the temporary config file used
|
|
69
|
+
#
|
|
70
|
+
# @return [void]
|
|
71
|
+
def update(_state, config_only: false)
|
|
51
72
|
dir = "-C #{config_directory}"
|
|
52
|
-
stack = config_stack.empty? ? instance.suite.name : config_stack
|
|
53
|
-
conf_file = config_file
|
|
54
73
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
74
|
+
::Kitchen::Pulumi.with_temp_conf(config_file) do |temp_conf_file|
|
|
75
|
+
login
|
|
76
|
+
refresh_config(stack, temp_conf_file, dir) if config_refresh_config
|
|
77
|
+
configure(config_config, stack, temp_conf_file, dir)
|
|
78
|
+
configure(config_secrets, stack, temp_conf_file, dir, is_secret: true)
|
|
79
|
+
update_stack(stack, temp_conf_file, dir) unless config_only
|
|
80
|
+
|
|
81
|
+
unless config_stack_evolution.empty?
|
|
82
|
+
evolve_stack(stack, temp_conf_file, dir, config_only: config_only)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
yield temp_conf_file if block_given?
|
|
86
|
+
end
|
|
59
87
|
end
|
|
60
88
|
|
|
89
|
+
# Destroys a stack via `pulumi destroy`
|
|
90
|
+
#
|
|
91
|
+
# @param _state [::Hash] the current kitchen state
|
|
92
|
+
# @return [void]
|
|
61
93
|
def destroy(_state)
|
|
62
94
|
dir = "-C #{config_directory}"
|
|
63
|
-
stack = config_stack.empty? ? instance.suite.name : config_stack
|
|
64
95
|
|
|
65
96
|
cmds = [
|
|
66
97
|
"destroy -y -r --show-config -s #{stack} #{dir}",
|
|
67
|
-
"stack rm
|
|
98
|
+
"stack rm #{preserve_config} -y -s #{stack} #{dir}",
|
|
68
99
|
]
|
|
69
100
|
|
|
70
101
|
login
|
|
71
102
|
::Kitchen::Pulumi::ShellOut.run(cmd: cmds, logger: logger)
|
|
72
103
|
rescue ::Kitchen::Pulumi::Error => e
|
|
73
|
-
|
|
104
|
+
if e.message.match?(/no stack named '#{stack}' found/) || (
|
|
105
|
+
e.message.match?(/failed to load checkpoint/) && config_backend == 'local'
|
|
106
|
+
)
|
|
107
|
+
puts "Stack '#{stack}' does not exist, continuing..."
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Returns `--preserve-config` if the `preserve_config` instance attribute is set
|
|
112
|
+
#
|
|
113
|
+
# @return [String] either `''` or `--preserve-config`
|
|
114
|
+
def preserve_config
|
|
115
|
+
return '' unless config_preserve_config
|
|
116
|
+
|
|
117
|
+
'--preserve-config'
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Returns the name of the current stack to use. If the `test_stack_name` driver
|
|
121
|
+
# attribute is set, then it uses that one, otherwise it will be
|
|
122
|
+
# `<suite name>-<platform name>`
|
|
123
|
+
#
|
|
124
|
+
# @return [String] either the empty string or '--preserve-config'
|
|
125
|
+
def stack
|
|
126
|
+
return config_test_stack_name unless config_test_stack_name.empty?
|
|
127
|
+
|
|
128
|
+
"#{instance.suite.name}-#{instance.platform.name}"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Returns the name of the secrets provider, if set, optionally as a Pulumi CLI flag
|
|
132
|
+
#
|
|
133
|
+
# @param flag [Boolean] specify true to prepend `--secrets-provider=`` to the name
|
|
134
|
+
# @return [String] value to use for the secrets provider
|
|
135
|
+
def secrets_provider(flag: false)
|
|
136
|
+
return '' if config_secrets_provider.empty?
|
|
137
|
+
|
|
138
|
+
return "--secrets-provider=\"#{config_secrets_provider}\"" if flag
|
|
139
|
+
|
|
140
|
+
config_secrets_provider
|
|
74
141
|
end
|
|
75
142
|
|
|
143
|
+
# Logs in to the Pulumi backend set for the instance via `pulumi login`
|
|
144
|
+
#
|
|
145
|
+
# @return [void]
|
|
76
146
|
def login
|
|
77
147
|
backend = config_backend == 'local' ? '--local' : config_backend
|
|
78
148
|
::Kitchen::Pulumi::ShellOut.run(
|
|
@@ -81,18 +151,31 @@ module Kitchen
|
|
|
81
151
|
)
|
|
82
152
|
end
|
|
83
153
|
|
|
154
|
+
# Initializes a stack in the current directory unless another is provided
|
|
155
|
+
#
|
|
156
|
+
# @param stack [String] name of the stack to initialize
|
|
157
|
+
# @param dir [String] path to the directory to run Pulumi commands in
|
|
84
158
|
def initialize_stack(stack, dir = '')
|
|
85
159
|
::Kitchen::Pulumi::ShellOut.run(
|
|
86
|
-
cmd: "stack init #{stack} #{dir}",
|
|
160
|
+
cmd: "stack init #{stack} #{dir} #{secrets_provider(flag: true)}",
|
|
87
161
|
logger: logger,
|
|
88
162
|
)
|
|
89
163
|
rescue ::Kitchen::Pulumi::Error => e
|
|
90
164
|
puts 'Continuing...' if e.message.match?(/stack '#{stack}' already exists/)
|
|
91
165
|
end
|
|
92
166
|
|
|
167
|
+
# Configures a stack in the current directory unless another is provided
|
|
168
|
+
#
|
|
169
|
+
# @param stack_confs [::Hash] hash specifying the stack config for the instance
|
|
170
|
+
# @param stack [String] name of the stack to configure
|
|
171
|
+
# @param conf_file [String] path to a stack config file to use for configuration
|
|
172
|
+
# @param dir [String] path to the directory to run Pulumi commands in
|
|
173
|
+
# @param is_secret [Boolean] specify true to set the given stack config as secrets
|
|
174
|
+
# @return [void]
|
|
93
175
|
def configure(stack_confs, stack, conf_file, dir = '', is_secret: false)
|
|
94
176
|
secret = is_secret ? '--secret' : ''
|
|
95
|
-
|
|
177
|
+
config_flag = config_file(conf_file, flag: true)
|
|
178
|
+
base_cmd = "config set #{secret} -s #{stack} #{dir} #{config_flag}"
|
|
96
179
|
|
|
97
180
|
stack_confs.each do |namespace, stack_settings|
|
|
98
181
|
stack_settings.each do |key, val|
|
|
@@ -104,59 +187,127 @@ module Kitchen
|
|
|
104
187
|
end
|
|
105
188
|
end
|
|
106
189
|
|
|
190
|
+
# Refreshes a stack's config on the specified config file
|
|
191
|
+
#
|
|
192
|
+
# @param stack [String] name of the stack being refreshed
|
|
193
|
+
# @param conf_file [String] path to a stack config file to use for configuration
|
|
194
|
+
# @param dir [String] path to the directory to run Pulumi commands in
|
|
195
|
+
# @return [void]
|
|
107
196
|
def refresh_config(stack, conf_file, dir = '')
|
|
108
197
|
::Kitchen::Pulumi::ShellOut.run(
|
|
109
|
-
cmd: "config refresh -s #{stack} #{dir} #{conf_file}",
|
|
198
|
+
cmd: "config refresh -s #{stack} #{dir} #{config_file(conf_file, flag: true)}",
|
|
110
199
|
logger: logger,
|
|
111
200
|
)
|
|
112
201
|
rescue ::Kitchen::Pulumi::Error => e
|
|
113
202
|
puts 'Continuing...' if e.message.match?(/no previous deployment/)
|
|
114
203
|
end
|
|
115
204
|
|
|
116
|
-
|
|
205
|
+
# Get the value of the config file to use, if set on instance or provided as param,
|
|
206
|
+
# optionally as a command line flag `--config-file`
|
|
207
|
+
#
|
|
208
|
+
# @param conf_file [String] path to a stack config file to use for configuration
|
|
209
|
+
# @param flag [Boolean] specify true to prepend '--config-file ' to the config file
|
|
210
|
+
# @return [String] the path to the config file or its corresponding CLI flag
|
|
211
|
+
def config_file(conf_file = '', flag: false)
|
|
117
212
|
file = conf_file.empty? ? config_config_file : conf_file
|
|
118
213
|
return '' if File.directory?(file) || file.empty?
|
|
119
214
|
|
|
120
|
-
"--config-file #{file}"
|
|
215
|
+
return "--config-file #{file}" if flag
|
|
216
|
+
|
|
217
|
+
file
|
|
121
218
|
end
|
|
122
219
|
|
|
220
|
+
# Updates a stack via `pulumi up` according to instance attributes
|
|
221
|
+
#
|
|
222
|
+
# @param (see #refresh_config)
|
|
223
|
+
# @return [void]
|
|
123
224
|
def update_stack(stack, conf_file, dir = '')
|
|
225
|
+
base_cmd = "up -y -r --show-config -s #{stack} #{dir}"
|
|
124
226
|
::Kitchen::Pulumi::ShellOut.run(
|
|
125
|
-
cmd: "
|
|
227
|
+
cmd: "#{base_cmd} #{config_file(conf_file, flag: true)}",
|
|
126
228
|
logger: logger,
|
|
127
229
|
)
|
|
128
230
|
end
|
|
129
231
|
|
|
130
|
-
|
|
232
|
+
# Evolves a stack via successive calls to `pulumi config set` and `pulumi up`
|
|
233
|
+
# according to the `stack_evolution` instance attribute, if set. This permits
|
|
234
|
+
# testing stack config changes over time.
|
|
235
|
+
#
|
|
236
|
+
# @param (see #refresh_config)
|
|
237
|
+
# @param config_only [Boolean] specify true to prevent running `pulumi up`
|
|
238
|
+
# @return [void]
|
|
239
|
+
def evolve_stack(stack, conf_file, dir = '', config_only: false)
|
|
131
240
|
config_stack_evolution.each do |evolution|
|
|
132
|
-
|
|
241
|
+
new_conf_file = config_file(evolution.fetch(:config_file, ''))
|
|
133
242
|
new_stack_confs = evolution.fetch(:config, {})
|
|
134
243
|
new_stack_secrets = evolution.fetch(:secrets, {})
|
|
135
244
|
|
|
245
|
+
rewrite_config_file(new_conf_file, conf_file)
|
|
246
|
+
|
|
136
247
|
configure(new_stack_confs, stack, conf_file, dir)
|
|
137
248
|
configure(new_stack_secrets, stack, conf_file, dir, is_secret: true)
|
|
138
|
-
update_stack(stack, conf_file, dir)
|
|
249
|
+
update_stack(stack, conf_file, dir) unless config_only
|
|
139
250
|
end
|
|
140
251
|
end
|
|
141
252
|
|
|
253
|
+
# Rewrites a temporary config file by merging the contents of the new config file
|
|
254
|
+
# into the old config file. This is used during stack evolution to ensure that
|
|
255
|
+
# stack config changes for each evolution step are implemented correctly if the
|
|
256
|
+
# user has provided a new config file to use for a step.
|
|
257
|
+
#
|
|
258
|
+
# @param new_conf_file [String] the path to the new config file to use
|
|
259
|
+
# @param old_conf_file [String] the path to the config file to overwrite
|
|
260
|
+
# @return [void]
|
|
261
|
+
def rewrite_config_file(new_conf_file, old_conf_file)
|
|
262
|
+
return if new_conf_file.empty?
|
|
263
|
+
|
|
264
|
+
old_conf = YAML.load_file(old_conf_file)
|
|
265
|
+
new_conf_file = File.join(config_directory, new_conf_file)
|
|
266
|
+
return unless File.exist?(new_conf_file)
|
|
267
|
+
|
|
268
|
+
new_conf = old_conf.deep_merge(YAML.load_file(new_conf_file))
|
|
269
|
+
File.write(old_conf_file, new_conf.to_yaml)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# Retrieves the fully resolved stack inputs based on the current configuration
|
|
273
|
+
# of the stack via `pulumi config`
|
|
274
|
+
#
|
|
275
|
+
# @param block [Block] block to run with stack inputs yielded to it
|
|
276
|
+
#
|
|
277
|
+
# for block {|stack_inputs| ... }
|
|
278
|
+
# @yield [stack_inputs] yields a hash of stack inputs
|
|
279
|
+
#
|
|
280
|
+
# @raise [Kitchen::ActionFailed] if an error occurs retrieving stack inputs
|
|
281
|
+
# @return [self]
|
|
142
282
|
def stack_inputs(&block)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
283
|
+
update({}, config_only: true) do |temp_conf_file|
|
|
284
|
+
::Kitchen::Pulumi::Command::Input.run(
|
|
285
|
+
directory: config_directory,
|
|
286
|
+
stack: stack,
|
|
287
|
+
conf_file: config_file(temp_conf_file, flag: true),
|
|
288
|
+
logger: logger,
|
|
289
|
+
&block
|
|
290
|
+
)
|
|
291
|
+
end
|
|
150
292
|
|
|
151
293
|
self
|
|
152
294
|
rescue ::Kitchen::Pulumi::Error => e
|
|
153
295
|
raise ::Kitchen::ActionFailed, e.message
|
|
154
296
|
end
|
|
155
297
|
|
|
298
|
+
# Retrieves stack outputs via `pulumi stack output`
|
|
299
|
+
#
|
|
300
|
+
# @param block [Block] block to run with stack outputs yielded to it
|
|
301
|
+
#
|
|
302
|
+
# for block {|stack_outputs| ... }
|
|
303
|
+
# @yield [stack_outputs] yields a hash of stack outputs
|
|
304
|
+
#
|
|
305
|
+
# @raise [Kitchen::ActionFailed] if an error occurs retrieving stack outputs
|
|
306
|
+
# @return [self]
|
|
156
307
|
def stack_outputs(&block)
|
|
157
308
|
::Kitchen::Pulumi::Command::Output.run(
|
|
158
309
|
directory: config_directory,
|
|
159
|
-
stack:
|
|
310
|
+
stack: stack,
|
|
160
311
|
logger: logger,
|
|
161
312
|
&block
|
|
162
313
|
)
|
|
@@ -165,6 +316,14 @@ module Kitchen
|
|
|
165
316
|
rescue ::Kitchen::Pulumi::Error => e
|
|
166
317
|
raise ::Kitchen::ActionFailed, e.message
|
|
167
318
|
end
|
|
319
|
+
|
|
320
|
+
private
|
|
321
|
+
|
|
322
|
+
# @return [Logger] the common logger
|
|
323
|
+
# @api private
|
|
324
|
+
def logger
|
|
325
|
+
Kitchen.logger
|
|
326
|
+
end
|
|
168
327
|
end
|
|
169
328
|
end
|
|
170
329
|
end
|
|
@@ -5,15 +5,25 @@ require 'kitchen/provisioner/base'
|
|
|
5
5
|
require 'kitchen/pulumi/configurable'
|
|
6
6
|
|
|
7
7
|
module Kitchen
|
|
8
|
+
# This namespace is defined by Kitchen.
|
|
9
|
+
#
|
|
10
|
+
# @see https://www.rubydoc.info/gems/test-kitchen/Kitchen/Provisioner
|
|
8
11
|
module Provisioner
|
|
9
|
-
#
|
|
10
|
-
# run kitchen converge
|
|
12
|
+
# Provisioner class whose call method is invoked when users
|
|
13
|
+
# run `kitchen converge`
|
|
14
|
+
#
|
|
15
|
+
# @author Jacob Learned
|
|
11
16
|
class Pulumi < ::Kitchen::Provisioner::Base
|
|
12
17
|
kitchen_provisioner_api_version 2
|
|
13
18
|
|
|
14
19
|
include ::Kitchen::Pulumi::Configurable
|
|
15
20
|
|
|
16
|
-
# Runs stack updates via the instance driver
|
|
21
|
+
# Runs stack updates via the instance driver which shells out
|
|
22
|
+
# to `pulumi up`
|
|
23
|
+
#
|
|
24
|
+
# @param state [::Hash] the current kitchen state
|
|
25
|
+
# @raise [Kitchen::ActionFailed] if an error occurs during update
|
|
26
|
+
# @return void
|
|
17
27
|
def call(state)
|
|
18
28
|
instance.driver.update(state)
|
|
19
29
|
rescue ::Kitchen::Pulumi::Error => e
|
data/lib/kitchen/pulumi.rb
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'tempfile'
|
|
4
|
+
|
|
3
5
|
# Global kitchen module
|
|
4
6
|
module Kitchen
|
|
5
7
|
# Namespace for Kitchen-Pulumi logic
|
|
8
|
+
# @author Jacob Learned
|
|
6
9
|
module Pulumi
|
|
10
|
+
# Copies the contents of the given config file to a temporary file and yields the
|
|
11
|
+
# path of the temporary file to the block given
|
|
12
|
+
#
|
|
13
|
+
# @param config_file [String] the path to the config file to copy into the temp file
|
|
14
|
+
#
|
|
15
|
+
# for block {|temp_conf| ... }
|
|
16
|
+
# @yield [temp_conf] gives the path to the temporary config file
|
|
17
|
+
def self.with_temp_conf(config_file = '')
|
|
18
|
+
temp_conf = Tempfile.new(['kitchen-pulumi', '.yaml'])
|
|
19
|
+
|
|
20
|
+
if config_file.empty?
|
|
21
|
+
yield('') if block_given?
|
|
22
|
+
else
|
|
23
|
+
begin
|
|
24
|
+
IO.copy_stream(config_file, temp_conf.path)
|
|
25
|
+
yield(temp_conf.path) if block_given?
|
|
26
|
+
ensure
|
|
27
|
+
temp_conf.close
|
|
28
|
+
temp_conf.unlink
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
7
32
|
end
|
|
8
33
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
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
|
+
# preserved after stack is removed with `pulumi stack rm`
|
|
13
|
+
# during destroy.
|
|
14
|
+
module PreserveConfig
|
|
15
|
+
def self.included(plugin_class)
|
|
16
|
+
definer = ConfigAttributeDefiner.new(
|
|
17
|
+
attribute: self,
|
|
18
|
+
schema: ConfigSchemas::Boolean,
|
|
19
|
+
)
|
|
20
|
+
definer.define(plugin_class: plugin_class)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.to_sym
|
|
24
|
+
:preserve_config
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
extend ConfigAttributeCacher
|
|
28
|
+
|
|
29
|
+
def config_preserve_config_default_value
|
|
30
|
+
false
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -8,8 +8,8 @@ require 'kitchen/pulumi/config_attribute_definer'
|
|
|
8
8
|
module Kitchen
|
|
9
9
|
module Pulumi
|
|
10
10
|
module ConfigAttribute
|
|
11
|
-
# Attribute used to specify the
|
|
12
|
-
module
|
|
11
|
+
# Attribute used to specify the secrets provider a stack should use
|
|
12
|
+
module SecretsProvider
|
|
13
13
|
def self.included(plugin_class)
|
|
14
14
|
definer = ConfigAttributeDefiner.new(
|
|
15
15
|
attribute: self,
|
|
@@ -19,12 +19,12 @@ module Kitchen
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def self.to_sym
|
|
22
|
-
:
|
|
22
|
+
:secrets_provider
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
extend ConfigAttributeCacher
|
|
26
26
|
|
|
27
|
-
def
|
|
27
|
+
def config_secrets_provider_default_value
|
|
28
28
|
''
|
|
29
29
|
end
|
|
30
30
|
end
|
|
@@ -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/config_attribute_definer'
|
|
7
|
+
|
|
8
|
+
module Kitchen
|
|
9
|
+
module Pulumi
|
|
10
|
+
module ConfigAttribute
|
|
11
|
+
# Attribute used to override the stack name to use for the stack
|
|
12
|
+
# created for an instance.
|
|
13
|
+
module TestStackName
|
|
14
|
+
def self.included(plugin_class)
|
|
15
|
+
definer = ConfigAttributeDefiner.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
|
+
:test_stack_name
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
extend ConfigAttributeCacher
|
|
27
|
+
|
|
28
|
+
def config_test_stack_name_default_value
|
|
29
|
+
''
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require 'dry/validation'
|
|
4
4
|
require 'kitchen/pulumi/config_schemas'
|
|
5
5
|
|
|
6
|
-
# rubocop:disable
|
|
6
|
+
# rubocop:disable Layout/LineLength
|
|
7
7
|
# rubocop:disable Metrics/BlockLength
|
|
8
8
|
module Kitchen
|
|
9
9
|
module Pulumi
|
|
@@ -574,4 +574,4 @@ module Kitchen
|
|
|
574
574
|
end
|
|
575
575
|
end
|
|
576
576
|
# rubocop:enable Metrics/BlockLength
|
|
577
|
-
# rubocop:enable
|
|
577
|
+
# rubocop:enable Layout/LineLength
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class ::Hash
|
|
4
|
+
def deep_merge(second)
|
|
5
|
+
merger = proc { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
|
|
6
|
+
merge(second.to_h, &merger)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -62,7 +62,7 @@ module Kitchen
|
|
|
62
62
|
attr_accessor :system_attributes_to_options
|
|
63
63
|
|
|
64
64
|
def initialize
|
|
65
|
-
self.system_attributes_to_options = ::Kitchen::Pulumi::InSpecOptionsMapper::SYSTEM_ATTRIBUTES_TO_OPTIONS.dup # rubocop:disable
|
|
65
|
+
self.system_attributes_to_options = ::Kitchen::Pulumi::InSpecOptionsMapper::SYSTEM_ATTRIBUTES_TO_OPTIONS.dup # rubocop:disable Layout/LineLength
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
end
|
|
@@ -9,7 +9,7 @@ module Kitchen
|
|
|
9
9
|
# Module orchestrating calls to the Pulumi CLI
|
|
10
10
|
module ShellOut
|
|
11
11
|
# Shells out to the Pulumi CLI
|
|
12
|
-
def self.run(cmd:, duration: 7200,
|
|
12
|
+
def self.run(cmd:, logger:, duration: 7200, &block)
|
|
13
13
|
cmds = Array(cmd)
|
|
14
14
|
block ||= ->(stdout) { stdout }
|
|
15
15
|
shell_out(commands: cmds, duration: duration, logger: logger, &block)
|
|
@@ -20,7 +20,7 @@ module Kitchen
|
|
|
20
20
|
raise(::Kitchen::Pulumi::Error, "Error: #{e.message}")
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
def self.shell_out(commands:, duration: 7200
|
|
23
|
+
def self.shell_out(commands:, logger:, duration: 7200)
|
|
24
24
|
commands.each do |command|
|
|
25
25
|
shell_out = ::Mixlib::ShellOut.new(
|
|
26
26
|
"pulumi #{command}",
|
|
@@ -38,19 +38,15 @@ module Kitchen
|
|
|
38
38
|
# @param inputs [#to_hash] the config inputs provided to a stack
|
|
39
39
|
# @param outputs [#to_hash] the outputs of the Pulumi stack under test.
|
|
40
40
|
def initialize(inputs:, outputs:)
|
|
41
|
-
@inputs = inputs.
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
@inputs.merge!(@inputs.
|
|
45
|
-
["input_#{key}", value]
|
|
46
|
-
end.to_h)
|
|
41
|
+
@inputs = inputs.transform_values do |value|
|
|
42
|
+
value.fetch('value', nil)
|
|
43
|
+
end
|
|
44
|
+
@inputs.merge!(@inputs.transform_keys { |key| "input_#{key}" })
|
|
47
45
|
|
|
48
46
|
@outputs = Hash[outputs].map do |key, value|
|
|
49
47
|
[key, value]
|
|
50
48
|
end.to_h
|
|
51
|
-
@outputs.merge!(@outputs.
|
|
52
|
-
["output_#{key}", value]
|
|
53
|
-
end.to_h)
|
|
49
|
+
@outputs.merge!(@outputs.transform_keys { |key| "output_#{key}" })
|
|
54
50
|
rescue ::KeyError => e
|
|
55
51
|
raise ::Kitchen::Pulumi::Error, "System attrs resolution failed\n#{e}"
|
|
56
52
|
end
|
|
@@ -13,7 +13,7 @@ module Kitchen
|
|
|
13
13
|
#
|
|
14
14
|
# @see https://www.rubydoc.info/gems/test-kitchen/Kitchen/Verifier
|
|
15
15
|
module Verifier
|
|
16
|
-
# The verifier utilizes the {https://www.inspec.io/ InSpec infrastructure
|
|
16
|
+
# The verifier utilizes the {https://www.inspec.io/ InSpec} infrastructure
|
|
17
17
|
# testing framework to verify the behaviour and
|
|
18
18
|
# state of resources in the Pulumi state.
|
|
19
19
|
#
|
|
@@ -63,7 +63,7 @@ module Kitchen
|
|
|
63
63
|
# :reek:MissingSafeMethod {
|
|
64
64
|
# exclude: [ finalize_config!, load_needed_dependencies! ]
|
|
65
65
|
# }
|
|
66
|
-
class Pulumi
|
|
66
|
+
class Pulumi < ::Kitchen::Verifier::Base
|
|
67
67
|
include ::Kitchen::Configurable
|
|
68
68
|
include ::Kitchen::Logging
|
|
69
69
|
include ::Kitchen::Pulumi::ConfigAttribute::Color
|
|
@@ -75,7 +75,7 @@ module Kitchen
|
|
|
75
75
|
attr_reader :inputs, :outputs
|
|
76
76
|
|
|
77
77
|
def initialize(configuration = {})
|
|
78
|
-
|
|
78
|
+
super(configuration)
|
|
79
79
|
self.inspec_options_mapper = ::Kitchen::Pulumi::InSpecOptionsMapper.new
|
|
80
80
|
self.error_messages = []
|
|
81
81
|
self.inputs = {}
|
|
@@ -100,7 +100,7 @@ module Kitchen
|
|
|
100
100
|
raise ::Kitchen::ActionFailed, e.message
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
-
#
|
|
103
|
+
# Checks the system and configuration for common errors.
|
|
104
104
|
#
|
|
105
105
|
# @param _kitchen_state [::Hash] the mutable Kitchen instance state.
|
|
106
106
|
# @return [Boolean] false
|
|
@@ -114,6 +114,10 @@ module Kitchen
|
|
|
114
114
|
attr_accessor :inspec_options_mapper, :error_messages
|
|
115
115
|
attr_writer :inputs, :outputs
|
|
116
116
|
|
|
117
|
+
# Raises an error immediately if the `fail_fast` config attribute is set on the
|
|
118
|
+
# or collects all errors until execution has ended verifier
|
|
119
|
+
#
|
|
120
|
+
# @return [void]
|
|
117
121
|
def handle_error(message:)
|
|
118
122
|
raise ::Kitchen::Pulumi::Error, message if config_fail_fast
|
|
119
123
|
|
|
@@ -121,6 +125,10 @@ module Kitchen
|
|
|
121
125
|
error_messages.push message
|
|
122
126
|
end
|
|
123
127
|
|
|
128
|
+
# Populates the `stack_inputs` and `stack_outputs` with the fully resolved stack
|
|
129
|
+
# inputs and outputs produced by the appropriate Pulumi commands
|
|
130
|
+
#
|
|
131
|
+
# @return [void]
|
|
124
132
|
def load_variables
|
|
125
133
|
instance.driver.stack_outputs do |outputs:|
|
|
126
134
|
self.outputs.replace(outputs)
|
|
@@ -151,6 +159,10 @@ module Kitchen
|
|
|
151
159
|
)
|
|
152
160
|
end
|
|
153
161
|
|
|
162
|
+
# Runs verification logic of the given system
|
|
163
|
+
#
|
|
164
|
+
# @param system [::Hash] the system to verify
|
|
165
|
+
# @return [void]
|
|
154
166
|
def verify(system:)
|
|
155
167
|
::Kitchen::Pulumi::System.new(
|
|
156
168
|
mapping: {
|
|
@@ -167,6 +179,10 @@ module Kitchen
|
|
|
167
179
|
handle_error message: e.message
|
|
168
180
|
end
|
|
169
181
|
|
|
182
|
+
# Runs verification logic for each system defined on the verifier's `systems` config
|
|
183
|
+
# attribute
|
|
184
|
+
#
|
|
185
|
+
# @return [void]
|
|
170
186
|
def verify_systems
|
|
171
187
|
config_systems.each do |system|
|
|
172
188
|
verify system: system
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kitchen-pulumi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jacob Learned
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-01-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: guard
|
|
@@ -44,42 +44,42 @@ dependencies:
|
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '0.
|
|
47
|
+
version: '0.13'
|
|
48
48
|
type: :development
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '0.
|
|
54
|
+
version: '0.13'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: pry-byebug
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '3.
|
|
61
|
+
version: '3.8'
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '3.
|
|
68
|
+
version: '3.8'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: rake
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
73
|
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
75
|
+
version: '13.0'
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
82
|
+
version: '13.0'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
84
|
name: rspec
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -128,14 +128,70 @@ dependencies:
|
|
|
128
128
|
requirements:
|
|
129
129
|
- - "~>"
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: '
|
|
131
|
+
version: '1.9'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '1.9'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: rubocop-rake
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "~>"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0.5'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0.5'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: rubocop-rspec
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - "~>"
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '2.1'
|
|
160
|
+
type: :development
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - "~>"
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '2.1'
|
|
167
|
+
- !ruby/object:Gem::Dependency
|
|
168
|
+
name: simplecov
|
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - "~>"
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '0.21'
|
|
132
174
|
type: :development
|
|
133
175
|
prerelease: false
|
|
134
176
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
177
|
requirements:
|
|
136
178
|
- - "~>"
|
|
137
179
|
- !ruby/object:Gem::Version
|
|
138
|
-
version: '0.
|
|
180
|
+
version: '0.21'
|
|
181
|
+
- !ruby/object:Gem::Dependency
|
|
182
|
+
name: yard
|
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - "~>"
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: '0.9'
|
|
188
|
+
type: :development
|
|
189
|
+
prerelease: false
|
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
191
|
+
requirements:
|
|
192
|
+
- - "~>"
|
|
193
|
+
- !ruby/object:Gem::Version
|
|
194
|
+
version: '0.9'
|
|
139
195
|
- !ruby/object:Gem::Dependency
|
|
140
196
|
name: logger
|
|
141
197
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -182,44 +238,62 @@ dependencies:
|
|
|
182
238
|
name: inspec
|
|
183
239
|
requirement: !ruby/object:Gem::Requirement
|
|
184
240
|
requirements:
|
|
185
|
-
- - "
|
|
241
|
+
- - ">="
|
|
186
242
|
- !ruby/object:Gem::Version
|
|
187
|
-
version: '3
|
|
243
|
+
version: '3'
|
|
244
|
+
- - "<"
|
|
245
|
+
- !ruby/object:Gem::Version
|
|
246
|
+
version: '5'
|
|
188
247
|
type: :runtime
|
|
189
248
|
prerelease: false
|
|
190
249
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
250
|
requirements:
|
|
192
|
-
- - "
|
|
251
|
+
- - ">="
|
|
193
252
|
- !ruby/object:Gem::Version
|
|
194
|
-
version: '3
|
|
253
|
+
version: '3'
|
|
254
|
+
- - "<"
|
|
255
|
+
- !ruby/object:Gem::Version
|
|
256
|
+
version: '5'
|
|
195
257
|
- !ruby/object:Gem::Dependency
|
|
196
258
|
name: json
|
|
197
259
|
requirement: !ruby/object:Gem::Requirement
|
|
198
260
|
requirements:
|
|
199
|
-
- - "
|
|
261
|
+
- - ">="
|
|
200
262
|
- !ruby/object:Gem::Version
|
|
201
|
-
version: 2.1
|
|
263
|
+
version: '2.1'
|
|
264
|
+
- - "<"
|
|
265
|
+
- !ruby/object:Gem::Version
|
|
266
|
+
version: '2.4'
|
|
202
267
|
type: :runtime
|
|
203
268
|
prerelease: false
|
|
204
269
|
version_requirements: !ruby/object:Gem::Requirement
|
|
205
270
|
requirements:
|
|
206
|
-
- - "
|
|
271
|
+
- - ">="
|
|
207
272
|
- !ruby/object:Gem::Version
|
|
208
|
-
version: 2.1
|
|
273
|
+
version: '2.1'
|
|
274
|
+
- - "<"
|
|
275
|
+
- !ruby/object:Gem::Version
|
|
276
|
+
version: '2.4'
|
|
209
277
|
- !ruby/object:Gem::Dependency
|
|
210
278
|
name: mixlib-shellout
|
|
211
279
|
requirement: !ruby/object:Gem::Requirement
|
|
212
280
|
requirements:
|
|
213
|
-
- - "
|
|
281
|
+
- - ">="
|
|
214
282
|
- !ruby/object:Gem::Version
|
|
215
283
|
version: '2.3'
|
|
284
|
+
- - "<"
|
|
285
|
+
- !ruby/object:Gem::Version
|
|
286
|
+
version: '4.0'
|
|
216
287
|
type: :runtime
|
|
217
288
|
prerelease: false
|
|
218
289
|
version_requirements: !ruby/object:Gem::Requirement
|
|
219
290
|
requirements:
|
|
220
|
-
- - "
|
|
291
|
+
- - ">="
|
|
221
292
|
- !ruby/object:Gem::Version
|
|
222
293
|
version: '2.3'
|
|
294
|
+
- - "<"
|
|
295
|
+
- !ruby/object:Gem::Version
|
|
296
|
+
version: '4.0'
|
|
223
297
|
- !ruby/object:Gem::Dependency
|
|
224
298
|
name: test-kitchen
|
|
225
299
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -243,7 +317,7 @@ dependencies:
|
|
|
243
317
|
description: 'Kitchen-Pulumi makes it easy to add integration tests to Pulumi-based
|
|
244
318
|
infrastructure projects.
|
|
245
319
|
|
|
246
|
-
|
|
320
|
+
'
|
|
247
321
|
email:
|
|
248
322
|
- jacobmlearned@gmail.com
|
|
249
323
|
executables: []
|
|
@@ -266,11 +340,13 @@ files:
|
|
|
266
340
|
- lib/kitchen/pulumi/config_attribute/directory.rb
|
|
267
341
|
- lib/kitchen/pulumi/config_attribute/fail_fast.rb
|
|
268
342
|
- lib/kitchen/pulumi/config_attribute/plugins.rb
|
|
343
|
+
- lib/kitchen/pulumi/config_attribute/preserve_config.rb
|
|
269
344
|
- lib/kitchen/pulumi/config_attribute/refresh_config.rb
|
|
270
345
|
- lib/kitchen/pulumi/config_attribute/secrets.rb
|
|
271
|
-
- lib/kitchen/pulumi/config_attribute/
|
|
346
|
+
- lib/kitchen/pulumi/config_attribute/secrets_provider.rb
|
|
272
347
|
- lib/kitchen/pulumi/config_attribute/stack_evolution.rb
|
|
273
348
|
- lib/kitchen/pulumi/config_attribute/systems.rb
|
|
349
|
+
- lib/kitchen/pulumi/config_attribute/test_stack_name.rb
|
|
274
350
|
- lib/kitchen/pulumi/config_attribute_cacher.rb
|
|
275
351
|
- lib/kitchen/pulumi/config_attribute_definer.rb
|
|
276
352
|
- lib/kitchen/pulumi/config_schemas.rb
|
|
@@ -284,6 +360,7 @@ files:
|
|
|
284
360
|
- lib/kitchen/pulumi/config_schemas/system.rb
|
|
285
361
|
- lib/kitchen/pulumi/config_schemas/systems.rb
|
|
286
362
|
- lib/kitchen/pulumi/configurable.rb
|
|
363
|
+
- lib/kitchen/pulumi/deep_merge.rb
|
|
287
364
|
- lib/kitchen/pulumi/error.rb
|
|
288
365
|
- lib/kitchen/pulumi/file_path_config_attribute_definer.rb
|
|
289
366
|
- lib/kitchen/pulumi/inspec.rb
|
|
@@ -300,7 +377,8 @@ files:
|
|
|
300
377
|
homepage: https://github.com/jacoblearned/kitchen-pulumi
|
|
301
378
|
licenses:
|
|
302
379
|
- MIT
|
|
303
|
-
metadata:
|
|
380
|
+
metadata:
|
|
381
|
+
yard.run: yri
|
|
304
382
|
post_install_message:
|
|
305
383
|
rdoc_options: []
|
|
306
384
|
require_paths:
|
|
@@ -309,14 +387,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
309
387
|
requirements:
|
|
310
388
|
- - ">="
|
|
311
389
|
- !ruby/object:Gem::Version
|
|
312
|
-
version: '
|
|
390
|
+
version: '2.6'
|
|
313
391
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
314
392
|
requirements:
|
|
315
|
-
- - "
|
|
393
|
+
- - ">="
|
|
316
394
|
- !ruby/object:Gem::Version
|
|
317
|
-
version:
|
|
395
|
+
version: '0'
|
|
318
396
|
requirements: []
|
|
319
|
-
rubygems_version: 3.
|
|
397
|
+
rubygems_version: 3.1.4
|
|
320
398
|
signing_key:
|
|
321
399
|
specification_version: 4
|
|
322
400
|
summary: Test-Kitchen plugins for Pulumi projects
|