smartdc 1.3.0 → 2.0.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 (120) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -19
  3. data/.travis.yml +1 -1
  4. data/Gemfile +5 -11
  5. data/README.md +25 -40
  6. data/Rakefile +5 -5
  7. data/bin/sdc +4 -380
  8. data/config.ru +2 -0
  9. data/lib/smartdc.rb +23 -15
  10. data/lib/smartdc/api/analytics.rb +19 -36
  11. data/lib/smartdc/api/analytics/heatmap.rb +6 -15
  12. data/lib/smartdc/api/datacenters.rb +7 -16
  13. data/lib/smartdc/api/images.rb +11 -0
  14. data/lib/smartdc/api/keys.rb +13 -23
  15. data/lib/smartdc/api/machines.rb +26 -60
  16. data/lib/smartdc/api/machines/metadata.rb +15 -0
  17. data/lib/smartdc/api/machines/snapshots.rb +23 -0
  18. data/lib/smartdc/api/machines/tags.rb +19 -0
  19. data/lib/smartdc/api/packages.rb +7 -17
  20. data/lib/smartdc/auth.rb +39 -5
  21. data/lib/smartdc/cli.rb +65 -0
  22. data/lib/smartdc/cli/analytic.rb +52 -0
  23. data/lib/smartdc/cli/datacenter.rb +15 -0
  24. data/lib/smartdc/cli/image.rb +19 -0
  25. data/lib/smartdc/cli/key.rb +26 -0
  26. data/lib/smartdc/cli/machine.rb +79 -0
  27. data/lib/smartdc/cli/machine/metadata.rb +30 -0
  28. data/lib/smartdc/cli/machine/snapshot.rb +38 -0
  29. data/lib/smartdc/cli/machine/tag.rb +33 -0
  30. data/lib/smartdc/cli/package.rb +17 -0
  31. data/lib/smartdc/cli_configure.rb +81 -0
  32. data/lib/smartdc/cli_helper.rb +111 -0
  33. data/lib/smartdc/client.rb +33 -28
  34. data/lib/smartdc/configure.rb +30 -0
  35. data/lib/smartdc/default.rb +35 -0
  36. data/lib/smartdc/version.rb +1 -1
  37. data/smartdc.gemspec +20 -16
  38. data/spec/cassettes/analytics/create.yml +64 -0
  39. data/spec/cassettes/analytics/describe.yml +123 -0
  40. data/spec/cassettes/analytics/destroy.yml +56 -0
  41. data/spec/cassettes/analytics/index.yml +62 -0
  42. data/spec/cassettes/analytics/show.yml +62 -0
  43. data/spec/cassettes/analytics/value.yml +62 -0
  44. data/spec/cassettes/datacenters/index.yml +62 -0
  45. data/spec/cassettes/datacenters/show.yml +64 -0
  46. data/spec/cassettes/images/index.yml +519 -0
  47. data/spec/cassettes/images/show.yml +63 -0
  48. data/spec/cassettes/keys/create.yml +65 -0
  49. data/spec/cassettes/keys/destroy.yml +56 -0
  50. data/spec/cassettes/keys/index.yml +63 -0
  51. data/spec/cassettes/keys/show.yml +63 -0
  52. data/spec/cassettes/machines/create.yml +65 -0
  53. data/spec/cassettes/machines/destroy.yml +56 -0
  54. data/spec/cassettes/machines/index.yml +67 -0
  55. data/spec/cassettes/machines/metadata/destroy.yml +56 -0
  56. data/spec/cassettes/machines/metadata/index.yml +62 -0
  57. data/spec/cassettes/machines/metadata/update.yml +64 -0
  58. data/spec/cassettes/machines/reboot.yml +58 -0
  59. data/spec/cassettes/machines/show.yml +63 -0
  60. data/spec/cassettes/machines/snapshots/create.yml +62 -0
  61. data/spec/cassettes/machines/snapshots/destroy.yml +56 -0
  62. data/spec/cassettes/machines/snapshots/index.yml +62 -0
  63. data/spec/cassettes/machines/snapshots/show.yml +62 -0
  64. data/spec/cassettes/machines/snapshots/start.yml +58 -0
  65. data/spec/cassettes/machines/start.yml +58 -0
  66. data/spec/cassettes/machines/stop.yml +58 -0
  67. data/spec/cassettes/machines/tags/create.yml +64 -0
  68. data/spec/cassettes/machines/tags/destroy.yml +56 -0
  69. data/spec/cassettes/machines/tags/index.yml +62 -0
  70. data/spec/cassettes/machines/tags/show.yml +62 -0
  71. data/spec/cassettes/packages/index.yml +123 -0
  72. data/spec/cassettes/packages/show.yml +63 -0
  73. data/spec/fixtures/config/sdccfg +4 -0
  74. data/spec/fixtures/ssh/id_rsa +27 -0
  75. data/spec/fixtures/ssh/id_rsa.pub +1 -0
  76. data/spec/smartdc/api/analytics_spec.rb +47 -0
  77. data/spec/smartdc/api/datacenters_spec.rb +19 -0
  78. data/spec/smartdc/api/images_spec.rb +19 -0
  79. data/spec/smartdc/api/keys_spec.rb +34 -0
  80. data/spec/smartdc/api/machines/metadata_spec.rb +27 -0
  81. data/spec/smartdc/api/machines/snapshots_spec.rb +38 -0
  82. data/spec/smartdc/api/machines/tags_spec.rb +33 -0
  83. data/spec/smartdc/api/machines_spec.rb +59 -0
  84. data/spec/smartdc/api/packages_spec.rb +19 -0
  85. data/spec/smartdc/auth_spec.rb +25 -0
  86. data/spec/smartdc/cli_configure_spec.rb +32 -0
  87. data/spec/smartdc/client_spec.rb +11 -0
  88. data/spec/smartdc_spec.rb +44 -0
  89. data/spec/spec_helper.rb +25 -8
  90. metadata +176 -83
  91. data/lib/cli_helper.rb +0 -126
  92. data/lib/configure.rb +0 -125
  93. data/lib/smartdc/api/datasets.rb +0 -20
  94. data/lib/smartdc/api/machine/metadata.rb +0 -24
  95. data/lib/smartdc/api/machine/snapshots.rb +0 -35
  96. data/lib/smartdc/api/machine/tags.rb +0 -29
  97. data/lib/smartdc/error.rb +0 -35
  98. data/lib/smartdc/request.rb +0 -83
  99. data/lib/smartdc/response.rb +0 -25
  100. data/lib/smartdc/response/raise_error.rb +0 -38
  101. data/spec/fixtures/analytics.json +0 -26
  102. data/spec/fixtures/datacenter.json +0 -4
  103. data/spec/fixtures/datacenters.json +0 -3
  104. data/spec/fixtures/datasets.json +0 -38
  105. data/spec/fixtures/keys.json +0 -14
  106. data/spec/fixtures/machines.json +0 -36
  107. data/spec/fixtures/packages.json +0 -18
  108. data/spec/fixtures/snapshots.json +0 -8
  109. data/spec/fixtures/tag.json +0 -3
  110. data/spec/unit/smartdc/api/analytics_spec.rb +0 -48
  111. data/spec/unit/smartdc/api/datacenters_spec.rb +0 -28
  112. data/spec/unit/smartdc/api/datasets_spec.rb +0 -28
  113. data/spec/unit/smartdc/api/keys_spec.rb +0 -48
  114. data/spec/unit/smartdc/api/machine/metadata_spec.rb +0 -38
  115. data/spec/unit/smartdc/api/machine/snapshots_spec.rb +0 -48
  116. data/spec/unit/smartdc/api/machine/tags_spec.rb +0 -48
  117. data/spec/unit/smartdc/api/machines_spec.rb +0 -48
  118. data/spec/unit/smartdc/api/packages_spec.rb +0 -28
  119. data/spec/unit/smartdc/client_spec.rb +0 -40
  120. data/spec/unit/smartdc_spec.rb +0 -9
@@ -0,0 +1,65 @@
1
+ require 'thor'
2
+ require 'cassette-rack/response/raise_error'
3
+ require 'smartdc/cli_helper'
4
+ require 'smartdc/cli_configure'
5
+ require 'smartdc/cli/datacenter'
6
+ require 'smartdc/cli/image'
7
+ require 'smartdc/cli/package'
8
+ require 'smartdc/cli/key'
9
+ require 'smartdc/cli/machine'
10
+ require 'smartdc/cli/analytic'
11
+
12
+ module Smartdc
13
+ module Cli
14
+ class Main < Thor
15
+ namespace 'sdc'
16
+ class_option :raw, type: :boolean, aliases: '-r', desc: 'Response body of raw.'
17
+
18
+ map '-v' => :version
19
+ desc 'version', 'Prints current version.'
20
+ def version
21
+ puts "sdc #{Smartdc::VERSION}"
22
+ end
23
+
24
+ desc 'init', 'Sets up configuration for use with this CLI.'
25
+ def init
26
+ clicfg = Smartdc::CliConfigure.new
27
+ clicfg.init
28
+ Smartdc::Cli.setup
29
+ Smartdc.keys
30
+ puts 'Successful configuration.'
31
+ rescue
32
+ puts 'Failed Configuration.'
33
+ end
34
+
35
+ cmd = ' [COMMAND]'
36
+ register(Smartdc::Cli::Datacenter, 'datacenter', 'datacenter' + cmd, 'Smart datacenters')
37
+ register(Smartdc::Cli::Image, 'image', 'image' + cmd, 'Machine images')
38
+ register(Smartdc::Cli::Package, 'package', 'package' + cmd, 'Machine resources')
39
+ register(Smartdc::Cli::Key, 'key', 'key' + cmd, 'SSH key')
40
+ register(Smartdc::Cli::Machine, 'machine', 'machine' + cmd, 'Virtual machine')
41
+ register(Smartdc::Cli::Analytic, 'analytic', 'analytic' + cmd, 'DTrace analytics')
42
+ end
43
+
44
+ class << self
45
+ def setup
46
+ clicfg = Smartdc::CliConfigure.new
47
+ sdccfg = clicfg.read
48
+ Smartdc.configure do |config|
49
+ config.url = "https://#{sdccfg[:hostname]}" if sdccfg.key?(:hostname)
50
+ config.version = sdccfg[:version] if sdccfg.key?(:version)
51
+ config.username = sdccfg[:username] if sdccfg.key?(:username)
52
+ config.use_key = sdccfg[:use_key] if sdccfg.key?(:use_key)
53
+ config.rsa_path = sdccfg[:rsa_path] if sdccfg.key?(:rsa_path)
54
+ config.middleware = Faraday::RackBuilder.new do |builder|
55
+ builder.adapter Faraday.default_adapter
56
+ #builder.use CassetteRack::Response::RaiseError
57
+ #builder.response :logger
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ Smartdc::Cli.setup
@@ -0,0 +1,52 @@
1
+ module Smartdc::Cli
2
+ class Analytic < Thor
3
+ include Smartdc::CliHelper
4
+
5
+ desc 'desc', 'Retrieves the schema for instrumentations.'
6
+ method_option :all, type: :boolean, desc: 'All describe.'
7
+ method_option :output, type: :string, default: 'metrics', aliases: '-o',
8
+ desc: 'Only output the modules or fields or types or metrics or transformations.'
9
+ def desc
10
+ if options['raw']
11
+ puts Smartdc.describe_analytics.body
12
+ else
13
+ content = Smartdc.describe_analytics.content
14
+ describe('modules', content, options.merge(cols: %w[key label]))
15
+ describe('fields', content, options.merge(cols: %w[key label type]))
16
+ describe('types', content, options.merge(cols: %w[key name arity unit abbr base power]))
17
+ describe('metrics', content, options.merge(cols: :all, exclude: %i[fields]))
18
+ describe('transformations', content, options.merge(cols: %w[key label]))
19
+ end
20
+ end
21
+
22
+ desc 'list', 'Retrieves all currently created instrumentations.'
23
+ def list
24
+ output Smartdc.analytics, options.merge(table: :horizontal, include: %i[
25
+ id module stat decomposition
26
+ ])
27
+ end
28
+
29
+ desc 'show [ID]', 'Retrieves the configuration for an instrumentation.'
30
+ method_option :value, type: :boolean, aliases: '-v', desc: 'Analytic value.'
31
+ def show(id)
32
+ if options[:value]
33
+ output Smartdc.value_analytic(id), options.merge({table: :vertical})
34
+ else
35
+ output Smartdc.analytic(id), options.merge(table: :vertical, exclude: %i[uris])
36
+ end
37
+ end
38
+
39
+ desc 'add [NAME]', 'Creates an instrumentation.'
40
+ method_option :module, type: :string, aliases: '-m', desc: 'The Cloud analytics module'
41
+ method_option :stat, type: :string, aliases: '-s', desc: 'The Cloud analytics stat'
42
+ def add
43
+ body = {module: options[:module], stat: options[:stat]}
44
+ output Smartdc.create_analytic(body), options.merge(table: :vertical, exclude: %i[uris])
45
+ end
46
+
47
+ desc 'destroy [ID]', 'Destroys an instrumentation.'
48
+ def destroy(id)
49
+ output Smartdc.destroy_analytic(id), options.merge(message: "Analytic #{id} destroy.")
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,15 @@
1
+ module Smartdc::Cli
2
+ class Datacenter < Thor
3
+ include Smartdc::CliHelper
4
+
5
+ desc 'list', 'Provides a list of all datacenters this cloud is aware of.'
6
+ def list
7
+ output Smartdc.datacenters, options.merge(table: :vertical)
8
+ end
9
+
10
+ desc 'show [NAME]', 'Gets an individual datacenter by name.'
11
+ def show(name)
12
+ output Smartdc.datacenter(name)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ module Smartdc::Cli
2
+ class Image < Thor
3
+ include Smartdc::CliHelper
4
+
5
+ desc 'list', 'Provides a list of images available in this datacenter.'
6
+ def list
7
+ output Smartdc.images, options.merge(table: :horizontal, include: %i[
8
+ id name version type os
9
+ ])
10
+ end
11
+
12
+ desc 'show [ID]', 'Gets an individual image by id.'
13
+ def show(id)
14
+ output Smartdc.image(id), options.merge(table: :vertical, exclude: %i[
15
+ description files
16
+ ])
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ module Smartdc::Cli
2
+ class Key < Thor
3
+ include Smartdc::CliHelper
4
+
5
+ desc 'list', 'Lists all public keys we have on record for the specified account.'
6
+ def list
7
+ output Smartdc.keys, options.merge(table: :horizontal, exclude: %i[key])
8
+ end
9
+
10
+ desc 'show [NAME]', 'Retrieves the record for an individual key.'
11
+ def show(name)
12
+ output Smartdc.key(name), options.merge(only: :key)
13
+ end
14
+
15
+ desc 'add [NAME] [FILE]', 'Uploads a new OpenSSH key.'
16
+ def add(name, file)
17
+ body = { name: name, key: File.read(file) }
18
+ output Smartdc.create_key(body), options.merge(table: :vertical, exclude: %i[key])
19
+ end
20
+
21
+ desc 'destroy [NAME]', 'Deletes a single SSH key, by name or fingerprint.'
22
+ def destroy(name)
23
+ output Smartdc.destroy_key(name), options.merge(message: "Key #{name} destroy.")
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,79 @@
1
+ require 'smartdc/cli/machine/tag'
2
+ require 'smartdc/cli/machine/metadata'
3
+ require 'smartdc/cli/machine/snapshot'
4
+
5
+ module Smartdc::Cli
6
+ class Machine < Thor
7
+ include Smartdc::CliHelper
8
+
9
+ desc 'list', 'Lists all machines we have on record for your account.'
10
+ method_option :type, type: :string, aliases: '-t', desc: 'virtualmachine or smartmachine'
11
+ method_option :state, type: :string, aliases: '-s', desc: 'running or stopped'
12
+ def list
13
+ output Smartdc.machines(options), options.merge(table: :horizontal, include: %i[
14
+ id name state primaryIp memory disk dataset
15
+ ])
16
+ end
17
+
18
+ desc 'show [ID]', 'Gets the details for an individual machine.'
19
+ def show(id=nil)
20
+ output Smartdc.machine(use_machine(id)), options.merge(table: :vertical)
21
+ end
22
+
23
+ desc 'add [NAME]', 'Allows you to provision a machine.'
24
+ method_option :image, type: :string, aliases: '-i', desc: 'The image UUID'
25
+ method_option :package, type: :string, aliases: '-p', desc: 'Id of the package to use on provisioning'
26
+ def add(name)
27
+ body = {name: name}.merge(options)
28
+ output Smartdc.create_machine(body), options.merge({table: :vertical})
29
+ end
30
+
31
+ desc 'destroy [ID]', 'Allows you to completely destroy a machine.'
32
+ def destroy(id=nil)
33
+ id = use_machine(id)
34
+ output Smartdc.destroy_machine(id), options.merge(message: "Destroy [#{id}] of machine.")
35
+ end
36
+
37
+ desc 'stop [ID]', 'Allows you to shut down a machine.'
38
+ def stop(id=nil)
39
+ id = use_machine(id)
40
+ output Smartdc.stop_machine(id), options.merge(message: "Stop [#{id}] of machine.")
41
+ end
42
+
43
+ desc 'start [ID]', 'Allows you to boot up a machine.'
44
+ def start(id=nil)
45
+ id = use_machine(id)
46
+ output Smartdc.start_machine(id), options.merge(message: "Start [#{id}] of machine.")
47
+ end
48
+
49
+ desc 'reboot [ID]', 'Allows you to reboot a machine'
50
+ def reboot(id=nil)
51
+ id = use_machine(id)
52
+ output Smartdc.reboot_machine(id), options.merge(message: "Reboot [#{id}] of machine.")
53
+ end
54
+
55
+ desc 'resize [ID]', 'Resize a machine to a new package.'
56
+ method_option :package, type: :string, aliases: '-p', desc: 'A package id, as returned from ListPackages'
57
+ def resize(id=nil)
58
+ body = {package: options[:package]}
59
+ id = use_machine(id)
60
+ output Smartdc.resize_machine(id, body), options.merge(message: "Resize [#{id}] of machine.")
61
+ end
62
+
63
+ desc 'use [ID]', 'Sets use machine.'
64
+ def use(id=nil)
65
+ clicfg = Smartdc::CliConfigure.new
66
+ sdccfg = clicfg.read
67
+ if id.nil?
68
+ puts "Use [#{sdccfg[:use_machine]}] of machine."
69
+ else
70
+ sdccfg[:use_machine] = id
71
+ clicfg.write(sdccfg)
72
+ end
73
+ end
74
+
75
+ register(Smartdc::Cli::MachineTag, 'tag', 'tag [COMMAND]', 'Machine tag')
76
+ register(Smartdc::Cli::MachineMetadata, 'meta', 'meta [COMMAND]', 'Machine metadata')
77
+ register(Smartdc::Cli::MachineSnapshot, 'snapshot', 'snapshot [COMMAND]', 'Machine snapshot')
78
+ end
79
+ end
@@ -0,0 +1,30 @@
1
+ module Smartdc::Cli
2
+ class MachineMetadata < Thor
3
+ include Smartdc::CliHelper
4
+
5
+ namespace 'machine meta'
6
+ class_option :id, type: :string, aliases: '-m', desc: 'Machine id'
7
+
8
+ desc 'list', 'Returns the complete set of metadata associated with this machine.'
9
+ def list
10
+ id = use_machine(options['id'])
11
+ output Smartdc.machine_metadata(id), options.merge(table: :vertical, exclude: %i[
12
+ root_authorized_keys
13
+ ])
14
+ end
15
+
16
+ desc 'update [KEY] [VALUE]', 'Allows you to update the metadata for a given machine.'
17
+ def update(key, value)
18
+ id = use_machine(options['id'])
19
+ output Smartdc.update_machine_metadata(id, {key => value}), options.merge(table: :vertical, exclude: %i[
20
+ root_authorized_keys
21
+ ])
22
+ end
23
+
24
+ desc 'destroy [KEY]', 'Deletes a single metadata key from this machine.'
25
+ def destroy(key)
26
+ id = use_machine(options['id'])
27
+ output Smartdc.destroy_machine_metadata(id, key), options.merge(message: "Destroy [#{key}] of machine metadata.")
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,38 @@
1
+ module Smartdc::Cli
2
+ class MachineSnapshot < Thor
3
+ include Smartdc::CliHelper
4
+
5
+ namespace 'machine snapshot'
6
+ class_option :id, type: :string, aliases: '-m', desc: 'Machine id'
7
+
8
+ desc 'list', 'Lists all snapshots taken for a given machine. '
9
+ def list
10
+ id = use_machine(options['id'])
11
+ output Smartdc.machine_snapshots(id), options.merge(table: :horizontal)
12
+ end
13
+
14
+ desc 'show [NAME]', 'Gets the state of the named snapshot.'
15
+ def show(name)
16
+ id = use_machine(options['id'])
17
+ output Smartdc.machine_snapshot(id, name), options.merge(table: :vertical)
18
+ end
19
+
20
+ desc 'add [NAME]', 'Allows you to take a snapshot of a machine.'
21
+ def add(name)
22
+ id = use_machine(options['id'])
23
+ output Smartdc.create_machine_snapshot(id, {name: name}), options.merge(table: :vertical)
24
+ end
25
+
26
+ desc 'destroy [NAME]', 'Deletes the specified snapshot of a machine.'
27
+ def destroy(name)
28
+ id = use_machine(options['id'])
29
+ output Smartdc.destroy_machine_snapshot(id, name), options.merge(message: "Destroy [#{name}] of machine snapshot.")
30
+ end
31
+
32
+ desc 'start [NAME]', 'Starts a stopped machine from the referenced snapshot.'
33
+ def start(name)
34
+ id = use_machine(options['id'])
35
+ output Smartdc.start_machine_snapshot(id, name), options.merge(message: "Start [#{name}] of machine snapshot.")
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,33 @@
1
+ module Smartdc::Cli
2
+ class MachineTag < Thor
3
+ include Smartdc::CliHelper
4
+
5
+ namespace 'machine tag'
6
+ class_option :id, type: :string, aliases: '-m', desc: 'Machine id'
7
+
8
+ desc 'list', 'Returns the complete set of tags associated with this machine.'
9
+ def list
10
+ id = use_machine(options['id'])
11
+ output Smartdc.machine_tags(id), options.merge(table: :vertical)
12
+ end
13
+
14
+ desc 'show [KEY]', 'Returns the value for a single tag on this machine.'
15
+ def show(key)
16
+ id = use_machine(options['id'])
17
+ response = Smartdc.machine_tag(id, key)
18
+ output response, options.merge(message: response.content)
19
+ end
20
+
21
+ desc 'add [KEY] [VALUE]', 'Allows you to add additional tags, other than those set at provisioning time.'
22
+ def add(key, value)
23
+ id = use_machine(options['id'])
24
+ output Smartdc.create_machine_tag(id, {key => value}), options.merge(table: :vertical)
25
+ end
26
+
27
+ desc 'destroy [KEY]', 'Deletes a single tag from this machine.'
28
+ def destroy(key)
29
+ id = use_machine(options['id'])
30
+ output Smartdc.destroy_machine_tag(id, key), options.merge(message: "Destroy [#{key}] of machine tag.")
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ module Smartdc::Cli
2
+ class Package < Thor
3
+ include Smartdc::CliHelper
4
+
5
+ desc 'list', 'Provides a list of packages available in this datacenter.'
6
+ def list
7
+ output Smartdc.packages, options.merge(table: :horizontal, include: %i[
8
+ id name version memory disk vcpus group
9
+ ])
10
+ end
11
+
12
+ desc 'show [NAME]', 'Gets a package by name or id.'
13
+ def show(name)
14
+ output Smartdc.package(name), options.merge(table: :vertical)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,81 @@
1
+ module Smartdc
2
+ class CliConfigure
3
+ attr_reader :path
4
+
5
+ def initialize(path=nil)
6
+ if path
7
+ @path =path
8
+ else
9
+ [Smartdc.root, ENV['HOME']].each do |path|
10
+ @path = File.join(path, '.sdccfg')
11
+ break if File.exist?(@path)
12
+ end
13
+ end
14
+ end
15
+
16
+ def read
17
+ begin
18
+ options = {}
19
+ File.open(path, 'r') do |file|
20
+ file.each do |row|
21
+ row.chomp!
22
+ cols = row.split(/\s+=\s+/)
23
+ options[cols[0].to_sym] = cols[1]
24
+ end
25
+ end
26
+ options
27
+ rescue
28
+ {}
29
+ end
30
+ end
31
+
32
+ def write(options)
33
+ File.open(path, 'w') do |file|
34
+ options.each do |key, value|
35
+ file.puts "#{key} = #{value}"
36
+ end
37
+ end
38
+ options
39
+ end
40
+
41
+ def init
42
+ output = <<__EOS__
43
+ .
44
+ |
45
+ .-. .--. .-.| .-.
46
+ : + : `--.( | (
47
+ `-' `--' `-'`- `-'
48
+ Smart Data Center Command Line Interface
49
+ https://apidocs.joyent.com/sdcapidoc/cloudapi/
50
+ __EOS__
51
+ puts output
52
+ puts
53
+
54
+ options = self.read
55
+ options = option(options, :Hostname, :hostname, 'api.example.com')
56
+ options = option(options, :Version, :version, '~7.0')
57
+ options = option(options, :Username, :username, ENV['USER'])
58
+ options = option(options, :Fingerprint, :use_key, 'none')
59
+
60
+ puts
61
+ puts "New settings!"
62
+ puts "Hostname: #{options[:hostname]}"
63
+ puts "Version: #{options[:version]}"
64
+ puts "Username: #{options[:username]}"
65
+ puts "Fingerprint: #{options[:use_key]}"
66
+ puts
67
+
68
+ self.write options
69
+ end
70
+
71
+ private
72
+ def option(options, name, key, value)
73
+ options[key] ||= value
74
+ print "#{name} (#{options[key]}): "
75
+ stdin = STDIN.gets.chomp.to_s
76
+ options[key] = stdin if !stdin.empty?
77
+ options
78
+ end
79
+ # end private
80
+ end
81
+ end