simplygenius-atmos 0.9.2 → 0.9.3
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 +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
|