duostack 0.2.1 → 0.3.0

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.
Files changed (2) hide show
  1. data/bin/duostack +122 -4
  2. metadata +5 -5
data/bin/duostack CHANGED
@@ -28,7 +28,7 @@ $client = File.basename(__FILE__)
28
28
  module Duostack
29
29
  class Client
30
30
 
31
- VERSION = '0.2.1'
31
+ VERSION = '0.3.0'
32
32
  DEPENDENCIES_LAST_MODIFIED = 1298683372
33
33
  USER_AGENT = "duostack-#{VERSION}"
34
34
 
@@ -49,7 +49,8 @@ module Duostack
49
49
  :user => [ # commands requiring credentials (first-time setup)
50
50
  'create',
51
51
  'list',
52
- 'sync'
52
+ 'sync',
53
+ 'billing_reset'
53
54
  ],
54
55
  :app => [ # commands requiring an app to be specified (either by git inference or flag)
55
56
  'logs',
@@ -61,7 +62,8 @@ module Duostack
61
62
  'config',
62
63
  'env',
63
64
  'access',
64
- 'domains'
65
+ 'domains',
66
+ 'instances'
65
67
  ],
66
68
  :compound => [ # mult-part commands that expect subsequent arguments, must validate extra args on their own
67
69
  'help',
@@ -70,7 +72,8 @@ module Duostack
70
72
  'config',
71
73
  'env',
72
74
  'access',
73
- 'domains'
75
+ 'domains',
76
+ 'instances'
74
77
  ]
75
78
  }
76
79
 
@@ -419,6 +422,9 @@ module Duostack
419
422
 
420
423
  def api_get(endpoint, params=nil, timeout=20)
421
424
 
425
+ # store previous request
426
+ @previous_request = [endpoint, params, timeout]
427
+
422
428
  url = "#{api_host}/api/#{endpoint}?#{@credentials}"
423
429
 
424
430
  url += "&app_name=#{@app_name}" if @app_name
@@ -427,6 +433,23 @@ module Duostack
427
433
  curl_get(url, timeout)
428
434
  end
429
435
 
436
+ # just retries last api_get, optionally passing additional params
437
+ def api_retry(params=nil)
438
+ exit false if @previous_request.empty?
439
+
440
+ # add in additional params
441
+ if params
442
+ if @previous_request[1]
443
+ @previous_request[1] = "#{@previous_request[1]}&#{params}"
444
+ else
445
+ @previous_request[1] = params
446
+ end
447
+ end
448
+
449
+ # retry
450
+ api_get(*@previous_request)
451
+ end
452
+
430
453
  def curl_get(url, timeout=nil)
431
454
  command = "curl -s -A '#{USER_AGENT}' -w '\n%{http_code}'" # use w flag to append http status code, set user-agent header
432
455
  command += " --cacert #{ca_cert_location}" if ca_cert_location # use our own certificate if present
@@ -448,6 +471,11 @@ module Duostack
448
471
  exit_with result
449
472
  end
450
473
 
474
+ if status == 402
475
+ print result # prints error message and prompt
476
+ return verify_account # handles input and retrying
477
+ end
478
+
451
479
  case (status / 100) # just get the class of status, e.g. any 4xx code will become 4
452
480
  when 2 # success, return result sans status code
453
481
  return result
@@ -458,6 +486,15 @@ module Duostack
458
486
  end
459
487
  end
460
488
 
489
+ def verify_account
490
+ response = $stdin.gets.chomp.downcase
491
+
492
+ # unless response is yes or blank (default yes), exit
493
+ exit unless response == 'yes'
494
+
495
+ api_retry("billing_confirmed=1")
496
+ end
497
+
461
498
  def sentencize(array, conjunction='or')
462
499
  # http://stackoverflow.com/questions/2038787/join-array-contents-into-an-english-list
463
500
  case array.length
@@ -504,6 +541,11 @@ module Duostack
504
541
  # empty method, just makes sure credentials are set
505
542
  end
506
543
 
544
+ # internal method for testing, just resets the billing confirmation prompt
545
+ def billing_reset
546
+ puts api_get('test_reset_billing_verification')
547
+ end
548
+
507
549
  def list
508
550
  puts api_get('list_apps')
509
551
  end
@@ -654,6 +696,56 @@ module Duostack
654
696
  })
655
697
  end
656
698
 
699
+ def instances
700
+
701
+ arg = @args.shift || 'show' # show is the default
702
+
703
+ # instance only takes one arg so any remaning ones are invalid
704
+ unless @args.empty?
705
+ exit_with("unrecognized argument: '#{@args.first}', run '#{@client} help #{@command}' for usage")
706
+ end
707
+
708
+ action = if arg == 'show'
709
+ :show
710
+ else
711
+ case arg[0..0]
712
+ when '+' then :add
713
+ when '-' then :remove
714
+ else :set
715
+ end
716
+ end
717
+
718
+ # process numerical argument unless listing
719
+ if action != :show
720
+ # drop the plus/minus sign to get qty (if add/remove)
721
+ qty = if action == :set
722
+ arg
723
+ else
724
+ arg[1..-1]
725
+ end
726
+ end
727
+
728
+ # ensure qty is a plain integer at this point
729
+ begin
730
+ qty = Integer(qty)
731
+ rescue ArgumentError # this is what Integer() throws if its arg isn't convertible to an int
732
+ exit_with "'#{@command}' requires a numerical argument, try '#{@command} [+/-]<quantity>'"
733
+ end
734
+
735
+
736
+ # finally, process action
737
+ case action
738
+ when :show
739
+ puts api_get("count_instances")
740
+ when :add
741
+ puts api_get("set_instances", "qty=#{qty}&type=inc")
742
+ when :remove
743
+ puts api_get("set_instances", "qty=#{qty}&type=dec")
744
+ when :set
745
+ puts api_get("set_instances", "qty=#{qty}")
746
+ end
747
+ end
748
+
657
749
 
658
750
  module Help
659
751
 
@@ -705,6 +797,7 @@ module Duostack
705
797
  env [<operation>] Manage environment variables
706
798
  access [<operation>] Manage app collaborator access
707
799
  domains [<operation>] Manage custom domains
800
+ instances [<operation>] Manage app instance count
708
801
 
709
802
  App Commands - Ruby:
710
803
  console Connect to IRB/Rails console
@@ -926,6 +1019,31 @@ module Duostack
926
1019
  EOF
927
1020
  end
928
1021
 
1022
+ def instances
1023
+ <<-EOF
1024
+
1025
+ Usage:
1026
+ #{$client} instances shows current instance count
1027
+ #{$client} instances <qty> sets instance count to <qty>
1028
+ #{$client} instances +<qty> increments instance count by <qty>
1029
+ #{$client} instances -<qty> decrements instance count by <qty>
1030
+
1031
+ Examples:
1032
+ #{$client} instances shows current instance count
1033
+ #{$client} instances 5 sets instance count to 5
1034
+ #{$client} instances +2 increments instance count by 2
1035
+ #{$client} instances -2 decrements instance count by 2
1036
+
1037
+ Adjusts instance count, either setting absolutely, or incrementing/decrementing
1038
+ by a given quantity.
1039
+
1040
+ Any increment, decrement, or set command that would result in an invalid
1041
+ instance count will be rejected with an error message. Instance counts must be
1042
+ greater than 0 and not greater than 15.
1043
+
1044
+ EOF
1045
+ end
1046
+
929
1047
  def console
930
1048
  <<-EOF
931
1049
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duostack
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 1
10
- version: 0.2.1
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Todd Eichel
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-28 00:00:00 -05:00
18
+ date: 2011-03-03 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies: []
21
21