miasma-aws 0.3.22 → 0.3.24

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52b34565420604144ef097dabea4e434e2f413af448c3cd5041abeb6a3aab3f3
4
- data.tar.gz: e2de941c5c78209ba8ee8c737f5c6b43113ce2251818e53e610bd2c688d4ed78
3
+ metadata.gz: 156fe688026787b3fb537197d4a39d88666b840920442f8be9d6eb4e9a8b6708
4
+ data.tar.gz: 4e46c9280237574c37b1178e17cb65398bd4dd682031cc8698f6ec98293f4fa0
5
5
  SHA512:
6
- metadata.gz: 9eba4d31741db7cd4efa9277ab0b8c831bcf6081f56bd591e943f694084d26ab5adfbb8e130c755350c2dd052a9f059e46f8d32c75dfd26ac56432edf6509168
7
- data.tar.gz: f89d2ca230d03b1bbc0745bab06e2dffc23828e785926e75bd604e1784777c8c831feef8bf03077852e17383ebff9b7680c8245f6f26ea3da56b0bd04125cdb5
6
+ metadata.gz: c97d6b839d0310e1f4a28c10d7624b479c01245b289a0c224a06e7e6b8afa57a542b40b1d4d163da21e56a61940c660f7bed4fe42dbbbfab4de83e03e1087207
7
+ data.tar.gz: 8447055c12cef4ed6847887ed76f3244e7d0e63b7bd0db361168e2e7544fd12de6b2786ccad7ee91c52949558a35717933c8c6df71b4333f29ebb0a593228ef0
@@ -1,3 +1,7 @@
1
+ # v0.3.24
2
+ * [enhancement] Add logging output to generic and orchestration
3
+ * [fix] Attribute access for sts update check
4
+
1
5
  # v0.3.22
2
6
  * [fix] Resolve configuration loading issues (#58)
3
7
  * [enhancement] Update token refresh to within 10m of expiry (#59)
@@ -1,4 +1,4 @@
1
1
  module MiasmaAws
2
2
  # Current library version
3
- VERSION = Gem::Version.new("0.3.22")
3
+ VERSION = Gem::Version.new("0.3.24")
4
4
  end
@@ -56,6 +56,8 @@ module Miasma
56
56
 
57
57
  # HMAC helper class
58
58
  class Hmac
59
+ include Bogo::Logger::Helpers
60
+ logger_name("aws.hmac")
59
61
 
60
62
  # @return [OpenSSL::Digest]
61
63
  attr_reader :digest
@@ -82,6 +84,7 @@ module Miasma
82
84
  # @param content [String] content to digest
83
85
  # @return [String] hashed result
84
86
  def hexdigest_of(content)
87
+ logger.debug("generating hexdigest for `#{content.inspect}`")
85
88
  digest << content
86
89
  hash = digest.hexdigest
87
90
  digest.reset
@@ -94,11 +97,17 @@ module Miasma
94
97
  # @param key_override [Object]
95
98
  # @return [Object] signature
96
99
  def sign(data, key_override = nil)
97
- s_key = key_override || key
100
+ logger.debug("signing data `#{data.inspect}`")
101
+ s_key = key
102
+ if key_override
103
+ logger.debug("using key override for signing")
104
+ s_key = key_override
105
+ end
98
106
  if s_key.nil?
99
- raise ArgumentError.new("No key provided for signing data")
107
+ logger.error("no key provided to sign")
108
+ raise ArgumentError, "No key provided for signing data"
100
109
  end
101
- result = OpenSSL::HMAC.digest(digest, key_override || key, data.to_s)
110
+ result = OpenSSL::HMAC.digest(digest, s_key, data.to_s)
102
111
  digest.reset
103
112
  result
104
113
  end
@@ -109,6 +118,7 @@ module Miasma
109
118
  # @param key_override [Object]
110
119
  # @return [String] hex encoded signature
111
120
  def hex_sign(data, key_override = nil)
121
+ logger.debug("hex signing data `#{data.inspect}`")
112
122
  result = OpenSSL::HMAC.hexdigest(digest, key_override || key, data)
113
123
  digest.reset
114
124
  result
@@ -120,7 +130,7 @@ module Miasma
120
130
 
121
131
  # Create new instance
122
132
  def initialize(*args)
123
- raise NotImplementedError.new "This class should not be used directly!"
133
+ raise NotImplementedError, "This class should not be used directly!"
124
134
  end
125
135
 
126
136
  # Generate the signature
@@ -146,6 +156,8 @@ module Miasma
146
156
 
147
157
  # AWS signature version 4
148
158
  class SignatureV4 < Signature
159
+ include Bogo::Logger::Helpers
160
+ logger_name("aws.signature4")
149
161
 
150
162
  # @return [Hmac]
151
163
  attr_reader :hmac
@@ -201,6 +213,7 @@ module Miasma
201
213
  opts.merge(:body => "UNSIGNED-PAYLOAD")
202
214
  )
203
215
  params = opts[:params].merge("X-Amz-Signature" => signature)
216
+ logger.debug("url generation parameters `#{params.inspect}`")
204
217
  "https://#{opts[:headers]["Host"]}/#{path}?#{canonical_query(params)}"
205
218
  end
206
219
 
@@ -219,6 +232,7 @@ module Miasma
219
232
  can_req = build_canonical_request(http_method, path, opts)
220
233
  ),
221
234
  ].join("\n")
235
+ logger.debug("generating signature for `#{to_sign.inspect}`")
222
236
  signature = sign_request(to_sign)
223
237
  end
224
238
 
@@ -240,7 +254,9 @@ module Miasma
240
254
  )
241
255
  )
242
256
  )
243
- hmac.hex_sign(request, key)
257
+ signature = hmac.hex_sign(request, key)
258
+ logger.debug("generated signature `#{signature.inspect}`")
259
+ signature
244
260
  end
245
261
 
246
262
  # @return [String] signature algorithm
@@ -405,6 +421,7 @@ module Miasma
405
421
  # @return [Api]
406
422
  def api_for(type)
407
423
  memoize(type) do
424
+ logger.debug("building API for type `#{type}`")
408
425
  creds = attributes.dup
409
426
  creds.delete(:aws_host)
410
427
  Miasma.api(
@@ -423,6 +440,7 @@ module Miasma
423
440
  # @param creds [Hash]
424
441
  # @return [TrueClass]
425
442
  def custom_setup(creds)
443
+ logger.debug("running custom setup configuration updates")
426
444
  cred_file = load_aws_file(creds.fetch(
427
445
  :aws_credentials_file, aws_credentials_file
428
446
  ))
@@ -434,6 +452,7 @@ module Miasma
434
452
  profile_list = [profile].compact
435
453
  new_config_creds = Smash.new
436
454
  while profile
455
+ logger.debug("loading aws configuration profile: #{profile}")
437
456
  new_config_creds = config_file.fetch(profile, Smash.new).merge(
438
457
  new_config_creds
439
458
  )
@@ -446,6 +465,7 @@ module Miasma
446
465
  # Load any configuration available from the creds file
447
466
  new_creds = Smash.new
448
467
  profile_list.each do |profile|
468
+ logger.debug("loading aws credentials profile: #{profile}")
449
469
  new_creds = cred_file.fetch(profile, Smash.new).merge(
450
470
  new_creds
451
471
  )
@@ -475,6 +495,7 @@ module Miasma
475
495
  # @param creds [Hash]
476
496
  # @return [TrueClass]
477
497
  def after_setup(creds)
498
+ logger.debug("running after setup configuration updates")
478
499
  skip = self.class.attributes.keys.map(&:to_s)
479
500
  creds.each do |k, v|
480
501
  k = k.to_s
@@ -489,6 +510,7 @@ module Miasma
489
510
  # @param creds [Hash]
490
511
  # @return [TrueClass]
491
512
  def load_instance_credentials!(creds)
513
+ logger.debug("loading instance credentials")
492
514
  role = HTTP.get(
493
515
  [
494
516
  self.class.const_get(:INSTANCE_PROFILE_HOST),
@@ -506,7 +528,8 @@ module Miasma
506
528
  unless data.is_a?(Hash)
507
529
  begin
508
530
  data = MultiJson.load(data.to_s)
509
- rescue MultiJson::ParseError
531
+ rescue MultiJson::ParseError => err
532
+ logger.debug("failed to parse instance credentials - #{err}")
510
533
  data = {}
511
534
  end
512
535
  end
@@ -522,6 +545,7 @@ module Miasma
522
545
  # @param creds [Hash]
523
546
  # @return [TrueClass]
524
547
  def load_ecs_credentials!(creds)
548
+ logger.debug("loading ECS credentials")
525
549
  # As per docs ECS_TASK_PROFILE_PATH is defined as
526
550
  # /credential_provider_version/credentials?id=task_UUID
527
551
  # where AWS fills in the version and UUID.
@@ -535,7 +559,8 @@ module Miasma
535
559
  unless data.is_a?(Hash)
536
560
  begin
537
561
  data = MultiJson.load(data.to_s)
538
- rescue MultiJson::ParseError
562
+ rescue MultiJson::ParseError => err
563
+ logger.debug("failed to parse ECS credentials - #{err}")
539
564
  data = {}
540
565
  end
541
566
  end
@@ -564,6 +589,7 @@ module Miasma
564
589
  #
565
590
  # @return [String]
566
591
  def get_region
592
+ logger.debug("fetching region from meta-data service")
567
593
  az = HTTP.get(
568
594
  [
569
595
  self.class.const_get(:INSTANCE_PROFILE_HOST),
@@ -571,11 +597,13 @@ module Miasma
571
597
  ].join("/")
572
598
  ).body.to_s.strip
573
599
  az.sub!(/[a-zA-Z]+$/, "")
600
+ logger.debug("region from meta-data service: #{az}")
574
601
  az
575
602
  end
576
603
 
577
604
  def sts_mfa_session!(creds)
578
605
  if sts_mfa_session_update_required?(creds)
606
+ logger.debug("loading STS MFA session")
579
607
  sts = Miasma::Contrib::Aws::Api::Sts.new(
580
608
  :aws_access_key_id => creds[:aws_access_key_id],
581
609
  :aws_secret_access_key => creds[:aws_secret_access_key],
@@ -603,6 +631,7 @@ module Miasma
603
631
  # @return [TrueClass]
604
632
  def sts_assume_role!(creds)
605
633
  if sts_assume_role_update_required?(creds)
634
+ logger.debug("loading STS assume role")
606
635
  sts = Miasma::Contrib::Aws::Api::Sts.new(
607
636
  :aws_access_key_id => get_credential(:access_key_id, creds),
608
637
  :aws_secret_access_key => get_credential(:secret_access_key, creds),
@@ -630,6 +659,7 @@ module Miasma
630
659
  # @return [Smash]
631
660
  def load_aws_file(file_path)
632
661
  if File.exist?(file_path)
662
+ logger.debug("loading aws file @ #{file_path}")
633
663
  Smash.new.tap do |creds|
634
664
  key = :default
635
665
  File.readlines(file_path).each_with_index do |line, idx|
@@ -637,18 +667,16 @@ module Miasma
637
667
  next if line.empty? || line.start_with?("#")
638
668
  if line.start_with?("[")
639
669
  unless line.end_with?("]")
640
- raise ArgumentError.new(
670
+ raise ArgumentError,
641
671
  "Failed to parse aws file! (#{file_path} line #{idx + 1})"
642
- )
643
672
  end
644
673
  key = line.tr("[]", "").strip.sub(/^profile /, "")
645
674
  creds[key] = Smash.new
646
675
  else
647
676
  unless key
648
- raise ArgumentError.new(
677
+ raise ArgumentError,
649
678
  "Failed to parse aws file! (#{file_path} line #{idx + 1}) " \
650
679
  "- No section defined!"
651
- )
652
680
  end
653
681
  line_args = line.split("=", 2).map(&:strip)
654
682
  line_args.first.replace(
@@ -658,18 +686,16 @@ module Miasma
658
686
  )
659
687
  if line_args.last.start_with?('"')
660
688
  unless line_args.last.end_with?('"')
661
- raise ArgumentError.new(
689
+ raise ArgumentError,
662
690
  "Failed to parse aws file! (#{file_path} line #{idx + 1})"
663
- )
664
691
  end
665
692
  line_args.last.replace(line_args.last[1..-2]) # NOTE: strip quoted values
666
693
  end
667
694
  begin
668
695
  creds[key].merge!(Smash[*line_args])
669
696
  rescue => e
670
- raise ArgumentError.new(
697
+ raise ArgumentError,
671
698
  "Failed to parse aws file! (#{file_path} line #{idx + 1})"
672
- )
673
699
  end
674
700
  end
675
701
  end
@@ -760,6 +786,7 @@ module Miasma
760
786
  # @param request_args [Array]
761
787
  # @return [HTTP::Response]
762
788
  def make_request(connection, http_method, request_args)
789
+ logger.debug("making #{http_method.to_s.upcase} request - #{request_args.inspect}")
763
790
  dest, options = request_args
764
791
  path = URI.parse(dest).path
765
792
  options = options ? options.to_smash : Smash.new
@@ -813,12 +840,12 @@ module Miasma
813
840
  # Check if STS attribute requires update
814
841
  #
815
842
  # @param key [String, Symbol] token key
816
- # @param expiry_key [Time] expiry of token
843
+ # @param expiry_key [String, Symbol] expiry of token (Time instance)
817
844
  # @param args [Hash] overrides to check instead of instance values
818
845
  # @return [TrueClass, FalseClass]
819
846
  def sts_attribute_update_required?(key, expiry_key, args = {})
820
- if args.fetch(key, attributes[key])
821
- expiry = args.fetch(expiry_key, attributes[expiry_key])
847
+ if args.to_smash.fetch(key, attributes[key])
848
+ expiry = args.to_smash.fetch(expiry_key, attributes[expiry_key])
822
849
  expiry.nil? || expiry - self.class.const_get(:STS_TOKEN_EXPIRY_BUFFER) <= Time.now
823
850
  else
824
851
  false
@@ -6,6 +6,9 @@ module Miasma
6
6
  # AWS Orchestration API
7
7
  class Aws < Orchestration
8
8
 
9
+ include Bogo::Logger::Helpers
10
+ logger_name("aws.orchestration")
11
+
9
12
  # Extended stack model to provide AWS specific stack options
10
13
  class Stack < Orchestration::Stack
11
14
  attribute :stack_policy_body, Hash, :coerce => lambda { |v| MultiJson.load(v).to_smash }
@@ -26,7 +29,7 @@ module Miasma
26
29
  "DELETE_IN_PROGRESS", "ROLLBACK_COMPLETE", "ROLLBACK_FAILED", "ROLLBACK_IN_PROGRESS",
27
30
  "UPDATE_COMPLETE", "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "UPDATE_IN_PROGRESS",
28
31
  "UPDATE_ROLLBACK_COMPLETE", "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS", "UPDATE_ROLLBACK_FAILED",
29
- "UPDATE_ROLLBACK_IN_PROGRESS",
32
+ "UPDATE_ROLLBACK_IN_PROGRESS", "REVIEW_IN_PROGRESS",
30
33
  ].map(&:freeze).freeze
31
34
 
32
35
  include Contrib::AwsApiCore::ApiCommon
@@ -59,10 +62,16 @@ module Miasma
59
62
  def load_stack_data(stack = nil)
60
63
  d_params = Smash.new("Action" => "DescribeStacks")
61
64
  l_params = Smash.new("Action" => "ListStacks")
62
- STACK_STATES.each_with_index do |state, idx|
63
- l_params["StackStatusFilter.member.#{idx + 1}"] = state.to_s.upcase
64
- end
65
+ # TODO: Disable state filtering so we get entire list of defined
66
+ # stacks. Allowing filtering would be ideal but need a generic
67
+ # way to pass it through. This current filter setup imposes
68
+ # list restrictions when new states are added that is less than
69
+ # ideal
70
+ # STACK_STATES.each_with_index do |state, idx|
71
+ # l_params["StackStatusFilter.member.#{idx + 1}"] = state.to_s.upcase
72
+ # end
65
73
  if stack
74
+ logger.debug("loading stack information for `#{stack.id}`")
66
75
  d_params["StackName"] = stack.id
67
76
  descriptions = all_result_pages(nil, :body,
68
77
  "DescribeStacksResponse", "DescribeStacksResult",
@@ -74,6 +83,7 @@ module Miasma
74
83
  )
75
84
  end
76
85
  else
86
+ logger.debug("loading stack listing information")
77
87
  lists = all_result_pages(nil, :body,
78
88
  "ListStacksResponse", "ListStacksResult",
79
89
  "StackSummaries", "member") do |options|
@@ -140,6 +150,8 @@ module Miasma
140
150
  :stack_policy_url => stk["StackPolicyURL"],
141
151
  ),
142
152
  ).valid_state
153
+ logger.debug("loaded stack information `#{new_stack.inspect}`")
154
+ new_stack
143
155
  end
144
156
  end
145
157
 
@@ -148,6 +160,7 @@ module Miasma
148
160
  # @param stack [Models::Orchestration::Stack]
149
161
  # @return [Models::Orchestration::Stack]
150
162
  def stack_save(stack)
163
+ logger.debug("saving stack information `#{stack.inspect}`")
151
164
  params = common_stack_params(stack)
152
165
  if stack.custom[:stack_policy_body]
153
166
  params["StackPolicyBody"] = MultiJson.dump(stack.custom[:stack_policy_body])
@@ -193,8 +206,16 @@ module Miasma
193
206
  # @todo Needs to include the rolearn and resourcetypes
194
207
  # at some point but more thought on how to integrate
195
208
  def stack_plan(stack)
209
+ logger.debug("generating plan for stack `#{stack.id}`")
196
210
  params = common_stack_params(stack)
197
211
  plan_name = changeset_name(stack)
212
+ if stack.persisted? && stack.state != :unknown
213
+ logger.debug("plan will update stack")
214
+ changeset_type = "UPDATE"
215
+ else
216
+ logger.debug("plan will create stack")
217
+ changeset_type = "CREATE"
218
+ end
198
219
  result = request(
199
220
  :path => "/",
200
221
  :method => :post,
@@ -202,7 +223,7 @@ module Miasma
202
223
  "Action" => "CreateChangeSet",
203
224
  "ChangeSetName" => plan_name,
204
225
  "StackName" => stack.name,
205
- "ChangeSetType" => stack.persisted? ? "UPDATE" : "CREATE",
226
+ "ChangeSetType" => changeset_type,
206
227
  )),
207
228
  )
208
229
  stack.reload
@@ -229,6 +250,7 @@ module Miasma
229
250
  plan.name = changeset_name(stack)
230
251
  end
231
252
  end
253
+ logger.debug("loading plan `#{plan.name}` for stack `#{stack.id}`")
232
254
  result = nil
233
255
  Bogo::Retry.build(:linear, max_attempts: 10, wait_interval: 5, ui: Bogo::Ui.new) do
234
256
  begin
@@ -244,16 +266,19 @@ module Miasma
244
266
  rescue Error::ApiError::RequestError => e
245
267
  # Plan does not exist
246
268
  if e.response.code == 404
269
+ logger.warn("plan `#{plan.name}` does not exist for stack `#{stack.id}`")
247
270
  return nil
248
271
  end
249
272
  # Stack does not exist
250
273
  if e.response.code == 400 && e.message.include?("ValidationError: Stack")
274
+ logger.warn("stack `#{stack.id}` does not exist")
251
275
  return nil
252
276
  end
253
277
  raise
254
278
  end
255
279
  status = result.get(:body, "DescribeChangeSetResponse", "DescribeChangeSetResult", "ExecutionStatus")
256
280
  if status != "AVAILABLE"
281
+ logger.debug("plan `#{plan.name}` is not available (status: `#{status}`)")
257
282
  raise "Plan execution is not yet available"
258
283
  end
259
284
  end.run!
@@ -326,10 +351,12 @@ module Miasma
326
351
  stack.id = plan.custom[:stack_id]
327
352
  stack.valid_state
328
353
  end
354
+ logger.debug("plan `#{plan.name}` loaded for stack `#{stack.id}` - `#{plan.inspect}`")
329
355
  stack.plan = plan.valid_state
330
356
  end
331
357
 
332
358
  def stack_plan_template(plan, state)
359
+ logger.debug("loading template for plan `#{plan.name}`")
333
360
  result = request(
334
361
  :path => "/",
335
362
  :method => :post,
@@ -347,6 +374,7 @@ module Miasma
347
374
  # @param stack [Models::Orchestration::Stack]
348
375
  # @return [Models::Orchestration::Stack]
349
376
  def stack_plan_destroy(stack)
377
+ logger.debug("deleting plan `#{stack.plan.id}` for stack `#{stack.id}`")
350
378
  request(
351
379
  :path => "/",
352
380
  :method => :post,
@@ -365,6 +393,7 @@ module Miasma
365
393
  # @param stack [Model::Orchestration::Stack]
366
394
  # @return [Model::Orchestration::Stack]
367
395
  def stack_plan_execute(stack)
396
+ logger.debug("applying plan `#{stack.plan.id}` to stack `#{stack.id}`")
368
397
  request(
369
398
  :path => "/",
370
399
  :method => :post,
@@ -382,6 +411,7 @@ module Miasma
382
411
  # @param plan [Model::Orchestration::Stack::Plan]
383
412
  # @return [Model::Orchestration::Stack::Plan]
384
413
  def stack_plan_reload(plan)
414
+ logger.debug("reloading plan `#{plan.id}`")
385
415
  if plan.stack.plan == plan
386
416
  stack_plan_load(plan.stack)
387
417
  else
@@ -398,6 +428,7 @@ module Miasma
398
428
  # @param stack [Models::Orchestration::Stack]
399
429
  # @return [Array<Models::Orchestration::Stack::Plan>]
400
430
  def stack_plan_all(stack)
431
+ logger.debug("loading all plans for stack `#{stack.id}`")
401
432
  all_result_pages(nil, :body,
402
433
  "ListChangeSetsResponse", "ListChangeSetsResult",
403
434
  "Summaries", "member") do |options|
@@ -437,6 +468,7 @@ module Miasma
437
468
  # @param stack [Models::Orchestration::Stack]
438
469
  # @return [Models::Orchestration::Stack]
439
470
  def stack_reload(stack)
471
+ logger.debug("reloading stack `#{stack.id}`")
440
472
  if stack.persisted?
441
473
  ustack = Stack.new(self)
442
474
  ustack.id = stack.id
@@ -458,6 +490,7 @@ module Miasma
458
490
  # @return [TrueClass, FalseClass]
459
491
  def stack_destroy(stack)
460
492
  if stack.persisted?
493
+ logger.debug("deleting stack `#{stack.id}`")
461
494
  request(
462
495
  :method => :post,
463
496
  :path => "/",
@@ -468,6 +501,7 @@ module Miasma
468
501
  )
469
502
  true
470
503
  else
504
+ logger.debug("stack not persisted. delete is no-op `#{stack.name}`")
471
505
  false
472
506
  end
473
507
  end
@@ -478,6 +512,7 @@ module Miasma
478
512
  # @return [Smash] stack template
479
513
  def stack_template_load(stack)
480
514
  if stack.persisted?
515
+ logger.debug("loading template for stack `#{stack.id}`")
481
516
  result = request(
482
517
  :method => :post,
483
518
  :path => "/",
@@ -489,6 +524,7 @@ module Miasma
489
524
  template = result.get(:body, "GetTemplateResponse", "GetTemplateResult", "TemplateBody")
490
525
  template.nil? ? Smash.new : MultiJson.load(template)
491
526
  else
527
+ logger.debug("no template for non-persisted stack `#{stack.name}`")
492
528
  Smash.new
493
529
  end
494
530
  end
@@ -513,6 +549,7 @@ module Miasma
513
549
  )
514
550
  nil
515
551
  rescue Error::ApiError::RequestError => e
552
+ logger.error("template validate error - #{e.response.body}")
516
553
  MultiXml.parse(e.response.body.to_s).to_smash.get(
517
554
  "ErrorResponse", "Error", "Message"
518
555
  )
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.description = "Smoggy AWS API"
11
11
  s.license = "Apache 2.0"
12
12
  s.require_path = "lib"
13
- s.add_runtime_dependency "miasma", ">= 0.3.3", "< 0.5"
13
+ s.add_runtime_dependency "miasma", ">= 0.3.5", "< 0.5"
14
14
  s.add_development_dependency "rake", "~> 10"
15
15
  s.add_development_dependency "pry"
16
16
  s.add_development_dependency "vcr"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miasma-aws
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.22
4
+ version: 0.3.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Roberts
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-22 00:00:00.000000000 Z
11
+ date: 2018-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: miasma
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.3.3
19
+ version: 0.3.5
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '0.5'
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 0.3.3
29
+ version: 0.3.5
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '0.5'