smartdc 1.3.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,126 +0,0 @@
1
- require 'thor'
2
- require 'thor/group'
3
- require 'terminal-table'
4
- require 'smartdc'
5
- require 'configure'
6
- include Configure
7
-
8
- def config(options={})
9
- cfg = Configure.read
10
-
11
- if !options.empty?
12
- options.each do |key, value|
13
- cfg[key.to_sym] = value
14
- end
15
- end
16
-
17
- cfg
18
- end
19
-
20
- def sdc(options)
21
- Smartdc.new(options)
22
- end
23
-
24
- def opt(argument, options={})
25
- opts = {}
26
- opts = opts.merge(options)
27
- opts['raw'] = true if argument.include?('--raw') or argument.include?('-r')
28
- opts['debug'] = true if argument.include?('--debug') or argument.include?('-d')
29
- opts
30
- end
31
-
32
- def output(response, options={})
33
- if options['raw']
34
- puts response.body
35
- else
36
- if response.status < 300
37
- if options[:table]
38
- case options[:table]
39
- when :h
40
- puts horizontal(response.content, options)
41
- when :v
42
- puts vertical(response.content, options)
43
- end
44
- else
45
- if options[:message]
46
- puts options[:message]
47
- else
48
- puts response.content[options[:only].to_s]
49
- end
50
- end
51
- else
52
- puts vertical(response.content)
53
- end
54
- end
55
- end
56
-
57
- def horizontal(content, options={})
58
- options[:include] ||= []
59
- options[:exclude] ||= []
60
- rows = []
61
- headings = nil
62
-
63
- content.each do |row|
64
- options[:exclude].each do |col|
65
- row.delete(col.to_s)
66
- end
67
-
68
- if !options[:include].empty?
69
- cols = {}
70
- options[:include].each do |col|
71
- cols[col.to_s] = row[col.to_s] if row.key?(col.to_s)
72
- end
73
- row = cols
74
- end
75
-
76
- rows << row.values
77
- headings = row.keys if headings.nil?
78
- end
79
-
80
- Terminal::Table.new :headings => headings, :rows => rows if !content.empty?
81
- end
82
-
83
- def vertical(content, options={})
84
- options[:exclude] ||= []
85
- options[:exclude].each do |col|
86
- content.delete(col.to_s)
87
- end
88
-
89
- rows = []
90
- content.to_a.each do |row|
91
- rows << row
92
- end
93
-
94
- Terminal::Table.new :headings => ['key','value'], :rows => rows if !content.empty?
95
- end
96
-
97
- def describe(name, content, options)
98
- if options['all'] or options['output'] == name
99
- options[:exclude] ||= []
100
- rows = []
101
-
102
- content[name].each do |row|
103
- cols = []
104
- if options[:cols] == :all
105
- options[:exclude].each do |col|
106
- row.delete(col.to_s)
107
- end
108
- cols = row.values
109
- else
110
- options[:cols].each do |col|
111
- if col == 'key'
112
- cols << row[0]
113
- else
114
- cols << row[1][col]
115
- end
116
- end
117
- end
118
- rows << cols
119
- end
120
-
121
- title = options['all'] ? name : nil
122
- headings = options[:cols] == :all ? content[name][0].keys : options[:cols]
123
- puts Terminal::Table.new :title => title, :headings => headings, :rows => rows
124
- puts if options['all']
125
- end
126
- end
@@ -1,125 +0,0 @@
1
- module Configure
2
- def self.read()
3
- begin
4
- config = {}
5
- File.open(path, 'r') do |file|
6
- file.each do |row|
7
- row.chomp!
8
- cols = row.split(/\s+=\s+/)
9
- config[cols[0].to_sym] = cols[1]
10
- end
11
- end
12
- rescue
13
- config = {}
14
- ensure
15
- return config
16
- end
17
- end
18
-
19
- def self.write(config)
20
- File.open(path, 'w') do |file|
21
- config.each do |key, value|
22
- file.puts "#{key} = #{value}"
23
- end
24
- end
25
- end
26
-
27
- def self.init
28
- config = self.read
29
-
30
- output = <<EOS
31
- .
32
- |
33
- .-. .--. .-.| .-.
34
- : + : `--.( | (
35
- `-' `--' `-'`- `-'
36
- Smart Data Center Command Line Interface
37
- http://apidocs.joyent.com/sdcapidoc/cloudapi/
38
-
39
- EOS
40
- puts output
41
-
42
- config[:hostname] ||= 'api.example.com'
43
- print "Hostname (#{config[:hostname]}): "
44
- stdin = STDIN.gets.chomp.to_s
45
- config[:hostname] = stdin if !stdin.empty?
46
-
47
- config[:username] ||= ENV['USER']
48
- print "Username (#{config[:username]}): "
49
- stdin = STDIN.gets.chomp.to_s
50
- config[:username] = stdin if !stdin.empty?
51
-
52
- config[:password] ||= ''
53
- print "Password: "
54
- stdin = STDIN.gets.chomp.to_s
55
- config[:password] = stdin if !stdin.empty?
56
-
57
- config[:version] ||= '~6.5 '
58
- print "Version (#{config[:version]}): "
59
- stdin = STDIN.gets.chomp.to_s
60
- config[:version] = stdin if !stdin.empty?
61
-
62
- puts
63
- puts "New settings:"
64
- puts "Hostname: #{config[:hostname]}"
65
- puts "Username: #{config[:username]}"
66
- puts "Password:"
67
- puts "Version: #{config[:version]}"
68
- puts
69
-
70
- self.write config
71
- end
72
-
73
- def self.key(keys)
74
- config = self.read
75
- use_key = 0
76
- rsa_path = nil
77
-
78
- puts "SSH Key Settings:"
79
- keys.each_with_index do |key, i|
80
- puts "#{i+1}) #{key['name']}"
81
- end
82
-
83
- if !keys.empty?
84
- puts "0) Add new key"
85
- print "Select SSH key: "
86
- stdin = STDIN.gets.chomp.to_s
87
- use_key = stdin.to_i if !stdin.empty?
88
- end
89
-
90
- if use_key > 0
91
- config[:use_key] = keys[use_key-1]['name']
92
- else
93
- config[:use_key] ||= 'id_rsa'
94
- print "Key name (#{config[:use_key]}): "
95
- stdin = STDIN.gets.chomp.to_s
96
- config[:use_key] = stdin if !stdin.empty?
97
-
98
- rsa_path = File.join(ENV["HOME"], '/.ssh/id_rsa.pub')
99
- print "Public key path (#{rsa_path}): "
100
- stdin = STDIN.gets.chomp.to_s
101
- rsa_path = stdin if !stdin.empty?
102
- end
103
-
104
- config[:rsa_path] ||= File.join(ENV["HOME"], '/.ssh/id_rsa')
105
- print "Private key path (#{config[:rsa_path]}): "
106
- stdin = STDIN.gets.chomp.to_s
107
- config[:rsa_path] = stdin if !stdin.empty?
108
- puts
109
-
110
- self.write config
111
- rsa_path
112
- end
113
-
114
- private
115
-
116
- def path
117
- config = '.sdccfg'
118
- file = File.join(File.dirname(__FILE__), '..', config)
119
- if File.exist?(file)
120
- file
121
- else
122
- File.join(ENV["HOME"], config)
123
- end
124
- end
125
- end
@@ -1,20 +0,0 @@
1
- module Smartdc
2
- module Api
3
- class Datasets
4
- attr_reader :request
5
-
6
- def initialize(options)
7
- @request = Smartdc::Request.new(options)
8
- end
9
-
10
- def read(id)
11
- raise ArgumentError unless id
12
- request.get('my/datasets/' + id.to_s)
13
- end
14
-
15
- def all(query={})
16
- request.get('my/datasets', query)
17
- end
18
- end
19
- end
20
- end
@@ -1,24 +0,0 @@
1
- module Smartdc::Api
2
- module Machine
3
- class Metadata
4
- attr_reader :request
5
-
6
- def initialize(id, options)
7
- @id = id
8
- @request = Smartdc::Request.new(options)
9
- end
10
-
11
- def create(raw={})
12
- request.post('my/machines/' + @id.to_s + '/metadata/', raw)
13
- end
14
-
15
- def read(query={})
16
- request.get('my/machines/' + @id.to_s + '/metadata', query)
17
- end
18
-
19
- def destroy(id=nil)
20
- request.del('my/machines/' + @id.to_s + '/metadata/' + id.to_s)
21
- end
22
- end
23
- end
24
- end
@@ -1,35 +0,0 @@
1
- module Smartdc::Api
2
- module Machine
3
- class Snapshots
4
- attr_reader :request
5
-
6
- def initialize(id, options)
7
- @id = id
8
- @request = Smartdc::Request.new(options)
9
- end
10
-
11
- def create(raw={})
12
- request.post('my/machines/' + @id.to_s + '/snapshots/', raw)
13
- end
14
-
15
- def read(id)
16
- raise ArgumentError unless id
17
- request.get('my/machines/' + @id.to_s + '/snapshots/' + id.to_s)
18
- end
19
-
20
- def all(query={})
21
- request.get('my/machines/' + @id.to_s + '/snapshots', query)
22
- end
23
-
24
- def destroy(id)
25
- raise ArgumentError unless id
26
- request.del('my/machines/' + @id.to_s + '/snapshots/' + id.to_s)
27
- end
28
-
29
- def start(id)
30
- raise ArgumentError unless id
31
- request.post('my/machines/' + @id.to_s + '/snapshots/' + id.to_s)
32
- end
33
- end
34
- end
35
- end
@@ -1,29 +0,0 @@
1
- module Smartdc::Api
2
- module Machine
3
- class Tags
4
- attr_reader :request
5
-
6
- def initialize(id, options)
7
- @id = id
8
- @request = Smartdc::Request.new(options)
9
- end
10
-
11
- def create(raw={})
12
- request.post('my/machines/' + @id.to_s + '/tags/', raw)
13
- end
14
-
15
- def read(id)
16
- raise ArgumentError unless id
17
- request.get('my/machines/' + @id.to_s + '/tags/' + id.to_s)
18
- end
19
-
20
- def all(query={})
21
- request.get('my/machines/' + @id.to_s + '/tags', query)
22
- end
23
-
24
- def destroy(id=nil)
25
- request.del('my/machines/' + @id.to_s + '/tags/' + id.to_s)
26
- end
27
- end
28
- end
29
- end
@@ -1,35 +0,0 @@
1
- module Smartdc
2
- class Error < StandardError
3
- attr_reader :response
4
-
5
- def initialize(response)
6
- @response = response
7
- begin
8
- body = JSON.parse(response[:body])
9
- if body['error_message']
10
- super(body['error_message'])
11
- else
12
- super(response[:body])
13
- end
14
- rescue
15
- super(response[:body])
16
- end
17
- end
18
-
19
- def response_status
20
- response[:status]
21
- end
22
- end
23
-
24
- class Error::BadRequest < Smartdc::Error; end
25
- class Error::Unauthorized < Smartdc::Error; end
26
- class Error::Forbidden < Smartdc::Error; end
27
- class Error::NotFound < Smartdc::Error; end
28
- class Error::MethodNotAllowed < Smartdc::Error; end
29
- class Error::NotAcceptable < Smartdc::Error; end
30
- class Error::Conflict < Smartdc::Error; end
31
- class Error::InternalServerError < Smartdc::Error; end
32
- class Error::NotImplemented < Smartdc::Error; end
33
- class Error::BadGateway < Smartdc::Error; end
34
- class Error::ServiceUnavailable < Smartdc::Error; end
35
- end
@@ -1,83 +0,0 @@
1
- require 'json'
2
- require 'faraday'
3
- require 'smartdc/auth'
4
- #require 'smartdc/response/raise_error'
5
-
6
- module Smartdc
7
- class Request
8
- def initialize(options)
9
- @options = options
10
- end
11
-
12
- def get(path, query={})
13
- request(:get, path, query, {})
14
- end
15
-
16
- def post(path, raw={})
17
- request(:post, path, {}, raw)
18
- end
19
-
20
- def put(path, raw={})
21
- request(:put, path, {}, raw)
22
- end
23
-
24
- def del(path, query={})
25
- request(:delete, path, query, {})
26
- end
27
-
28
- def request(method, path, query={}, raw={})
29
- path = path.gsub(/^my/, @options[:username])
30
- res = connection.send(method) do |req|
31
- case method
32
- when :get
33
- req.url path, query
34
- when :post, :put
35
- req.path = path
36
- req.body = raw.to_json unless raw.empty?
37
- when :delete
38
- req.url path
39
- end
40
-
41
- if @options[:debug]
42
- print 'Request: '
43
- puts "method: #{req.method.to_s}"
44
- puts "path: #{req.path}"
45
- puts "params: #{req.params}"
46
- puts "headers: #{req.headers}"
47
- puts "body: #{req.body}"
48
- end
49
- end
50
-
51
- if @options[:debug]
52
- print 'Response: '
53
- puts "status: #{res.status}"
54
- puts "headers: #{res.headers}"
55
- puts "body: #{res.body}"
56
- end
57
-
58
- Smartdc::Response.new(res)
59
- end
60
-
61
- private
62
-
63
- def connection
64
- options = {
65
- :url => 'https://' + @options[:hostname],
66
- :ssl => {:verify => false},
67
- :headers => {
68
- :date => Time.now.gmtime.to_s,
69
- 'content-type'=>'application/json',
70
- 'x-api-version' => @options[:version]
71
- }
72
- }
73
-
74
- options[:headers][:authorization] = Smartdc::Auth::sign(options, @options) if @options[:rsa_path] && !@options[:password]
75
-
76
- Faraday.new(options) do |builder|
77
- builder.request :basic_auth, @options[:username], @options[:password] if @options[:password]
78
- # builder.use Smartdc::Response::RaiseError
79
- builder.adapter Faraday.default_adapter
80
- end
81
- end
82
- end
83
- end