sfn-parameters 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|