simplygenius-atmos 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/simplygenius/atmos/config.rb +47 -24
- data/lib/simplygenius/atmos/generator.rb +3 -0
- data/lib/simplygenius/atmos/otp.rb +6 -9
- data/lib/simplygenius/atmos/plugin_manager.rb +2 -2
- data/lib/simplygenius/atmos/plugins/output_filter.rb +1 -1
- data/lib/simplygenius/atmos/plugins/prompt_notify.rb +1 -1
- data/lib/simplygenius/atmos/providers/aws/auth_manager.rb +14 -2
- data/lib/simplygenius/atmos/providers/aws/s3_secret_manager.rb +10 -5
- data/lib/simplygenius/atmos/terraform_executor.rb +14 -2
- data/lib/simplygenius/atmos/version.rb +1 -1
- data/templates/new/config/atmos/runtime.yml +9 -7
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02b47aaaf544e268b0d3a9a9d6a69d8165f165ef9e9e500753ec8c87787228b4
|
4
|
+
data.tar.gz: 673992076c584283ee340d683a5a0c5aa8d9c9b0c4203cac7c96250480a012a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4a7fc7d2c74988b22482c4252023fb4ecd1f0216bb8f28b0e802b5ee7a4532a4fa6f995cca60f11e7015545d20566463d577f3cb656240563436490a4c70237
|
7
|
+
data.tar.gz: 2396303b7e6ce14afc455597477be362f3ea77a3540d6187ec743efe2a2f48dcc8ab5f2fc7a2175da3ad2e5addeeb72f6b1dabaeb2ebc9d2a85262ad8a70cdd8
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
0.9.3 (02/12/2019)
|
2
|
+
------------------
|
3
|
+
|
4
|
+
* add the ability to use a prefix for scoping secrets [470556a](https://github.com/simplygenius/atmos/commit/470556a)
|
5
|
+
* add comment [b0592d5](https://github.com/simplygenius/atmos/commit/b0592d5)
|
6
|
+
* fix pro recipe source url [9ddb8a8](https://github.com/simplygenius/atmos/commit/9ddb8a8)
|
7
|
+
* handle flushing of data in plugin output handlers when streaming completes [e1e4707](https://github.com/simplygenius/atmos/commit/e1e4707)
|
8
|
+
* refactor secrets config into a more general user config file in users home directory [06875b7](https://github.com/simplygenius/atmos/commit/06875b7)
|
9
|
+
* expand warnings for missing aws auth [3ad6ec0](https://github.com/simplygenius/atmos/commit/3ad6ec0)
|
10
|
+
|
1
11
|
0.9.2 (12/01/2018)
|
2
12
|
------------------
|
3
13
|
|
@@ -16,6 +16,7 @@ module SimplyGenius
|
|
16
16
|
attr_accessor :atmos_env, :working_group,
|
17
17
|
:root_dir,
|
18
18
|
:config_file,
|
19
|
+
:user_config_file,
|
19
20
|
:tmp_root
|
20
21
|
|
21
22
|
def initialize(atmos_env, working_group = 'default')
|
@@ -23,6 +24,7 @@ module SimplyGenius
|
|
23
24
|
@working_group = working_group
|
24
25
|
@root_dir = File.expand_path(Dir.pwd)
|
25
26
|
@config_file = File.join(root_dir, "config", "atmos.yml")
|
27
|
+
@user_config_file = "~/.atmos.yml"
|
26
28
|
@tmp_root = File.join(root_dir, "tmp")
|
27
29
|
@included_configs = []
|
28
30
|
end
|
@@ -37,6 +39,12 @@ module SimplyGenius
|
|
37
39
|
return result
|
38
40
|
end
|
39
41
|
|
42
|
+
def []=(key, value)
|
43
|
+
load
|
44
|
+
result = @config.notation_put(key, value)
|
45
|
+
return result
|
46
|
+
end
|
47
|
+
|
40
48
|
def to_h
|
41
49
|
load
|
42
50
|
@config.to_hash
|
@@ -100,6 +108,17 @@ module SimplyGenius
|
|
100
108
|
end
|
101
109
|
end
|
102
110
|
|
111
|
+
def save_user_config_file(data, merge_to_existing: true)
|
112
|
+
logger.debug("Saving to user config file (merging=#{merge_to_existing}): #{user_config_file}")
|
113
|
+
|
114
|
+
if merge_to_existing
|
115
|
+
existing = load_file(user_config_file, SettingsHash.new)
|
116
|
+
data = config_merge(existing, data, ["saving #{user_config_file}"])
|
117
|
+
end
|
118
|
+
File.write(user_config_file, YAML.dump(data.to_hash))
|
119
|
+
File.chmod(0600, user_config_file)
|
120
|
+
end
|
121
|
+
|
103
122
|
private
|
104
123
|
|
105
124
|
INTERP_PATTERN = /(\#\{([^\}]+)\})/
|
@@ -164,15 +183,7 @@ module SimplyGenius
|
|
164
183
|
logger.debug("Expanded pattern: #{pattern}")
|
165
184
|
|
166
185
|
Dir[pattern].each do |f|
|
167
|
-
|
168
|
-
data = YAML.load_file(f)
|
169
|
-
if ! data.is_a?(Hash)
|
170
|
-
logger.debug("Skipping non-hash config file: #{f}")
|
171
|
-
else
|
172
|
-
h = SettingsHash.new(data)
|
173
|
-
config = config_merge(config, h, [f])
|
174
|
-
@included_configs << f
|
175
|
-
end
|
186
|
+
config = load_file(f, config)
|
176
187
|
end
|
177
188
|
end
|
178
189
|
|
@@ -182,16 +193,8 @@ module SimplyGenius
|
|
182
193
|
def load_submap(relative_root, group, name, config)
|
183
194
|
submap_dir = File.join(relative_root, 'atmos', group)
|
184
195
|
submap_file = File.join(submap_dir, "#{name}.yml")
|
185
|
-
|
186
|
-
|
187
|
-
data = YAML.load_file(submap_file)
|
188
|
-
if ! data.is_a?(Hash)
|
189
|
-
logger.debug("Skipping non-hash config file: #{submap_file}")
|
190
|
-
else
|
191
|
-
h = SettingsHash.new({group => {name => data}})
|
192
|
-
config = config_merge(config, h, [submap_file])
|
193
|
-
@included_configs << submap_file
|
194
|
-
end
|
196
|
+
config = load_file(submap_file, config) do |d|
|
197
|
+
SettingsHash.new({group => {name => d}})
|
195
198
|
end
|
196
199
|
|
197
200
|
begin
|
@@ -209,15 +212,12 @@ module SimplyGenius
|
|
209
212
|
|
210
213
|
logger.debug("Atmos env: #{atmos_env}")
|
211
214
|
|
215
|
+
|
212
216
|
if ! File.exist?(config_file)
|
213
217
|
logger.warn "Could not find an atmos config file at: #{config_file}"
|
214
218
|
@full_config = SettingsHash.new
|
215
219
|
else
|
216
|
-
|
217
|
-
data = YAML.load_file(config_file)
|
218
|
-
raise ArgumentError.new("Invalid main config file (not hash-like): #{config_file}") if ! data.is_a?(Hash)
|
219
|
-
@full_config = SettingsHash.new(data)
|
220
|
-
@included_configs << config_file
|
220
|
+
@full_config = load_file(config_file, SettingsHash.new)
|
221
221
|
end
|
222
222
|
|
223
223
|
@full_config = load_config_sources(File.dirname(config_file), @full_config, *Array(@full_config.notation_get("atmos.config_sources")))
|
@@ -227,6 +227,10 @@ module SimplyGenius
|
|
227
227
|
@full_config = load_submap(File.dirname(config_file), 'providers', provider_name, @full_config)
|
228
228
|
@full_config = load_submap(File.dirname(config_file), 'environments', atmos_env, @full_config)
|
229
229
|
|
230
|
+
@user_config_file = @full_config.notation_get("atmos.user_config") || @user_config_file
|
231
|
+
@user_config_file = File.expand_path(@user_config_file)
|
232
|
+
@full_config = load_file(user_config_file, @full_config)
|
233
|
+
|
230
234
|
global = SettingsHash.new(@full_config.reject {|k, v| ['providers', 'environments'].include?(k) })
|
231
235
|
conf = config_merge(global, {
|
232
236
|
atmos_env: atmos_env,
|
@@ -237,6 +241,25 @@ module SimplyGenius
|
|
237
241
|
end
|
238
242
|
end
|
239
243
|
|
244
|
+
def load_file(file, config=SettingsHash.new, &block)
|
245
|
+
if File.exist?(file)
|
246
|
+
logger.debug("Loading atmos config file #{file}")
|
247
|
+
data = YAML.load_file(file)
|
248
|
+
if ! data.is_a?(Hash)
|
249
|
+
logger.debug("Skipping invalid atmos config file (not hash-like): #{file}")
|
250
|
+
else
|
251
|
+
data = SettingsHash.new(data)
|
252
|
+
data = block.call(data) if block
|
253
|
+
config = config_merge(config, data, [file])
|
254
|
+
@included_configs << file
|
255
|
+
end
|
256
|
+
else
|
257
|
+
logger.debug "Could not find an atmos config file at: #{file}"
|
258
|
+
end
|
259
|
+
|
260
|
+
config
|
261
|
+
end
|
262
|
+
|
240
263
|
def expand(config, obj)
|
241
264
|
case obj
|
242
265
|
when Hash
|
@@ -51,6 +51,9 @@ module SimplyGenius
|
|
51
51
|
|
52
52
|
end
|
53
53
|
|
54
|
+
# TODO: return all context so the calling template can see answers to
|
55
|
+
# template questions to use in customizing its output (e.g. service
|
56
|
+
# needs cluster name and ec2 backed state)
|
54
57
|
return visited_templates
|
55
58
|
end
|
56
59
|
|
@@ -10,13 +10,9 @@ module SimplyGenius
|
|
10
10
|
include GemLogger::LoggerSupport
|
11
11
|
|
12
12
|
def initialize
|
13
|
-
@
|
14
|
-
@
|
15
|
-
|
16
|
-
@secret_store = SettingsHash.new(yml_hash)
|
17
|
-
@secret_store[Atmos.config[:org]] ||= {}
|
18
|
-
@secret_store[Atmos.config[:org]][:otp] ||= {}
|
19
|
-
@scoped_secret_store = @secret_store[Atmos.config[:org]][:otp]
|
13
|
+
@scoped_path = "atmos.otp.#{Atmos.config[:org]}"
|
14
|
+
Atmos.config[@scoped_path] ||= {}
|
15
|
+
@scoped_secret_store = Atmos.config[@scoped_path]
|
20
16
|
end
|
21
17
|
|
22
18
|
def add(name, secret)
|
@@ -32,8 +28,9 @@ module SimplyGenius
|
|
32
28
|
end
|
33
29
|
|
34
30
|
def save
|
35
|
-
|
36
|
-
|
31
|
+
data = SettingsHash.new
|
32
|
+
data.notation_put(@scoped_path, @scoped_secret_store)
|
33
|
+
Atmos.config.save_user_config_file(data)
|
37
34
|
end
|
38
35
|
|
39
36
|
def generate(name)
|
@@ -91,10 +91,10 @@ module SimplyGenius
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def filter_block
|
94
|
-
return Proc.new do |data|
|
94
|
+
return Proc.new do |data, flushing: false|
|
95
95
|
@filters.inject(data) do |memo, obj|
|
96
96
|
begin
|
97
|
-
obj.filter(memo)
|
97
|
+
obj.filter(memo, flushing: flushing)
|
98
98
|
rescue StandardError => e
|
99
99
|
logger.log_exception e, "Output filter failed during filter: #{obj.class}"
|
100
100
|
memo
|
@@ -25,8 +25,20 @@ module SimplyGenius
|
|
25
25
|
profile = system_env['AWS_PROFILE']
|
26
26
|
key = system_env['AWS_ACCESS_KEY_ID']
|
27
27
|
secret = system_env['AWS_SECRET_ACCESS_KEY']
|
28
|
-
|
29
|
-
|
28
|
+
# dont warn if default profile
|
29
|
+
no_creds = ::Aws::SharedCredentials.new.credentials.nil? rescue true
|
30
|
+
|
31
|
+
if profile.blank? && (key.blank? || secret.blank?) && no_creds
|
32
|
+
logger.warn("No AWS credentials are active in the environment nor shared credential store")
|
33
|
+
logger.warn("Run 'aws configure' to add some to the shared credential store")
|
34
|
+
end
|
35
|
+
if profile.present? && key.present?
|
36
|
+
logger.warn("Ignoring AWS_PROFILE because AWS_ACCESS_KEY_ID is set in the environment")
|
37
|
+
end
|
38
|
+
|
39
|
+
if Atmos.config["auth.bypass"]
|
40
|
+
logger.warn("Bypassing atmos aws authentication")
|
41
|
+
return block.call(Hash[system_env])
|
30
42
|
end
|
31
43
|
|
32
44
|
# Handle bootstrapping a new env account. Newly created organization
|
@@ -13,26 +13,31 @@ module SimplyGenius
|
|
13
13
|
@provider = provider
|
14
14
|
logger.debug("Secrets config is: #{Atmos.config[:secret]}")
|
15
15
|
@bucket_name = Atmos.config[:secret][:bucket]
|
16
|
+
@bucket_prefix = "#{Atmos.config[:secret][:prefix]}"
|
16
17
|
@encrypt = Atmos.config[:secret][:encrypt]
|
17
18
|
end
|
18
19
|
|
19
20
|
def set(key, value)
|
20
21
|
opts = {}
|
21
22
|
opts[:server_side_encryption] = "AES256" if @encrypt
|
22
|
-
bucket.object(key).put(body: value, **opts)
|
23
|
+
bucket.object(@bucket_prefix + key).put(body: value, **opts)
|
23
24
|
end
|
24
25
|
|
25
26
|
def get(key)
|
26
|
-
bucket.object(key).get.body.read
|
27
|
+
bucket.object(@bucket_prefix + key).get.body.read
|
27
28
|
end
|
28
29
|
|
29
30
|
def delete(key)
|
30
|
-
bucket.object(key).delete
|
31
|
+
bucket.object(@bucket_prefix + key).delete
|
31
32
|
end
|
32
33
|
|
33
34
|
def to_h
|
34
|
-
Hash[bucket.objects.collect {|o|
|
35
|
-
|
35
|
+
Hash[bucket.objects(prefix: @bucket_prefix).collect {|o|
|
36
|
+
key = o.key
|
37
|
+
if @bucket_prefix.present?
|
38
|
+
key = o.key.gsub(/^#{@bucket_prefix}/, '')
|
39
|
+
end
|
40
|
+
[key, o.get.body.read]
|
36
41
|
}]
|
37
42
|
end
|
38
43
|
|
@@ -259,18 +259,30 @@ module SimplyGenius
|
|
259
259
|
end
|
260
260
|
end
|
261
261
|
|
262
|
-
def pipe_stream(src, dest)
|
262
|
+
def pipe_stream(src, dest, &block)
|
263
263
|
Thread.new do
|
264
264
|
block_size = 1024
|
265
265
|
begin
|
266
266
|
while data = src.readpartial(block_size)
|
267
|
-
data =
|
267
|
+
data = block.call(data, flushing: false) if block
|
268
268
|
dest.write(data)
|
269
269
|
end
|
270
270
|
rescue IOError, EOFError => e
|
271
271
|
logger.log_exception(e, "Stream failure", level: :debug)
|
272
272
|
rescue Exception => e
|
273
273
|
logger.log_exception(e, "Stream failure")
|
274
|
+
ensure
|
275
|
+
begin
|
276
|
+
if block
|
277
|
+
data = block.call('', flushing: true)
|
278
|
+
dest.write(data)
|
279
|
+
end
|
280
|
+
dest.flush
|
281
|
+
rescue IOError, EOFError => e
|
282
|
+
logger.log_exception(e, "Stream failure while flushing", level: :debug)
|
283
|
+
rescue Exception => e
|
284
|
+
logger.log_exception(e, "Stream failure while flushing")
|
285
|
+
end
|
274
286
|
end
|
275
287
|
end
|
276
288
|
end
|
@@ -1,6 +1,11 @@
|
|
1
1
|
# Configuration for controlling the behavior of the atmos runtime
|
2
2
|
atmos:
|
3
3
|
|
4
|
+
# Configure the location of a user config file. This is where secrets are
|
5
|
+
# stored, e.g. OTP secrets and atmos pro auth token
|
6
|
+
#
|
7
|
+
user_config_file: ~/.atmos.yml
|
8
|
+
|
4
9
|
# Sources for atmos templates
|
5
10
|
# To circumvent the version lock and get the latest git master recipes, use the git
|
6
11
|
# location, e.g.:
|
@@ -9,11 +14,13 @@ atmos:
|
|
9
14
|
template_sources:
|
10
15
|
- name: atmos-recipes
|
11
16
|
location: https://github.com/simplygenius/atmos-recipes/archive/v#{atmos_version}.zip#atmos-recipes-#{atmos_version}
|
17
|
+
# To access the Atmos Pro recipes, add your atmos pro auth token to
|
18
|
+
# ~/.atmos.yml and uncomment below
|
12
19
|
#- name: atmos-pro-recipes
|
13
|
-
# location: https
|
20
|
+
# location: https://#{atmos.pro_auth_token}@releases.simplygenius.com/recipes/v#{atmos_version}.zip#atmos-pro-recipes-#{atmos_version}
|
14
21
|
|
15
22
|
# To get the atmos-pro gem, add the gem source like:
|
16
|
-
# gem sources -a https://
|
23
|
+
# gem sources -a https://ATMOS_PRO_AUTH_TOKEN@releases.simplygenius.com/gems/
|
17
24
|
# then install the gem:
|
18
25
|
# gem install simplygenius-atmos-pro
|
19
26
|
# then add simplygenius-atmos-pro to the plugins key below
|
@@ -36,11 +43,6 @@ atmos:
|
|
36
43
|
# Disable notify callbacks
|
37
44
|
disable: false
|
38
45
|
|
39
|
-
# Configure the integrated otp mechanism
|
40
|
-
otp:
|
41
|
-
# The file where otp secrets are stored
|
42
|
-
secret_file: ~/.atmos.yml
|
43
|
-
|
44
46
|
# Configure the template generator
|
45
47
|
generate:
|
46
48
|
# The file storing the record of each generated template
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simplygenius-atmos
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Conway
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -526,8 +526,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
526
526
|
- !ruby/object:Gem::Version
|
527
527
|
version: '0'
|
528
528
|
requirements: []
|
529
|
-
|
530
|
-
rubygems_version: 2.7.6
|
529
|
+
rubygems_version: 3.0.1
|
531
530
|
signing_key:
|
532
531
|
specification_version: 4
|
533
532
|
summary: Atmos provides a terraform scaffold for creating cloud system architectures
|