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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e52d0f9fe95219722359232e6a8895b0cdbf23f99fbeda7ad8a48fdfe8a21397
4
- data.tar.gz: bb3c2e1d01fd2071ecc41e10b7622cb320e10dcd65ee90d254cc68465ee923db
3
+ metadata.gz: 02b47aaaf544e268b0d3a9a9d6a69d8165f165ef9e9e500753ec8c87787228b4
4
+ data.tar.gz: 673992076c584283ee340d683a5a0c5aa8d9c9b0c4203cac7c96250480a012a1
5
5
  SHA512:
6
- metadata.gz: 0da4f8dc5d90d23b6f5f7bbc348c4b5c1a431924e7763d369a5bbfd3528bae260a7e627294ad9aebc2e67e88cc3f7a5843a5b269b3c90fba88d7af37cf981bf5
7
- data.tar.gz: c8e92569daec346d3c9e2a963374fcefd9e04c23a3a6d298fc9b3474871e8edc2f899c0903a5bc19a032993ec53588d4683e2c08ad3c8471d1f8b45a64eed1fc
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
- logger.debug("Loading atmos config file: #{f}")
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
- if File.exist?(submap_file)
186
- logger.debug("Loading atmos #{group} config file: #{submap_file}")
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
- logger.debug("Loading atmos config file #{config_file}")
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
- @secret_file = Atmos.config["atmos.otp.secret_file"] || "~/.atmos.yml"
14
- @secret_file = File.expand_path(@secret_file)
15
- yml_hash = YAML.load_file(@secret_file) rescue Hash.new
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
- File.write(@secret_file, YAML.dump(@secret_store.to_hash))
36
- File.chmod(0600, @secret_file)
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
@@ -15,7 +15,7 @@ module SimplyGenius
15
15
  @context = context
16
16
  end
17
17
 
18
- def filter(data)
18
+ def filter(data, flushing: false)
19
19
  raise "not implemented"
20
20
  end
21
21
 
@@ -7,7 +7,7 @@ module SimplyGenius
7
7
 
8
8
  class PromptNotify < OutputFilter
9
9
 
10
- def filter(data)
10
+ def filter(data, flushing: false)
11
11
  if data =~ /^[\e\[\dm\s]*Enter a value:[\e\[\dm\s]*$/
12
12
  notify(message: "Terraform is waiting for user input")
13
13
  end
@@ -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
- if profile.blank? && (key.blank? || secret.blank?)
29
- logger.warn("An aws profile or key/secret should be supplied via the environment")
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
- [o.key, o.get.body.read]
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 = yield data if block_given?
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,5 +1,5 @@
1
1
  module SimplyGenius
2
2
  module Atmos
3
- VERSION = "0.9.2"
3
+ VERSION = "0.9.3"
4
4
  end
5
5
  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://YOUR_API_KEY@releases.simplygenius.com/recipes/v#{atmos_version}#atmos-pro-recipes-#{atmos_version}
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://YOUR_API_KEY@releases.simplygenius.com/gems/
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.2
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: 2018-12-01 00:00:00.000000000 Z
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
- rubyforge_project:
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