vcap_services_base 0.2.10
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 +7 -0
- data/lib/base/abstract.rb +11 -0
- data/lib/base/api/message.rb +31 -0
- data/lib/base/asynchronous_service_gateway.rb +529 -0
- data/lib/base/backup.rb +206 -0
- data/lib/base/barrier.rb +54 -0
- data/lib/base/base.rb +159 -0
- data/lib/base/base_async_gateway.rb +164 -0
- data/lib/base/base_job.rb +5 -0
- data/lib/base/catalog_manager_base.rb +67 -0
- data/lib/base/catalog_manager_v1.rb +225 -0
- data/lib/base/catalog_manager_v2.rb +291 -0
- data/lib/base/cloud_controller_services.rb +75 -0
- data/lib/base/datamapper_l.rb +148 -0
- data/lib/base/gateway.rb +167 -0
- data/lib/base/gateway_service_catalog.rb +68 -0
- data/lib/base/http_handler.rb +101 -0
- data/lib/base/job/async_job.rb +71 -0
- data/lib/base/job/config.rb +27 -0
- data/lib/base/job/lock.rb +153 -0
- data/lib/base/job/package.rb +112 -0
- data/lib/base/job/serialization.rb +365 -0
- data/lib/base/job/snapshot.rb +354 -0
- data/lib/base/node.rb +471 -0
- data/lib/base/node_bin.rb +154 -0
- data/lib/base/plan.rb +63 -0
- data/lib/base/provisioner.rb +1120 -0
- data/lib/base/provisioner_v1.rb +125 -0
- data/lib/base/provisioner_v2.rb +193 -0
- data/lib/base/service.rb +93 -0
- data/lib/base/service_advertiser.rb +184 -0
- data/lib/base/service_error.rb +122 -0
- data/lib/base/service_message.rb +94 -0
- data/lib/base/service_plan_change_set.rb +11 -0
- data/lib/base/simple_aop.rb +63 -0
- data/lib/base/snapshot_v2/snapshot.rb +227 -0
- data/lib/base/snapshot_v2/snapshot_client.rb +158 -0
- data/lib/base/snapshot_v2/snapshot_job.rb +95 -0
- data/lib/base/utils.rb +63 -0
- data/lib/base/version.rb +7 -0
- data/lib/base/warden/instance_utils.rb +161 -0
- data/lib/base/warden/node_utils.rb +205 -0
- data/lib/base/warden/service.rb +426 -0
- data/lib/base/worker_bin.rb +76 -0
- data/lib/vcap_services_base.rb +16 -0
- metadata +364 -0
data/lib/base/node.rb
ADDED
@@ -0,0 +1,471 @@
|
|
1
|
+
# Copyright (c) 2009-2011 VMware, Inc.
|
2
|
+
require 'nats/client'
|
3
|
+
require 'vcap/component'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'socket'
|
6
|
+
|
7
|
+
$:.unshift(File.dirname(__FILE__))
|
8
|
+
require 'base'
|
9
|
+
require 'service_message'
|
10
|
+
require 'datamapper_l'
|
11
|
+
|
12
|
+
class VCAP::Services::Base::Node < VCAP::Services::Base::Base
|
13
|
+
include VCAP::Services::Internal
|
14
|
+
|
15
|
+
def initialize(options)
|
16
|
+
super(options)
|
17
|
+
@node_id = options[:node_id]
|
18
|
+
@plan = options[:plan]
|
19
|
+
@capacity = options[:capacity]
|
20
|
+
@max_capacity = @capacity
|
21
|
+
@capacity_lock = Mutex.new
|
22
|
+
@migration_nfs = options[:migration_nfs]
|
23
|
+
@fqdn_hosts = options[:fqdn_hosts]
|
24
|
+
@op_time_limit = options[:op_time_limit]
|
25
|
+
@disabled_file = options[:disabled_file]
|
26
|
+
DataMapper::initialize_lock_file(options[:database_lock_file]) if options[:database_lock_file]
|
27
|
+
|
28
|
+
# A default supported version
|
29
|
+
# *NOTE: All services *MUST* override this to provide the actual supported versions
|
30
|
+
@supported_versions = options[:supported_versions] || []
|
31
|
+
z_interval = options[:z_interval] || 30
|
32
|
+
EM.add_periodic_timer(z_interval) do
|
33
|
+
EM.defer { update_varz }
|
34
|
+
end if @node_nats
|
35
|
+
|
36
|
+
# Defer 5 seconds to give service a change to wake up
|
37
|
+
EM.add_timer(5) do
|
38
|
+
EM.defer { update_varz }
|
39
|
+
end if @node_nats
|
40
|
+
end
|
41
|
+
|
42
|
+
def flavor
|
43
|
+
return "Node"
|
44
|
+
end
|
45
|
+
|
46
|
+
def on_connect_node
|
47
|
+
@logger.debug("#{service_description}: Connected to node mbus")
|
48
|
+
|
49
|
+
%w[provision unprovision bind unbind restore disable_instance
|
50
|
+
enable_instance import_instance update_instance cleanupnfs_instance purge_orphan
|
51
|
+
].each do |op|
|
52
|
+
eval %[@node_nats.subscribe("#{service_name}.#{op}.#{@node_id}") { |msg, reply| EM.defer{ on_#{op}(msg, reply) } }]
|
53
|
+
end
|
54
|
+
%w[discover check_orphan].each do |op|
|
55
|
+
eval %[@node_nats.subscribe("#{service_name}.#{op}") { |msg, reply| EM.defer{ on_#{op}(msg, reply) } }]
|
56
|
+
end
|
57
|
+
|
58
|
+
pre_send_announcement
|
59
|
+
send_node_announcement
|
60
|
+
EM.add_periodic_timer(30) { send_node_announcement }
|
61
|
+
end
|
62
|
+
|
63
|
+
# raise an error if operation does not finish in time limit
|
64
|
+
# and perform a rollback action if rollback function is provided
|
65
|
+
def timing_exec(time_limit, rollback=nil)
|
66
|
+
return unless block_given?
|
67
|
+
|
68
|
+
start = Time.now
|
69
|
+
response = yield
|
70
|
+
if response && Time.now - start > time_limit
|
71
|
+
rollback.call(response) if rollback
|
72
|
+
raise ServiceError::new(ServiceError::NODE_OPERATION_TIMEOUT)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def on_provision(msg, reply)
|
77
|
+
@logger.debug("#{service_description}: Provision request: #{msg} from #{reply}")
|
78
|
+
response = ProvisionResponse.new
|
79
|
+
rollback = lambda do |res|
|
80
|
+
@logger.error("#{service_description}: Provision takes too long. Rollback for #{res.inspect}")
|
81
|
+
@capacity_lock.synchronize{ @capacity += capacity_unit } if unprovision(res.credentials["name"], [])
|
82
|
+
end
|
83
|
+
|
84
|
+
timing_exec(@op_time_limit, rollback) do
|
85
|
+
provision_req = ProvisionRequest.decode(msg)
|
86
|
+
plan = provision_req.plan
|
87
|
+
credentials = provision_req.credentials
|
88
|
+
version = provision_req.version
|
89
|
+
@logger.debug("#{service_description}: Provision Request Details - plan=#{plan}, credentials=#{credentials}, version=#{version}")
|
90
|
+
credential = provision(plan, credentials, version)
|
91
|
+
credential['node_id'] = @node_id
|
92
|
+
response.credentials = credential
|
93
|
+
@capacity_lock.synchronize{ @capacity -= capacity_unit }
|
94
|
+
@logger.debug("#{service_description}: Successfully provisioned service for request #{msg}: #{response.inspect}")
|
95
|
+
response
|
96
|
+
end
|
97
|
+
publish(reply, encode_success(response))
|
98
|
+
rescue => e
|
99
|
+
@logger.warn("Exception at on_provision #{e}")
|
100
|
+
publish(reply, encode_failure(response, e))
|
101
|
+
end
|
102
|
+
|
103
|
+
def on_unprovision(msg, reply)
|
104
|
+
@logger.debug("#{service_description}: Unprovision request: #{msg}.")
|
105
|
+
response = SimpleResponse.new
|
106
|
+
unprovision_req = UnprovisionRequest.decode(msg)
|
107
|
+
name = unprovision_req.name
|
108
|
+
bindings = unprovision_req.bindings
|
109
|
+
result = unprovision(name, bindings)
|
110
|
+
if result
|
111
|
+
publish(reply, encode_success(response))
|
112
|
+
@capacity_lock.synchronize{ @capacity += capacity_unit }
|
113
|
+
else
|
114
|
+
publish(reply, encode_failure(response))
|
115
|
+
end
|
116
|
+
rescue => e
|
117
|
+
@logger.warn("Exception at on_unprovision #{e}")
|
118
|
+
if e.http_status == ServiceError::HTTP_NOT_FOUND
|
119
|
+
publish(reply, encode_success(response))
|
120
|
+
else
|
121
|
+
publish(reply, encode_failure(response, e))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def on_bind(msg, reply)
|
126
|
+
@logger.debug("#{service_description}: Bind request: #{msg} from #{reply}")
|
127
|
+
response = BindResponse.new
|
128
|
+
rollback = lambda do |res|
|
129
|
+
@logger.error("#{service_description}: Binding takes too long. Rollback for #{res.inspect}")
|
130
|
+
unbind(res.credentials)
|
131
|
+
end
|
132
|
+
|
133
|
+
timing_exec(@op_time_limit, rollback) do
|
134
|
+
bind_message = BindRequest.decode(msg)
|
135
|
+
name = bind_message.name
|
136
|
+
bind_opts = bind_message.bind_opts
|
137
|
+
credentials = bind_message.credentials
|
138
|
+
response.credentials = bind(name, bind_opts, credentials)
|
139
|
+
response
|
140
|
+
end
|
141
|
+
publish(reply, encode_success(response))
|
142
|
+
rescue => e
|
143
|
+
@logger.warn("Exception at on_bind #{e}")
|
144
|
+
publish(reply, encode_failure(response, e))
|
145
|
+
end
|
146
|
+
|
147
|
+
def on_unbind(msg, reply)
|
148
|
+
@logger.debug("#{service_description}: Unbind request: #{msg} from #{reply}")
|
149
|
+
response = SimpleResponse.new
|
150
|
+
unbind_req = UnbindRequest.decode(msg)
|
151
|
+
result = unbind(unbind_req.credentials)
|
152
|
+
if result
|
153
|
+
publish(reply, encode_success(response))
|
154
|
+
else
|
155
|
+
publish(reply, encode_failure(response))
|
156
|
+
end
|
157
|
+
rescue => e
|
158
|
+
@logger.warn("Exception at on_unbind #{e}")
|
159
|
+
publish(reply, encode_failure(response, e))
|
160
|
+
end
|
161
|
+
|
162
|
+
def on_restore(msg, reply)
|
163
|
+
@logger.debug("#{service_description}: Restore request: #{msg} from #{reply}")
|
164
|
+
response = SimpleResponse.new
|
165
|
+
restore_message = RestoreRequest.decode(msg)
|
166
|
+
instance_id = restore_message.instance_id
|
167
|
+
backup_path = restore_message.backup_path
|
168
|
+
result = restore(instance_id, backup_path)
|
169
|
+
if result
|
170
|
+
publish(reply, encode_success(response))
|
171
|
+
else
|
172
|
+
publish(reply, encode_failure(response))
|
173
|
+
end
|
174
|
+
rescue => e
|
175
|
+
@logger.warn("Exception at on_restore #{e}")
|
176
|
+
publish(reply, encode_failure(response, e))
|
177
|
+
end
|
178
|
+
|
179
|
+
# Disable and dump instance
|
180
|
+
def on_disable_instance(msg, reply)
|
181
|
+
@logger.debug("#{service_description}: Disable instance #{msg} request from #{reply}")
|
182
|
+
response = SimpleResponse.new
|
183
|
+
request = Yajl::Parser.parse(msg)
|
184
|
+
prov_handle, binding_handles = request
|
185
|
+
prov_cred = prov_handle["credentials"]
|
186
|
+
binding_creds = get_all_bindings(binding_handles)
|
187
|
+
file_path = get_migration_folder(prov_handle["service_id"])
|
188
|
+
FileUtils.mkdir_p(file_path)
|
189
|
+
result = disable_instance(prov_cred, binding_creds)
|
190
|
+
if result
|
191
|
+
# Do dump together with disable for simpler migration logic
|
192
|
+
result = dump_instance(prov_cred, binding_creds, file_path)
|
193
|
+
if result
|
194
|
+
publish(reply, encode_success(response))
|
195
|
+
else
|
196
|
+
publish(reply, encode_failure(response))
|
197
|
+
end
|
198
|
+
else
|
199
|
+
publish(reply, encode_failure(response))
|
200
|
+
end
|
201
|
+
rescue => e
|
202
|
+
@logger.warn("Exception at on_disable_instance #{e}")
|
203
|
+
publish(reply, encode_failure(response, e))
|
204
|
+
end
|
205
|
+
|
206
|
+
# Enable instance, the opposite operation of disable
|
207
|
+
def on_enable_instance(msg, reply)
|
208
|
+
@logger.debug("#{service_description}: enable instance #{msg} request from #{reply}")
|
209
|
+
response = SimpleResponse.new
|
210
|
+
request = Yajl::Parser.parse(msg)
|
211
|
+
prov_handle, binding_handles = request
|
212
|
+
prov_cred = prov_handle["credentials"]
|
213
|
+
binding_creds_hash = get_all_bindings_with_option(binding_handles)
|
214
|
+
result = enable_instance(prov_cred, binding_creds_hash)
|
215
|
+
if result
|
216
|
+
publish(reply, encode_success(response))
|
217
|
+
else
|
218
|
+
publish(reply, encode_failure(response))
|
219
|
+
end
|
220
|
+
rescue => e
|
221
|
+
@logger.warn("Exception at on_enable_instance #{e}")
|
222
|
+
publish(reply, encode_failure(response, e))
|
223
|
+
end
|
224
|
+
|
225
|
+
# Import the generated data
|
226
|
+
def on_import_instance(msg, reply)
|
227
|
+
@logger.debug("#{service_description}: import instance #{msg} request from #{reply}")
|
228
|
+
response = SimpleResponse.new
|
229
|
+
request = Yajl::Parser.parse(msg)
|
230
|
+
prov_handle, binding_handles = request
|
231
|
+
prov_cred = prov_handle["credentials"]
|
232
|
+
binding_creds_hash = get_all_bindings_with_option(binding_handles)
|
233
|
+
plan = prov_handle["configuration"]["plan"]
|
234
|
+
file_path = get_migration_folder(prov_handle["service_id"])
|
235
|
+
result = import_instance(prov_cred, binding_creds_hash, file_path, plan)
|
236
|
+
if result
|
237
|
+
publish(reply, encode_success(response))
|
238
|
+
else
|
239
|
+
publish(reply, encode_failure(response))
|
240
|
+
end
|
241
|
+
rescue => e
|
242
|
+
@logger.warn("Exception at on_import_instance #{e}")
|
243
|
+
publish(reply, encode_failure(response, e))
|
244
|
+
end
|
245
|
+
|
246
|
+
# Update credentials in destination node of migration
|
247
|
+
def on_update_instance(msg, reply)
|
248
|
+
@logger.debug("#{service_description}: update instance #{msg} request from #{reply}")
|
249
|
+
request = Yajl::Parser.parse(msg)
|
250
|
+
prov_handle, binding_handles = request
|
251
|
+
prov_cred = prov_handle["credentials"]
|
252
|
+
binding_creds_hash = get_all_bindings_with_option(binding_handles)
|
253
|
+
result = update_instance(prov_cred, binding_creds_hash)
|
254
|
+
# Need decrease the capacity in destination node when finish migration
|
255
|
+
@capacity_lock.synchronize{ @capacity -= capacity_unit }
|
256
|
+
prov_cred, binding_creds_hash = result
|
257
|
+
# Update node_id in provision credentials
|
258
|
+
prov_cred["node_id"] = @node_id
|
259
|
+
handles = []
|
260
|
+
prov_handle["credentials"] = prov_cred
|
261
|
+
handles << prov_handle
|
262
|
+
binding_handles.each do |handle|
|
263
|
+
handle["credentials"] = binding_creds_hash[handle["service_id"]]["credentials"]
|
264
|
+
handles << handle
|
265
|
+
end
|
266
|
+
publish(reply, Yajl::Encoder.encode(handles))
|
267
|
+
rescue => e
|
268
|
+
@logger.warn("Exception at on_update_instance #{e}")
|
269
|
+
response = SimpleResponse.new
|
270
|
+
publish(reply, encode_failure(response, e))
|
271
|
+
end
|
272
|
+
|
273
|
+
# Cleanup nfs folder which contains migration data
|
274
|
+
def on_cleanupnfs_instance(msg, reply)
|
275
|
+
@logger.debug("#{service_description}: cleanup nfs request #{msg} from #{reply}")
|
276
|
+
response = SimpleResponse.new
|
277
|
+
request = Yajl::Parser.parse(msg)
|
278
|
+
prov_handle, _ = request
|
279
|
+
FileUtils.rm_rf(get_migration_folder(prov_handle["service_id"]))
|
280
|
+
publish(reply, encode_success(response))
|
281
|
+
rescue => e
|
282
|
+
@logger.warn("Exception at on_cleanupnfs_instance #{e}")
|
283
|
+
publish(reply, encode_failure(response, e))
|
284
|
+
end
|
285
|
+
|
286
|
+
# Send all handles to gateway to check orphan
|
287
|
+
def on_check_orphan(msg, reply)
|
288
|
+
@logger.debug("#{service_description}: Request to check orphan")
|
289
|
+
live_ins_list = all_instances_list
|
290
|
+
live_bind_list = all_bindings_list
|
291
|
+
handles_size = @max_nats_payload - 200
|
292
|
+
|
293
|
+
group_handles_in_json(live_ins_list, live_bind_list, handles_size) do |ins_list, bind_list|
|
294
|
+
request = NodeHandlesReport.new
|
295
|
+
request.instances_list = ins_list
|
296
|
+
request.bindings_list = bind_list
|
297
|
+
request.node_id = @node_id
|
298
|
+
publish("#{service_name}.node_handles", request.encode)
|
299
|
+
end
|
300
|
+
rescue => e
|
301
|
+
@logger.warn("Exception at on_check_orphan #{e}")
|
302
|
+
end
|
303
|
+
|
304
|
+
def on_purge_orphan(msg, reply)
|
305
|
+
@logger.debug("#{service_description}: Request to purge orphan" )
|
306
|
+
request = PurgeOrphanRequest.decode(msg)
|
307
|
+
purge_orphan(request.orphan_ins_list,request.orphan_binding_list)
|
308
|
+
rescue => e
|
309
|
+
@logger.warn("Exception at on_purge_orphan #{e}")
|
310
|
+
end
|
311
|
+
|
312
|
+
def purge_orphan(oi_list,ob_list)
|
313
|
+
oi_list.each do |ins|
|
314
|
+
begin
|
315
|
+
@logger.debug("Unprovision orphan instance #{ins}")
|
316
|
+
@capacity_lock.synchronize{ @capacity += capacity_unit } if unprovision(ins,[])
|
317
|
+
rescue => e
|
318
|
+
@logger.debug("Error on purge orphan instance #{ins}: #{e}")
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
ob_list.each do |credential|
|
323
|
+
begin
|
324
|
+
@logger.debug("Unbind orphan binding #{credential}")
|
325
|
+
unbind(credential)
|
326
|
+
rescue => e
|
327
|
+
@logger.debug("Error on purge orphan binding #{credential}: #{e}")
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
# Subclass must overwrite this method to enable check orphan instance feature.
|
333
|
+
# Otherwise it will not check orphan instance
|
334
|
+
# The return value should be a list of instance name(handle["service_id"]).
|
335
|
+
def all_instances_list
|
336
|
+
[]
|
337
|
+
end
|
338
|
+
|
339
|
+
# Subclass must overwrite this method to enable check orphan binding feature.
|
340
|
+
# Otherwise it will not check orphan bindings
|
341
|
+
# The return value should be a list of binding credentials
|
342
|
+
# Binding credential will be the argument for unbind method
|
343
|
+
# And it should have at least username & name property for base code
|
344
|
+
# to find the orphans
|
345
|
+
def all_bindings_list
|
346
|
+
[]
|
347
|
+
end
|
348
|
+
|
349
|
+
# Get the tmp folder for migration
|
350
|
+
def get_migration_folder(instance)
|
351
|
+
File.join(@migration_nfs, 'migration', service_name, instance)
|
352
|
+
end
|
353
|
+
|
354
|
+
def get_all_bindings(handles)
|
355
|
+
binding_creds = []
|
356
|
+
handles.each do |handle|
|
357
|
+
binding_creds << handle["credentials"]
|
358
|
+
end
|
359
|
+
binding_creds
|
360
|
+
end
|
361
|
+
|
362
|
+
def get_all_bindings_with_option(handles)
|
363
|
+
binding_creds_hash = {}
|
364
|
+
handles.each do |handle|
|
365
|
+
value = {
|
366
|
+
"credentials" => handle["credentials"],
|
367
|
+
"binding_options" => nil
|
368
|
+
}
|
369
|
+
value["binding_options"] = handle["configuration"]["data"]["binding_options"] if handle["configuration"].has_key?("data")
|
370
|
+
binding_creds_hash[handle["service_id"]] = value
|
371
|
+
end
|
372
|
+
binding_creds_hash
|
373
|
+
end
|
374
|
+
|
375
|
+
def on_discover(msg, reply)
|
376
|
+
send_node_announcement(msg, reply)
|
377
|
+
end
|
378
|
+
|
379
|
+
def pre_send_announcement
|
380
|
+
end
|
381
|
+
|
382
|
+
def disabled?
|
383
|
+
File.exist?(@disabled_file)
|
384
|
+
end
|
385
|
+
|
386
|
+
def send_node_announcement(msg=nil, reply=nil)
|
387
|
+
if disabled?
|
388
|
+
@logger.info("#{service_description}: Not sending announcement because node is disabled")
|
389
|
+
return
|
390
|
+
end
|
391
|
+
unless node_ready?
|
392
|
+
@logger.debug("#{service_description}: Not ready to send announcement")
|
393
|
+
return
|
394
|
+
end
|
395
|
+
@logger.debug("#{service_description}: Sending announcement for #{reply || "everyone"}")
|
396
|
+
req = nil
|
397
|
+
req = Yajl::Parser.parse(msg) if msg
|
398
|
+
if !req || req["plan"] == @plan
|
399
|
+
a = announcement
|
400
|
+
a[:id] = @node_id
|
401
|
+
a[:plan] = @plan
|
402
|
+
a[:supported_versions] = @supported_versions
|
403
|
+
publish(reply || "#{service_name}.announce", Yajl::Encoder.encode(a))
|
404
|
+
end
|
405
|
+
rescue => e
|
406
|
+
@logger.warn("Exception at send_node_announcement #{e}")
|
407
|
+
end
|
408
|
+
|
409
|
+
def node_ready?()
|
410
|
+
# Service Node subclasses can override this method if they depend
|
411
|
+
# on some external service in order to operate; for example, MySQL
|
412
|
+
# and Postgresql require a connection to the underlying server.
|
413
|
+
true
|
414
|
+
end
|
415
|
+
|
416
|
+
def varz_details
|
417
|
+
# Service Node subclasses may want to override this method to
|
418
|
+
# provide service specific data beyond what is returned by their
|
419
|
+
# "announcement" method.
|
420
|
+
return announcement
|
421
|
+
end
|
422
|
+
|
423
|
+
def capacity_unit
|
424
|
+
# subclasses could overwrite this method to re-define
|
425
|
+
# the capacity unit decreased/increased by provision/unprovision
|
426
|
+
1
|
427
|
+
end
|
428
|
+
|
429
|
+
# Helper
|
430
|
+
def encode_success(response)
|
431
|
+
response.success = true
|
432
|
+
response.encode
|
433
|
+
end
|
434
|
+
|
435
|
+
def encode_failure(response, error=nil)
|
436
|
+
response.success = false
|
437
|
+
if error.nil? || !error.is_a?(ServiceError)
|
438
|
+
error = ServiceError.new(ServiceError::INTERNAL_ERROR)
|
439
|
+
end
|
440
|
+
response.error = error.to_hash
|
441
|
+
response.encode
|
442
|
+
end
|
443
|
+
|
444
|
+
def get_host
|
445
|
+
@fqdn_hosts ? Socket.gethostname : @local_ip
|
446
|
+
end
|
447
|
+
|
448
|
+
# Service Node subclasses must implement the following methods
|
449
|
+
|
450
|
+
# provision(plan) --> {name, host, port, user, password}, {version}
|
451
|
+
abstract :provision
|
452
|
+
|
453
|
+
# unprovision(name) --> void
|
454
|
+
abstract :unprovision
|
455
|
+
|
456
|
+
# bind(name, bind_opts) --> {host, port, login, secret}
|
457
|
+
abstract :bind
|
458
|
+
|
459
|
+
# unbind(credentials) --> void
|
460
|
+
abstract :unbind
|
461
|
+
|
462
|
+
# announcement() --> { any service-specific announcement details }
|
463
|
+
abstract :announcement
|
464
|
+
|
465
|
+
# service_name() --> string
|
466
|
+
# (inhereted from VCAP::Services::Base::Base)
|
467
|
+
|
468
|
+
# <action>_instance(prov_credential, binding_credentials) --> true for success and nil for fail
|
469
|
+
abstract :disable_instance, :dump_instance, :import_instance, :enable_instance, :update_instance
|
470
|
+
|
471
|
+
end
|