ncc-api 1.0.1 → 1.1.2

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
  SHA1:
3
- metadata.gz: d97a74f21100b3127d9f244f2e711012af1cd09e
4
- data.tar.gz: d28b36e3e1019d00ae17757c4d31e5603166f828
3
+ metadata.gz: a94804c0a647446cdfd140587f6337c806a4b133
4
+ data.tar.gz: 59c2c2f47c8bc855674828a4185302c7ae51c561
5
5
  SHA512:
6
- metadata.gz: 4c8cf9e2eab3579af7714f307acb7126e6eee4af93df90d8e329b31253d09885a89e10e59677ad996454c4c1f7cf83ae022d36a3f824a3ed25695aab8cd783b6
7
- data.tar.gz: 0791685953d5894dca54c5ddf9d0e3ef44cdb3b424e06a7c160d49dd258d9075aed11a0e68b18942627afe2d9a8cdf94fb2a5238019309614ced47184dd21013
6
+ metadata.gz: 11ed2a94d010101eaa53a465941414bde1c78a64a62c0cb84f8c3d567fb6ce12fad68e32b9da44a481517ee229b670b7f39ef57de2de0e1033e007e214262a01
7
+ data.tar.gz: 9ded9650c9df907a13241f196ff43e4963485f900249e034df2c745ff62d104c2555bc92b4de72ad31ba7b76565372a090b35149b572d1f209293cbfd7637829
@@ -79,7 +79,9 @@ class NCC::Connection::AWS < NCC::Connection
79
79
 
80
80
  def console_log(instance_id)
81
81
  begin
82
- @fog.get_console_output(instance_id).body
82
+ do_fog do |fog|
83
+ fog.get_console_output(instance_id).body
84
+ end
83
85
  rescue Fog::Compute::AWS::NotFound
84
86
  instance_not_found instance_id
85
87
  rescue Exception => e
@@ -89,10 +91,10 @@ class NCC::Connection::AWS < NCC::Connection
89
91
 
90
92
  def provider_request_of(instance)
91
93
  {
92
- :name => instance.name,
93
- :flavor_id => sizes(instance.size)['provider_id'],
94
- :image_id => images(instance.image)['provider_id'],
95
- :tags => { 'Name' => instance.name }
94
+ :name => instance.name,
95
+ :flavor_id => sizes(instance.size)['provider_id'],
96
+ :image_id => images(instance.image)['provider_id'],
97
+ :tags => { 'Name' => instance.name }
96
98
  }.merge(instance.extra provider)
97
99
  end
98
100
 
@@ -98,15 +98,13 @@ class NCC::Connection::OpenStack < NCC::Connection
98
98
  end
99
99
 
100
100
  def instance_ip_address(server)
101
- instance_network_names = ['instance_net', 'instnace_net']
102
- if !server.addresses.nil?
103
- instance_network_names.each do |network_name|
104
- if server.addresses.has_key? network_name
105
- return server.addresses[network_name].first['addr']
106
- end
107
- end
101
+ begin
102
+ server.private_ip_address.to_s
103
+ rescue StandardError => err
104
+ # Fog collapses badly when you just ask it for this
105
+ # field which isn't there (yet?)
106
+ nil
108
107
  end
109
- return nil
110
108
  end
111
109
 
112
110
  def instance_host(server)
@@ -114,7 +112,7 @@ class NCC::Connection::OpenStack < NCC::Connection
114
112
  end
115
113
 
116
114
  def console_log(instance_id)
117
- server = @fog.servers.get(instance_id)
115
+ server = do_fog { |fog| fog.servers.get(instance_id) }
118
116
  if server.nil?
119
117
  instance_not_found instance_id
120
118
  else
@@ -126,6 +124,31 @@ class NCC::Connection::OpenStack < NCC::Connection
126
124
  end
127
125
  end
128
126
 
127
+ def console(instance_id, console_type='novnc')
128
+ server = do_fog { |fog| fog.servers.get(instance_id) }
129
+ if server.nil?
130
+ instance_not_found instance_id
131
+ else
132
+ begin
133
+ response = do_fog { |fog| fog.get_vnc_console(server.id, console_type) }
134
+ body = response.body
135
+ rescue Exception => e
136
+ communication_error e.message
137
+ end
138
+
139
+ unless body.respond_to?(:[]) and
140
+ body['console'] and
141
+ body['console'].respond_to?(:[]) and
142
+ body['console']['url']
143
+ raise communication_error "Expected Fog::Compute::Openstack#get_vnc_console(#{instance_id.inspect}, " +
144
+ "#{console_type.inspect})# to return object with key 'console' => 'url'; " +
145
+ "instead got: #{body.inspect}"
146
+ end
147
+
148
+ body['console']
149
+ end
150
+ end
151
+
129
152
  def provider_request_of(instance)
130
153
  {
131
154
  :name => instance.name,
@@ -135,7 +158,7 @@ class NCC::Connection::OpenStack < NCC::Connection
135
158
  end
136
159
 
137
160
  def reboot(instance_id)
138
- server = @fog.servers.get(instance_id)
161
+ server = do_fog { |fog| fog.servers.get(instance_id) }
139
162
  if server.nil?
140
163
  instance_not_found instance_id
141
164
  else
@@ -15,6 +15,9 @@
15
15
  # limitations under the License.
16
16
  # */
17
17
 
18
+ # TODO:
19
+ # Align desired logger interface with Ruby Logger class standard
20
+
18
21
  require 'rubygems'
19
22
  require 'fog'
20
23
  require 'uuidtools'
@@ -44,11 +47,12 @@ class NCC::Connection
44
47
  @ncc = ncc
45
48
  @cache = { }
46
49
  @cfg = ncc.config
47
- @cfg_mtime = @cfg.mtime
50
+ @cfg_mtime = @cfg[:clouds][cloud].mtime
48
51
  @cloud = cloud
49
52
  @logger = opt[:logger] if opt.has_key? :logger
50
53
  @cache_timeout = opt[:cache_timeout] || 600
51
54
  @auth_retry_limit = opt[:auth_retry_limit] || 1
55
+ @create_timeout = opt[:create_timeout] || 160
52
56
  do_connect
53
57
  end
54
58
 
@@ -111,9 +115,13 @@ class NCC::Connection
111
115
  end
112
116
 
113
117
  def do_fog
114
- do_connect unless @fog
115
118
  remaining_tries = @auth_retry_limit
116
119
  begin
120
+ unless @fog
121
+ debug "do_fog: connecting because @fog is nil (@auth_retry_limit=#{@auth_retry_limit})"
122
+ do_connect
123
+ end
124
+ debug "do_fog: beginning fog operation"
117
125
  yield @fog
118
126
  rescue Excon::Errors::Unauthorized => err
119
127
  # might be an expired auth token, retry
@@ -132,6 +140,7 @@ class NCC::Connection
132
140
  rescue NCC::Error => err
133
141
  raise err
134
142
  rescue StandardError => err
143
+ debug "Unknown error [#{err.class}]: #{err.message} #{err.backtrace.join("\n ")}"
135
144
  @fog = nil
136
145
  raise NCC::Error::Cloud, "Error communicating with #{provider} " +
137
146
  "cloud #{@cloud} [#{err.class}]: #{err.message}"
@@ -312,7 +321,7 @@ class NCC::Connection
312
321
  do_fog { |fog| fog.send(enum).get(id) }
313
322
  end
314
323
  else
315
- do_fog { |fog| fog.send(enum) }
324
+ do_fog { |fog| fog.send(enum).map { |e| e } }
316
325
  end
317
326
  end
318
327
 
@@ -414,13 +423,13 @@ class NCC::Connection
414
423
  end
415
424
 
416
425
  def instance_ip_address(server)
417
- server.ip_address
426
+ server.ip_address.to_s
418
427
  end
419
428
 
420
429
  def instances(instance_id=nil)
421
430
  debug "instances(#{instance_id.inspect})"
422
431
  if instance_id.nil?
423
- do_fog { |fog| fog.servers }.map { |server| instance_for server }
432
+ do_fog { |fog| fog.servers.map { |server| instance_for server } }
424
433
  else
425
434
  server = do_fog { |fog| fog.servers.get instance_id }
426
435
  if server.nil?
@@ -466,8 +475,9 @@ class NCC::Connection
466
475
  'size' => i.size,
467
476
  'image' => i.image,
468
477
  'serial_number' => i.id,
478
+ 'uuid' => i.id,
469
479
  'roles' => i.role.sort.join(','),
470
- 'ip_address' => i.ip_address,
480
+ 'ipaddress' => i.ip_address,
471
481
  'host_fqdn' => host_fqdn(i.host),
472
482
  'environment_name' => i.environment
473
483
  }.merge(instance.extra 'inventory')
@@ -485,7 +495,9 @@ class NCC::Connection
485
495
  instance
486
496
  end
487
497
 
488
- def create_instance(instance_spec, wait_for_ip=60)
498
+ def create_instance(instance_spec, wait_for_ip=nil)
499
+ wait_for_ip ||= @create_timeout
500
+
489
501
  if ! instance_spec.kind_of? NCC::Instance
490
502
  instance_spec = NCC::Instance.new(@cfg, instance_spec)
491
503
  end
@@ -511,11 +523,13 @@ class NCC::Connection
511
523
  if wait_for_ip > 0 and instance_ip_address(server).nil?
512
524
  info "#{@cloud} waiting for ip on #{server.id}"
513
525
  this = self
514
- server.wait_for(wait_for_ip) { this.instance_ip_address(server) }
526
+ server.wait_for(wait_for_ip) { ready? and this.instance_ip_address(server) }
515
527
  end
516
528
  rescue StandardError => err
529
+ debug "Error [#{err.class}]: #{err.message} #{err.backtrace.join("\n ")}"
517
530
  inv_update = { 'fqdn' => fqdn, 'status' => 'decommissioned' }
518
531
  if ! server.nil? and server.id
532
+ inv_update['uuid'] = server.id
519
533
  inv_update['serial_number'] = server.id
520
534
  end
521
535
  @ncc.inventory.update('system', inv_update, fqdn)
@@ -578,6 +592,11 @@ class NCC::Connection
578
592
  "#{provider} does not support console logs"
579
593
  end
580
594
 
595
+ def console(instance_id)
596
+ raise NCC::Error::NotFound, "Cloud #{@cloud} provider " +
597
+ "#{provider} does not support interactive console"
598
+ end
599
+
581
600
  def reboot(instance_id)
582
601
  server = do_fog { |fog| fog.servers.get(instance_id) }
583
602
  if server.nil?
@@ -0,0 +1,3 @@
1
+ class NCC
2
+ VERSION = '1.1.2'
3
+ end
data/lib/ncc-api.rb CHANGED
@@ -29,7 +29,7 @@ end
29
29
 
30
30
  $ncc = NCC.new
31
31
 
32
- def error_message(status, err)
32
+ def error_message(status, err, object=nil)
33
33
  status_message = case status
34
34
  when 400
35
35
  "400 Bad Request"
@@ -42,6 +42,14 @@ def error_message(status, err)
42
42
  end
43
43
  status_message ||= status.to_s
44
44
  data = { "status" => status_message, "message" => err.message }
45
+ # I can't really just spit the object out here because I don't
46
+ # know what it is--it might be configuration objects that would
47
+ # contain passwords.
48
+ unless object.nil?
49
+ data['original_object'] = {
50
+ "class" => object.class
51
+ }
52
+ end
45
53
  if params.has_key? 'details'
46
54
  data['details'] = err.backtrace
47
55
  data['error'] = err.class
@@ -68,7 +76,7 @@ def respond(status, header={}, &block)
68
76
  rescue NCC::Error::Client => error
69
77
  halt error_message(400, error)
70
78
  rescue Exception => error
71
- halt error_message(500, error)
79
+ halt error_message(500, error, obj)
72
80
  end
73
81
  end
74
82
 
@@ -84,6 +92,7 @@ get '/ncc_api/v2' do
84
92
  "clouds" => "/ncc_api/v2/clouds",
85
93
  "images" => "/ncc_api/v2/images",
86
94
  "sizes" => "/ncc_api/v2/sizes",
95
+ "version" => NCC::VERSION,
87
96
  }
88
97
  end
89
98
  end
@@ -148,6 +157,11 @@ get '/ncc_api/v2/clouds/:cloud/instances/:instance_id/console_log' do |cloud,
148
157
  end
149
158
  end
150
159
 
160
+ get '/ncc_api/v2/clouds/:cloud/instances/:instance_id/console' do |cloud,
161
+ instance_id|
162
+ respond(200) { $ncc.clouds(cloud).console(instance_id) }
163
+ end
164
+
151
165
  post '/ncc_api/v2/clouds/:cloud/instances' do |cloud|
152
166
  respond 201 do
153
167
  begin
data/lib/ncc.rb CHANGED
@@ -16,24 +16,41 @@
16
16
  # */
17
17
 
18
18
 
19
+ require 'rubygems'
20
+ require 'noms/cmdb'
19
21
  require 'ncc/config'
20
22
  require 'ncc/connection'
21
23
  require 'ncc/instance'
22
24
  require 'ncc/error'
23
- require 'cmdbclient'
25
+ require 'ncc/version'
26
+
27
+ class NCC::Configurator
28
+
29
+ attr_accessor :config_path
30
+
31
+ def initialize
32
+ @config_path = ['/etc/ncc-api']
33
+ end
34
+
35
+ end
24
36
 
25
37
  class NCC
26
38
  attr_reader :config, :inventory
27
39
 
40
+ @@global_config = NCC::Configurator.new
41
+
42
+ def self.configure
43
+ yield @@global_config
44
+ end
45
+
28
46
  def initialize(config_path=nil, opt={})
29
47
  @logger = opt[:logger] if opt.has_key? :logger
30
- config_path ||= [
31
- '/etc/ncc-api']
48
+ config_path ||= @@global_config.config_path
32
49
  config_path = [config_path] unless config_path.respond_to? :unshift
33
50
  config_path.unshift(File.join(ENV['NCCAPI_HOME'], 'etc')) if
34
51
  ENV['NCCAPI_HOME']
35
52
  @config = NCC::Config.new(config_path, :logger => @logger)
36
- @inventory = CMDBclient.new(@config)
53
+ @inventory = NOMS::CMDB.new(@config)
37
54
  @clouds = { }
38
55
  end
39
56
 
@@ -99,4 +116,3 @@ class NCC
99
116
  end
100
117
 
101
118
  end
102
-
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ncc-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Brinkley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-15 00:00:00.000000000 Z
11
+ date: 2015-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fog
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: noms-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: The NOMS cloud controller API provides a ReSTful API abstracting and
56
70
  aggregating a set of specific cloud computing providers (called "clouds").
57
71
  email: jbrinkley@evernote.com
@@ -61,6 +75,7 @@ extensions: []
61
75
  extra_rdoc_files: []
62
76
  files:
63
77
  - lib/ncc/config.rb
78
+ - lib/ncc/version.rb
64
79
  - lib/ncc/connection/aws.rb
65
80
  - lib/ncc/connection/openstack.rb
66
81
  - lib/ncc/connection.rb