sfn-parameters 0.1.2 → 0.2.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/CHANGELOG.md +4 -0
- data/README.md +160 -28
- data/lib/sfn-parameters/command.rb +167 -0
- data/lib/sfn-parameters/config.rb +8 -0
- data/lib/sfn-parameters/infrastructure.rb +6 -2
- data/lib/sfn-parameters/safe/ssl.rb +97 -0
- data/lib/sfn-parameters/safe.rb +56 -0
- data/lib/sfn-parameters/stacks.rb +26 -0
- data/lib/sfn-parameters/utils.rb +37 -0
- data/lib/sfn-parameters/version.rb +1 -1
- data/lib/sfn-parameters.rb +10 -1
- data/sfn-parameters.gemspec +1 -1
- metadata +12 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa98393dbb5772d3b8058e38d07d604ad0bd14e4
|
4
|
+
data.tar.gz: 4eb0b9d98743d33e4cab470c4e0034fc6f38baa3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ab1532d9ed57477fe43dd480c91fa1cbdf047c12216be462f341b5db45265b58dc4570acb4c5b4b745df6e6f55dfb79af47ef0f76128bba51436ae5fdc1c786
|
7
|
+
data.tar.gz: dd16da459bc56af432aa2fa0528032f64b9210f16684ce409c21e5e32f1698f0a03a940127673ee03707a580606d41ecccc6eb9df97822211a1d849e869a0c6a
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -4,15 +4,25 @@ Provides automatic assignment of stack parameter information.
|
|
4
4
|
Currently supported workflows:
|
5
5
|
|
6
6
|
* Infrastructure Mode
|
7
|
+
* Stacks Mode
|
8
|
+
|
9
|
+
This callback also supports optional encryption of stack
|
10
|
+
parameter files. Current implementations:
|
11
|
+
|
12
|
+
* OpenSSL
|
7
13
|
|
8
14
|
## Usage
|
9
15
|
|
10
|
-
|
16
|
+
Make the callback available by adding it to the bundle via the
|
17
|
+
project's Gemfile:
|
11
18
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
19
|
+
~~~ruby
|
20
|
+
group :sfn do
|
21
|
+
gem 'sfn-parameters'
|
22
|
+
end
|
23
|
+
~~~
|
24
|
+
|
25
|
+
### Parameters
|
16
26
|
|
17
27
|
#### Enable
|
18
28
|
|
@@ -23,12 +33,39 @@ configuration file. First the callback must be enabled:
|
|
23
33
|
Configuration.new do
|
24
34
|
callbacks do
|
25
35
|
require ['sfn-parameters']
|
26
|
-
default ['parameters_infrastructure']
|
36
|
+
default ['parameters_infrastructure'] # or ['parameters_stacks']
|
27
37
|
end
|
28
38
|
end
|
29
39
|
~~~
|
30
40
|
|
31
|
-
####
|
41
|
+
#### File format
|
42
|
+
|
43
|
+
The basic structure of the file in JSON:
|
44
|
+
|
45
|
+
~~~json
|
46
|
+
{
|
47
|
+
"parameters": {},
|
48
|
+
"compile_parameters": {},
|
49
|
+
"apply_stacks": [],
|
50
|
+
"stacks": {}
|
51
|
+
}
|
52
|
+
~~~
|
53
|
+
|
54
|
+
Break down of the keys:
|
55
|
+
|
56
|
+
* `parameters` - Run time parameters sent to the orchestration API
|
57
|
+
* `compile_parameters` - Compile time parameters used to generate the template
|
58
|
+
* `apply_stacks` - List of stacks whose outputs should be applied
|
59
|
+
* `stacks`- Nested stack information
|
60
|
+
|
61
|
+
#### Infrastructure Mode
|
62
|
+
|
63
|
+
Infrastructure mode assumes a single template which describes
|
64
|
+
an entire infrastructure (generally via nested templates). A
|
65
|
+
configuration file can provide all information required for the
|
66
|
+
root stack, as well as all descendant stacks.
|
67
|
+
|
68
|
+
##### Configure
|
32
69
|
|
33
70
|
Some optional configuration is available via the `.sfn` file
|
34
71
|
to control the behavior of the callback:
|
@@ -45,7 +82,7 @@ end
|
|
45
82
|
* `directory` - Relative path from repository root to directory containing configuration files
|
46
83
|
* `destination` - Name of file holding configuration minus the extension
|
47
84
|
|
48
|
-
|
85
|
+
##### Functionality
|
49
86
|
|
50
87
|
One file will contain the configuration information required
|
51
88
|
for the stack operation (create/update). The location of this
|
@@ -61,26 +98,6 @@ The contents of the file will be processed using the bogo-config
|
|
61
98
|
library. This allows defining the file in a serialization format
|
62
99
|
(JSON, YAML, XML) or as a Ruby file.
|
63
100
|
|
64
|
-
#### File format
|
65
|
-
|
66
|
-
The basic structure of the file in JSON:
|
67
|
-
|
68
|
-
~~~json
|
69
|
-
{
|
70
|
-
"parameters": {},
|
71
|
-
"compile_parameters": {},
|
72
|
-
"apply_stacks": [],
|
73
|
-
"stacks": {}
|
74
|
-
}
|
75
|
-
~~~
|
76
|
-
|
77
|
-
Break down of the keys:
|
78
|
-
|
79
|
-
* `parameters` - Run time parameters sent to the orchestration API
|
80
|
-
* `compile_parameters` - Compile time parameters used to generate the template
|
81
|
-
* `apply_stacks` - List of stacks whose outputs should be applied
|
82
|
-
* `stacks`- Nested stack information
|
83
|
-
|
84
101
|
##### Example
|
85
102
|
|
86
103
|
~~~json
|
@@ -101,6 +118,121 @@ Break down of the keys:
|
|
101
118
|
}
|
102
119
|
~~~
|
103
120
|
|
121
|
+
#### Stacks Mode
|
122
|
+
|
123
|
+
The stacks mode assumes multiple stacks represented by multiple templates. Each stack
|
124
|
+
will have a corresponding parameters file which matches the stack name.
|
125
|
+
|
126
|
+
##### Configure
|
127
|
+
|
128
|
+
Some optional configuration is available via the `.sfn` file
|
129
|
+
to control the behavior of the callback:
|
130
|
+
|
131
|
+
~~~ruby
|
132
|
+
Configuration.new do
|
133
|
+
sfn_parameters do
|
134
|
+
directory 'stacks'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
~~~
|
138
|
+
|
139
|
+
* `directory` - Relative path from repository root to directory containing configuration files
|
140
|
+
|
141
|
+
##### Functionality
|
142
|
+
|
143
|
+
One file will contain the configuration information required
|
144
|
+
for a single stack operation (create/update). The location of this
|
145
|
+
file is generated using the configuration value provided
|
146
|
+
above with the stack name. For example, if working with a stack
|
147
|
+
named `my-test-stack`, the file will be expected at:
|
148
|
+
|
149
|
+
~~~
|
150
|
+
REPO_ROOT/stacks/my-test-stack.{rb,xml,json,yaml,yml}
|
151
|
+
~~~
|
152
|
+
|
153
|
+
The contents of the file will be processed using the bogo-config
|
154
|
+
library. This allows defining the file in a serialization format
|
155
|
+
(JSON, YAML, XML) or as a Ruby file.
|
156
|
+
|
157
|
+
##### Example
|
158
|
+
|
159
|
+
~~~json
|
160
|
+
{
|
161
|
+
"parameters": {
|
162
|
+
"stack_creator": "chris"
|
163
|
+
},
|
164
|
+
"apply_stacks": [
|
165
|
+
"networking"
|
166
|
+
]
|
167
|
+
}
|
168
|
+
~~~
|
169
|
+
|
170
|
+
### Encryption
|
171
|
+
|
172
|
+
This callback also supports encrypting stack parameter information for storage. The callback
|
173
|
+
adds a `parameters` command for handling encryption/decryption.
|
174
|
+
|
175
|
+
#### Configuration
|
176
|
+
|
177
|
+
Encryption configuration is controlled within the `.sfn` file:
|
178
|
+
|
179
|
+
~~~ruby
|
180
|
+
Configuration.new
|
181
|
+
sfn_parameters do
|
182
|
+
safe do
|
183
|
+
key 'MY-SECRET-KEY'
|
184
|
+
type 'ssl'
|
185
|
+
cipher 'AES-256-CBC'
|
186
|
+
iterations 10000
|
187
|
+
salt 'sfn~parameters~crypt~salt'
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
~~~
|
192
|
+
|
193
|
+
##### Default options
|
194
|
+
|
195
|
+
* `type` - Safe type for encryption (default: ssl)
|
196
|
+
|
197
|
+
##### OpenSSL options
|
198
|
+
|
199
|
+
* `key` - **REQUIRED** - Secret shared key
|
200
|
+
* `cipher` - Cipher to be used (default: 'AES-256-CBC')
|
201
|
+
* `iterations` - Modify computation length (default: 10000)
|
202
|
+
* `salt` - Random string (default: random bytes)
|
203
|
+
|
204
|
+
#### Commands
|
205
|
+
|
206
|
+
##### Create a new file
|
207
|
+
|
208
|
+
Create a new parameters file and automatically lock it when complete:
|
209
|
+
|
210
|
+
~~~
|
211
|
+
$ sfn parameters create my-test-stack
|
212
|
+
~~~
|
213
|
+
|
214
|
+
##### Update an existing file
|
215
|
+
|
216
|
+
Edit the file and only lock the file if it was previously locked:
|
217
|
+
|
218
|
+
~~~
|
219
|
+
$ sfn parameters edit my-test-stack
|
220
|
+
~~~
|
221
|
+
|
222
|
+
##### Lock an existing file
|
223
|
+
|
224
|
+
~~~
|
225
|
+
$ sfn parameters lock my-test-stack
|
226
|
+
~~~
|
227
|
+
|
228
|
+
##### Unlock an existing file
|
229
|
+
|
230
|
+
~~~
|
231
|
+
$ sfn parameters unlock my-test-stack
|
232
|
+
~~~
|
233
|
+
|
234
|
+
_NOTE: Full paths can also be used when defining parameters file._
|
235
|
+
|
104
236
|
# Info
|
105
237
|
|
106
238
|
* Repository: https://github.com/sparkleformation/sfn-parameters
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'sfn-parameters'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
class Command
|
5
|
+
# Parameters command
|
6
|
+
class Parameters < Command
|
7
|
+
|
8
|
+
include SfnParameters::Utils
|
9
|
+
include Sfn::CommandModule::Base
|
10
|
+
|
11
|
+
# Execute parameters action request
|
12
|
+
def execute!
|
13
|
+
action, item = arguments[0,2]
|
14
|
+
ui.info "Running parameters action #{ui.color(action.to_s, :bold)}"
|
15
|
+
case action.to_sym
|
16
|
+
when :lock
|
17
|
+
item = validate_item(item)
|
18
|
+
ui.print " Locking #{ui.color(item, :bold)}... "
|
19
|
+
content = load_json(File.read(item)).to_smash
|
20
|
+
if(content[:sfn_parameters_lock])
|
21
|
+
ui.puts ui.color('no-op', :yellow)
|
22
|
+
ui.warn "Item is already locked! (#{item})"
|
23
|
+
else
|
24
|
+
thing = lock_content(content)
|
25
|
+
val = format_json(thing)
|
26
|
+
File.write(item, val)
|
27
|
+
ui.puts ui.color('locked', :blue)
|
28
|
+
end
|
29
|
+
when :unlock
|
30
|
+
item = validate_item(item)
|
31
|
+
ui.print " Unlocking #{ui.color(item, :bold)}... "
|
32
|
+
content = load_json(File.read(item)).to_smash
|
33
|
+
if(content[:sfn_parameters_lock])
|
34
|
+
content = unlock_content(content)
|
35
|
+
content.delete(:sfn_lock_enabled)
|
36
|
+
File.write(item, format_json(content))
|
37
|
+
ui.puts ui.color('unlocked', :green)
|
38
|
+
else
|
39
|
+
ui.puts ui.color('no-op', :yellow)
|
40
|
+
ui.warn "Item is already unlocked! (#{item})"
|
41
|
+
end
|
42
|
+
when :show
|
43
|
+
item = validate_item(item)
|
44
|
+
content = load_json(File.read(item)).to_smash
|
45
|
+
if(content[:sfn_parameters_lock])
|
46
|
+
ui.print ui.color(' *', :bold)
|
47
|
+
ui.print " Unlocking #{ui.color(item, :bold)} for display... "
|
48
|
+
content = unlock_content(content)
|
49
|
+
content.delete(:sfn_lock_enabled)
|
50
|
+
ui.puts ui.color('unlocked', :green)
|
51
|
+
end
|
52
|
+
ui.puts format_json(content)
|
53
|
+
when :create, :edit
|
54
|
+
unless(ENV['EDITOR'])
|
55
|
+
raise ArgumentError.new '$EDITOR must be set for create/edit commands!'
|
56
|
+
end
|
57
|
+
begin
|
58
|
+
item = validate_item(item)
|
59
|
+
rescue ArgumentError
|
60
|
+
new_item = true
|
61
|
+
item = new_item(item)
|
62
|
+
end
|
63
|
+
FileUtils.mkdir_p(File.dirname(item))
|
64
|
+
tmp = Bogo::EphemeralFile.new('sfn-parameters')
|
65
|
+
content = new_item ? Smash.new : load_json(File.read(item)).to_smash
|
66
|
+
if(content[:sfn_parameters_lock])
|
67
|
+
ui.print ui.color(' *', :bold)
|
68
|
+
ui.print " Unlocking #{ui.color(item, :bold)} for edit... "
|
69
|
+
content = unlock_content(content)
|
70
|
+
ui.puts ui.color('unlocked', :green)
|
71
|
+
end
|
72
|
+
lock_enabled = content.delete(:sfn_lock_enabled) || new_item
|
73
|
+
tmp.write(format_json(content))
|
74
|
+
tmp.flush
|
75
|
+
system("#{ENV['EDITOR']} #{tmp.path}")
|
76
|
+
tmp.rewind
|
77
|
+
content = load_json(tmp.read).to_smash
|
78
|
+
ui.print ui.color(' *', :bold)
|
79
|
+
if(lock_enabled)
|
80
|
+
ui.print " Locking #{ui.color(item, :bold)} for storage... "
|
81
|
+
content = lock_content(content)
|
82
|
+
ui.puts ui.color('locked', :blue)
|
83
|
+
else
|
84
|
+
ui.puts " Storing #{ui.color(item, :bold)} for storage... #{ui.color('unlocked', :yellow)}"
|
85
|
+
end
|
86
|
+
File.write(item, format_json(content))
|
87
|
+
tmp.close
|
88
|
+
else
|
89
|
+
ArgumentError.new "Unsupported action received `#{action}`. " \
|
90
|
+
"Allowed: lock, unlock, show, create, edit"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Expand path for new item if required
|
95
|
+
#
|
96
|
+
# @param item [String]
|
97
|
+
# @return [String]
|
98
|
+
def new_item(item)
|
99
|
+
unless(item.include?(File::SEPARATOR))
|
100
|
+
prefixes = [
|
101
|
+
config.get(:sfn_parameters, :directory),
|
102
|
+
'infrastructure',
|
103
|
+
'stacks'
|
104
|
+
].compact
|
105
|
+
prefix = prefixes.find_all do |dir|
|
106
|
+
File.directory?(dir)
|
107
|
+
end
|
108
|
+
if(prefix.size > 1)
|
109
|
+
raise ArgumentError.new "Unable to auto-determine directory for item! Multiple directories found. " \
|
110
|
+
"(detected: #{prefix.join(', ')})"
|
111
|
+
elsif(prefix.empty?)
|
112
|
+
raise ArgumentError.new "No existing parameter directories found. Please create required directory. " \
|
113
|
+
"(checked: #{prefixes.join(', ')})"
|
114
|
+
end
|
115
|
+
File.join(prefix.first, "#{item}.json")
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Validate existence of requested item. Expand path
|
120
|
+
# if only name given
|
121
|
+
#
|
122
|
+
# @param item [String]
|
123
|
+
# @return [String]
|
124
|
+
def validate_item(item)
|
125
|
+
items = [
|
126
|
+
item,
|
127
|
+
File.join(
|
128
|
+
config.fetch(
|
129
|
+
:sfn_parameters, :directory, 'stacks'
|
130
|
+
),
|
131
|
+
item
|
132
|
+
),
|
133
|
+
File.join(
|
134
|
+
config.fetch(
|
135
|
+
:sfn_parameters, :directory, 'stacks'
|
136
|
+
),
|
137
|
+
"#{item}.json"
|
138
|
+
),
|
139
|
+
File.join(
|
140
|
+
config.fetch(
|
141
|
+
:sfn_parameters, :directory, 'infrastructure'
|
142
|
+
),
|
143
|
+
item
|
144
|
+
),
|
145
|
+
File.join(
|
146
|
+
config.fetch(
|
147
|
+
:sfn_parameters, :directory, 'infrastructure'
|
148
|
+
),
|
149
|
+
"#{item}.json"
|
150
|
+
)
|
151
|
+
]
|
152
|
+
valid = items.find_all do |file|
|
153
|
+
File.exist?(file)
|
154
|
+
end
|
155
|
+
if(valid.empty?)
|
156
|
+
raise ArgumentError.new "Failed to locate item `#{item}`!"
|
157
|
+
elsif(valid.size > 1)
|
158
|
+
raise ArgumentError.new "Multiple matches detected for item `#{item}`. " \
|
159
|
+
"(Matches: #{valid.join(', ')})"
|
160
|
+
else
|
161
|
+
valid.first
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -5,6 +5,9 @@ module Sfn
|
|
5
5
|
# Auto load stack parameters for infrastructure pattern
|
6
6
|
class ParametersInfrastructure < Callback
|
7
7
|
|
8
|
+
include Sfn::Utils::JSON
|
9
|
+
include SfnParameters::Utils
|
10
|
+
|
8
11
|
# Valid file extensions for configuration file
|
9
12
|
VALID_EXTENSIONS = ['.rb', '.xml', '.json', '.yaml', '.yml']
|
10
13
|
|
@@ -37,9 +40,10 @@ module Sfn
|
|
37
40
|
if(paths.size > 1)
|
38
41
|
raise ArgumentError.new "Multiple parameter file matches encountered! (#{paths.join(', ')})"
|
39
42
|
elsif(paths.empty?)
|
40
|
-
|
43
|
+
Smash.new
|
44
|
+
else
|
45
|
+
unlock_content(Bogo::Config.new(paths.first).data)
|
41
46
|
end
|
42
|
-
Bogo::Config.new(paths.first).data
|
43
47
|
end
|
44
48
|
|
45
49
|
# Process the given hash and set configuration values
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'sfn-parameters'
|
2
|
+
|
3
|
+
module SfnParameters
|
4
|
+
# Safe storage
|
5
|
+
class Safe
|
6
|
+
|
7
|
+
# OpenSSL based Safe implementation
|
8
|
+
class Ssl < Safe
|
9
|
+
|
10
|
+
# Default cipher
|
11
|
+
DEFAULT_CIPHER='AES-256-CBC'
|
12
|
+
# Maximum computation iteration length
|
13
|
+
CRYPT_ITER=10000
|
14
|
+
# Default length of generated key
|
15
|
+
CRYPT_KEY_LENGTH=32
|
16
|
+
|
17
|
+
# Create OpenSSL backed safe
|
18
|
+
#
|
19
|
+
# @param args [Hash]
|
20
|
+
# @option :args [String] :cipher name of cipher
|
21
|
+
# @option :args [String] :key shared key value
|
22
|
+
# @option :args [Integer] :iterations generation interation
|
23
|
+
# @option :args [String] :salt value for salting
|
24
|
+
# @option :args [Integer] :key_length length of generated key
|
25
|
+
# @return [self]
|
26
|
+
def initialize(*_)
|
27
|
+
super
|
28
|
+
unless(arguments[:salt])
|
29
|
+
arguments[:salt] = OpenSSL::Random.random_bytes(16)
|
30
|
+
end
|
31
|
+
unless(arguments[:key])
|
32
|
+
raise ArgumentError.new 'Required `:key` argument unset for `Safe::Ssl`!'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Lock a given value for storage
|
37
|
+
#
|
38
|
+
# @param value [String] value to lock
|
39
|
+
# @return [Hash] locked content in form {:iv, :content}
|
40
|
+
def lock(value)
|
41
|
+
cipher = build(arguments[:salt])
|
42
|
+
new_iv = cipher.random_iv
|
43
|
+
cipher.iv = new_iv
|
44
|
+
result = cipher.update(value) + cipher.final
|
45
|
+
Smash.new(
|
46
|
+
:iv => Base64.urlsafe_encode64(new_iv),
|
47
|
+
:cipher => arguments.fetch(:cipher, DEFAULT_CIPHER),
|
48
|
+
:content => Base64.urlsafe_encode64(result),
|
49
|
+
:salt => Base64.urlsafe_encode64(arguments[:salt]),
|
50
|
+
:sfn_parameters_lock => Bogo::Utility.snake(self.class.name.split('::').last)
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Unlock a given value for access
|
55
|
+
#
|
56
|
+
# @param value [Hash] content to unlock
|
57
|
+
# @option :value [String] :iv initialization vector value
|
58
|
+
# @option :value [String] :salt random salt value
|
59
|
+
# @option :value [String] :content stored content
|
60
|
+
# @return [String]
|
61
|
+
def unlock(value)
|
62
|
+
value = value.to_smash
|
63
|
+
o_cipher = arguments[:cipher]
|
64
|
+
arguments[:cipher] = value[:cipher] if value[:cipher]
|
65
|
+
cipher = build(
|
66
|
+
Base64.urlsafe_decode64(value[:salt]),
|
67
|
+
Base64.urlsafe_decode64(value[:iv])
|
68
|
+
)
|
69
|
+
arguments[:cipher] = o_cipher
|
70
|
+
string = Base64.urlsafe_decode64(value[:content])
|
71
|
+
cipher.update(string) + cipher.final
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
# Build a new cipher
|
77
|
+
#
|
78
|
+
# @param iv [String] initialization vector
|
79
|
+
# @param salt [String] random value
|
80
|
+
# @return [OpenSSL::Cipher]
|
81
|
+
def build(salt=nil, iv=nil)
|
82
|
+
cipher = OpenSSL::Cipher.new(arguments[:cipher] || DEFAULT_CIPHER)
|
83
|
+
iv ? cipher.decrypt : cipher.encrypt
|
84
|
+
key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(
|
85
|
+
arguments[:key],
|
86
|
+
salt,
|
87
|
+
arguments.fetch(:iterations, CRYPT_ITER),
|
88
|
+
arguments.fetch(:key_length, CRYPT_KEY_LENGTH)
|
89
|
+
)
|
90
|
+
cipher.iv = iv if iv
|
91
|
+
cipher.key = key
|
92
|
+
cipher
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'sfn-parameters'
|
2
|
+
|
3
|
+
module SfnParameters
|
4
|
+
# Safe storage
|
5
|
+
class Safe
|
6
|
+
|
7
|
+
autoload :Ssl, 'sfn-parameters/safe/ssl'
|
8
|
+
|
9
|
+
# @return [Hash] safe configuration
|
10
|
+
attr_reader :arguments
|
11
|
+
|
12
|
+
# Create a new safe
|
13
|
+
#
|
14
|
+
# @param args [Hash]
|
15
|
+
# @return [self]
|
16
|
+
def initialize(args={})
|
17
|
+
@arguments = args.to_smash
|
18
|
+
end
|
19
|
+
|
20
|
+
# Lock a given value for storage
|
21
|
+
#
|
22
|
+
# @param value [String] value to lock
|
23
|
+
# @return [Hash]
|
24
|
+
def lock(value)
|
25
|
+
raise NotImplementedError
|
26
|
+
end
|
27
|
+
|
28
|
+
# Unlock a given value for access
|
29
|
+
#
|
30
|
+
# @param value [Hash] content to unlock
|
31
|
+
# @return [String]
|
32
|
+
def unlock(value)
|
33
|
+
raise NotImplementedError
|
34
|
+
end
|
35
|
+
|
36
|
+
class << self
|
37
|
+
|
38
|
+
# Build a new safe instance
|
39
|
+
#
|
40
|
+
# @param args [Hash] arguments for safe instance
|
41
|
+
# @option args [String] :type type of safe
|
42
|
+
# @return [Safe]
|
43
|
+
def build(args={})
|
44
|
+
args = args.to_smash
|
45
|
+
type = Bogo::Utility.camel(args.fetch(:type, 'ssl'))
|
46
|
+
if(const_defined?(type))
|
47
|
+
const_get(type).new(args)
|
48
|
+
else
|
49
|
+
raise ArgumentError.new "Unknown safe type provided `#{type}`."
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'sfn-parameters'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
class Callback
|
5
|
+
# Auto load stack parameters for single stack pattern
|
6
|
+
class ParametersStacks < ParametersInfrastructure
|
7
|
+
|
8
|
+
# Load the configuration file
|
9
|
+
#
|
10
|
+
# @param stack_name [String]
|
11
|
+
# @return [Smash]
|
12
|
+
def load_file_for(stack_name)
|
13
|
+
root_path = config.fetch(:sfn_parameters, :directory, 'stacks')
|
14
|
+
paths = Dir.glob(File.join(root_path, "#{stack_name}{#{VALID_EXTENSIONS.join(',')}}")).map(&:to_s)
|
15
|
+
if(paths.size > 1)
|
16
|
+
raise ArgumentError.new "Multiple parameter file matches encountered! (#{paths.join(', ')})"
|
17
|
+
elsif(paths.empty?)
|
18
|
+
Smash.new
|
19
|
+
else
|
20
|
+
unlock_content(Bogo::Config.new(paths.first).data)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'sfn-parameters'
|
2
|
+
|
3
|
+
module SfnParameters
|
4
|
+
# Common helper methods
|
5
|
+
module Utils
|
6
|
+
|
7
|
+
# Lock the given content
|
8
|
+
#
|
9
|
+
# @param content [Hash] content to lock
|
10
|
+
# @return [Hash] locked content
|
11
|
+
def lock_content(content)
|
12
|
+
content = content.to_smash
|
13
|
+
content.merge!(:sfn_lock_enabled => true)
|
14
|
+
safe = SfnParameters::Safe.build(
|
15
|
+
config.fetch(:sfn_parameters, :safe, Smash.new)
|
16
|
+
)
|
17
|
+
safe.lock(dump_json(content))
|
18
|
+
end
|
19
|
+
|
20
|
+
# Unlock given content
|
21
|
+
#
|
22
|
+
# @param content [Hash] content to unlock
|
23
|
+
# @return [Hash] unlocked content
|
24
|
+
def unlock_content(content)
|
25
|
+
content = content.to_smash
|
26
|
+
if(content[:sfn_parameters_lock])
|
27
|
+
safe = SfnParameters::Safe.build(
|
28
|
+
config.fetch(:sfn_parameters, :safe, Smash.new)
|
29
|
+
)
|
30
|
+
load_json(safe.unlock(content)).to_smash.merge(:sfn_lock_enabled => true)
|
31
|
+
else
|
32
|
+
content
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
data/lib/sfn-parameters.rb
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module SfnParameters
|
4
|
+
autoload :Safe, 'sfn-parameters/safe'
|
5
|
+
autoload :Utils, 'sfn-parameters/utils'
|
6
|
+
end
|
7
|
+
|
1
8
|
require 'sfn-parameters/version'
|
2
9
|
require 'sfn-parameters/infrastructure'
|
3
|
-
|
10
|
+
require 'sfn-parameters/stacks'
|
11
|
+
require 'sfn-parameters/config'
|
12
|
+
require 'sfn-parameters/command'
|
data/sfn-parameters.gemspec
CHANGED
@@ -10,6 +10,6 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.description = 'SparkleFormation Parameters Callback'
|
11
11
|
s.license = 'Apache-2.0'
|
12
12
|
s.require_path = 'lib'
|
13
|
-
s.add_dependency 'sfn', '>=
|
13
|
+
s.add_dependency 'sfn', '>= 3.0', '< 4.0'
|
14
14
|
s.files = Dir['{lib,bin,docs}/**/*'] + %w(sfn-parameters.gemspec README.md CHANGELOG.md LICENSE)
|
15
15
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sfn-parameters
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sfn
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '3.0'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '4.0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: '3.0'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '4.0'
|
33
33
|
description: SparkleFormation Parameters Callback
|
34
34
|
email: code@chrisroberts.org
|
35
35
|
executables: []
|
@@ -40,7 +40,13 @@ files:
|
|
40
40
|
- LICENSE
|
41
41
|
- README.md
|
42
42
|
- lib/sfn-parameters.rb
|
43
|
+
- lib/sfn-parameters/command.rb
|
44
|
+
- lib/sfn-parameters/config.rb
|
43
45
|
- lib/sfn-parameters/infrastructure.rb
|
46
|
+
- lib/sfn-parameters/safe.rb
|
47
|
+
- lib/sfn-parameters/safe/ssl.rb
|
48
|
+
- lib/sfn-parameters/stacks.rb
|
49
|
+
- lib/sfn-parameters/utils.rb
|
44
50
|
- lib/sfn-parameters/version.rb
|
45
51
|
- sfn-parameters.gemspec
|
46
52
|
homepage: http://github.com/sparkleformation/sfn-parameters
|