nfv/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/nfvi_guest_api.py

877 lines
32 KiB
Python
Executable File

#
# Copyright (c) 2015-2018 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import json
import httplib
from nfv_common import debug
from nfv_vim import nfvi
from nfv_plugins.nfvi_plugins import config
from nfv_plugins.nfvi_plugins.openstack import rest_api
from nfv_plugins.nfvi_plugins.openstack import exceptions
from nfv_plugins.nfvi_plugins.openstack import openstack
from nfv_plugins.nfvi_plugins.openstack import guest
DLOG = debug.debug_get_logger('nfv_plugins.nfvi_plugins.guest_api')
def guest_service_get_name(name):
"""
Convert the nfvi guest service naming
"""
if guest.GUEST_SERVICE_NAME.HEARTBEAT == name:
return nfvi.objects.v1.GUEST_SERVICE_NAME.HEARTBEAT
else:
return nfvi.objects.v1.GUEST_SERVICE_NAME.UNKNOWN
def guest_service_get_admin_state(state):
"""
Convert the nfvi guest service state to a guest service administrative
state
"""
if guest.GUEST_SERVICE_STATE.ENABLED == state:
return nfvi.objects.v1.GUEST_SERVICE_ADMIN_STATE.UNLOCKED
else:
return nfvi.objects.v1.GUEST_SERVICE_ADMIN_STATE.LOCKED
def guest_service_get_service_state(state):
"""
Convert the guest service administrative state to nfvi guest service state
"""
if nfvi.objects.v1.GUEST_SERVICE_ADMIN_STATE.UNLOCKED == state:
return guest.GUEST_SERVICE_STATE.ENABLED
else:
return guest.GUEST_SERVICE_STATE.DISABLED
def guest_service_get_oper_state(status):
"""
Convert the nfvi guest service status to a guest service operational
state
"""
if guest.GUEST_SERVICE_STATUS.ENABLED == status:
return nfvi.objects.v1.GUEST_SERVICE_OPER_STATE.ENABLED
else:
return nfvi.objects.v1.GUEST_SERVICE_OPER_STATE.DISABLED
def instance_get_event(action_type, pre_notification):
"""
Convert the action type to a guest instance event
"""
if nfvi.objects.v1.INSTANCE_ACTION_TYPE.PAUSE == action_type:
event = guest.GUEST_EVENT.PAUSE
elif nfvi.objects.v1.INSTANCE_ACTION_TYPE.UNPAUSE == action_type:
event = guest.GUEST_EVENT.UNPAUSE
elif nfvi.objects.v1.INSTANCE_ACTION_TYPE.SUSPEND == action_type:
event = guest.GUEST_EVENT.SUSPEND
elif nfvi.objects.v1.INSTANCE_ACTION_TYPE.RESUME == action_type:
event = guest.GUEST_EVENT.RESUME
elif nfvi.objects.v1.INSTANCE_ACTION_TYPE.REBOOT == action_type:
event = guest.GUEST_EVENT.REBOOT
elif nfvi.objects.v1.INSTANCE_ACTION_TYPE.STOP == action_type:
event = guest.GUEST_EVENT.STOP
elif nfvi.objects.v1.INSTANCE_ACTION_TYPE.LIVE_MIGRATE == action_type:
if pre_notification:
event = guest.GUEST_EVENT.LIVE_MIGRATE_BEGIN
else:
event = guest.GUEST_EVENT.LIVE_MIGRATE_END
elif nfvi.objects.v1.INSTANCE_ACTION_TYPE.COLD_MIGRATE == action_type:
if pre_notification:
event = guest.GUEST_EVENT.COLD_MIGRATE_BEGIN
else:
event = guest.GUEST_EVENT.COLD_MIGRATE_END
elif nfvi.objects.v1.INSTANCE_ACTION_TYPE.RESIZE == action_type:
if pre_notification:
event = guest.GUEST_EVENT.RESIZE_BEGIN
else:
event = guest.GUEST_EVENT.RESIZE_END
elif nfvi.objects.v1.INSTANCE_ACTION_TYPE.CONFIRM_RESIZE == action_type:
event = guest.GUEST_EVENT.RESIZE_END
elif nfvi.objects.v1.INSTANCE_ACTION_TYPE.REVERT_RESIZE == action_type:
event = guest.GUEST_EVENT.RESIZE_END
else:
event = guest.GUEST_EVENT.UNKNOWN
DLOG.error("Unsupported action-type %s" % action_type)
return event
def instance_get_action_type(event):
"""
Convert guest instance event to an action type
"""
if guest.GUEST_EVENT.PAUSE == event:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.PAUSE
elif guest.GUEST_EVENT.UNPAUSE == event:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.UNPAUSE
elif guest.GUEST_EVENT.SUSPEND == event:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.SUSPEND
elif guest.GUEST_EVENT.RESUME == event:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.RESUME
elif guest.GUEST_EVENT.REBOOT == event:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.REBOOT
elif guest.GUEST_EVENT.STOP == event:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.STOP
elif guest.GUEST_EVENT.LIVE_MIGRATE_BEGIN == event:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.LIVE_MIGRATE
elif guest.GUEST_EVENT.LIVE_MIGRATE_END == event:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.LIVE_MIGRATE
elif guest.GUEST_EVENT.COLD_MIGRATE_BEGIN == event:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.COLD_MIGRATE
elif guest.GUEST_EVENT.COLD_MIGRATE_END == event:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.COLD_MIGRATE
elif guest.GUEST_EVENT.RESIZE_BEGIN == event:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.RESIZE
elif guest.GUEST_EVENT.RESIZE_END == event:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.RESIZE
else:
action_type = nfvi.objects.v1.INSTANCE_ACTION_TYPE.UNKNOWN
DLOG.error("Unsupported event %s" % event)
return action_type
def get_services_with_guest_service_state(services):
"""
Return guest service data with guest service administrative state
converted to nfvi guest service state
"""
services_data = []
for service in services:
service_data = dict()
service_data['service'] = service['service']
service_data['state'] \
= guest_service_get_service_state(service['admin_state'])
services_data.append(service_data)
return services_data
class NFVIGuestAPI(nfvi.api.v1.NFVIGuestAPI):
"""
NFVI Guest API Class Definition
"""
_name = 'Guest-API'
_version = '1.0.0'
_provider = 'Wind River'
_signature = '22b3dbf6-e4ba-441b-8797-fb8a51210a43'
@property
def name(self):
return self._name
@property
def version(self):
return self._version
@property
def provider(self):
return self._provider
@property
def signature(self):
return self._signature
def __init__(self):
super(NFVIGuestAPI, self).__init__()
self._token = None
self._directory = None
self._rest_api_server = None
self._host_services_query_callback = None
self._guest_services_query_callback = None
self._guest_services_state_notify_callbacks = list()
self._guest_services_alarm_notify_callbacks = list()
self._guest_services_action_notify_callbacks = list()
def guest_services_create(self, future, instance_uuid, host_name,
services, callback):
"""
Guest Services Create
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("OpenStack get-token did not complete, "
"instance_uuid=%s." % instance_uuid)
return
self._token = future.result.data
future.work(guest.guest_services_create, self._token,
instance_uuid, host_name, services)
future.result = (yield)
if not future.result.is_complete():
return
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
else:
DLOG.exception("Caught exception while trying to create "
"guest services, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to create "
"guest services, instance_uuid=%s, error=%s."
% (instance_uuid, e))
finally:
callback.send(response)
callback.close()
def guest_services_set(self, future, instance_uuid, host_name,
services, callback):
"""
Guest Services Set
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("OpenStack get-token did not complete, "
"instance_uuid=%s." % instance_uuid)
return
self._token = future.result.data
services_data = get_services_with_guest_service_state(services)
future.work(guest.guest_services_set, self._token,
instance_uuid, host_name, services_data)
future.result = (yield)
if not future.result.is_complete():
return
set_data = future.result.data
result_data = dict()
result_data['instance_uuid'] = set_data['uuid']
result_data['host_name'] = set_data['hostname']
service_objs = list()
for service in set_data.get('services', list()):
service_name = guest_service_get_name(service['service'])
admin_state = guest_service_get_admin_state(service['state'])
oper_state = guest_service_get_oper_state(service['status'])
restart_timeout = service.get('restart-timeout', None)
if restart_timeout is not None:
restart_timeout = int(restart_timeout)
service_obj = nfvi.objects.v1.GuestService(
service_name, admin_state, oper_state, restart_timeout)
service_objs.append(service_obj)
result_data['services'] = service_objs
response['result-data'] = result_data
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
else:
DLOG.exception("Caught exception while trying to set "
"guest services, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to set "
"guest services, instance_uuid=%s, error=%s."
% (instance_uuid, e))
finally:
callback.send(response)
callback.close()
def guest_services_delete(self, future, instance_uuid, callback):
"""
Guest Services Delete
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("OpenStack get-token did not complete, "
"instance_uuid=%s." % instance_uuid)
return
self._token = future.result.data
future.work(guest.guest_services_delete, self._token,
instance_uuid)
try:
future.result = (yield)
if not future.result.is_complete():
return
except exceptions.OpenStackRestAPIException as e:
if httplib.NOT_FOUND != e.http_status_code:
raise
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
else:
DLOG.exception("Caught exception while trying to delete "
"guest services, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to delete "
"guest services, instance_uuid=%s, error=%s."
% (instance_uuid, e))
finally:
callback.send(response)
callback.close()
def guest_services_query(self, future, instance_uuid, callback):
"""
Guest Services Query
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("OpenStack get-token did not complete, "
"instance_uuid=%s." % instance_uuid)
return
self._token = future.result.data
future.work(guest.guest_services_query, self._token, instance_uuid)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("Guest-Services query failed, operation "
"did not complete, instance_uuid=%s" %
instance_uuid)
return
query_data = future.result.data
result_data = dict()
result_data['instance_uuid'] = query_data['uuid']
result_data['host_name'] = query_data['hostname']
service_objs = list()
for service in query_data.get('services', list()):
service_name = guest_service_get_name(service['service'])
admin_state = guest_service_get_admin_state(service['state'])
oper_state = guest_service_get_oper_state(service['status'])
restart_timeout = service.get('restart-timeout', None)
if restart_timeout is not None:
restart_timeout = int(restart_timeout)
service_obj = nfvi.objects.v1.GuestService(
service_name, admin_state, oper_state, restart_timeout)
service_objs.append(service_obj)
result_data['services'] = service_objs
response['result-data'] = result_data
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
else:
DLOG.exception("Caught exception while trying to query "
"guest services, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to query "
"guest services, instance_uuid=%s, error=%s."
% (instance_uuid, e))
finally:
callback.send(response)
callback.close()
def guest_services_vote(self, future, instance_uuid, host_name,
action_type, callback):
"""
Guest Services Vote
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("OpenStack get-token did not complete, "
"instance_uuid=%s." % instance_uuid)
return
self._token = future.result.data
future.work(guest.guest_services_vote, self._token, instance_uuid,
host_name, instance_get_event(action_type,
pre_notification=True))
future.result = (yield)
if not future.result.is_complete():
DLOG.error("Guest-Services vote failed, action-type %s "
"did not complete, instance_uuid=%s" %
(action_type, instance_uuid))
return
vote_data = future.result.data
response['uuid'] = vote_data.get('uuid', instance_uuid)
response['host-name'] = vote_data.get('hostname', host_name)
response['action-type'] = vote_data.get('action', action_type)
response['timeout'] = int(vote_data.get('timeout', '15'))
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
else:
DLOG.exception("Caught exception while trying to vote,"
"action_type=%s error=%s." % (action_type, e))
except Exception as e:
DLOG.exception("Caught exception while trying to vote "
"guest services, instance_uuid=%s, error=%s."
% (instance_uuid, e))
finally:
callback.send(response)
callback.close()
def guest_services_notify(self, future, instance_uuid, host_name,
action_type, pre_notification, callback):
"""
Guest Services Notify
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("OpenStack get-token did not complete, "
"instance_uuid=%s." % instance_uuid)
return
self._token = future.result.data
future.work(guest.guest_services_notify, self._token,
instance_uuid, host_name,
instance_get_event(action_type, pre_notification))
future.result = (yield)
if not future.result.is_complete():
DLOG.error("Guest-Services_notify failed, action-type %s "
"did not complete, instance_uuid=%s" %
(action_type, instance_uuid))
return
notify_data = future.result.data
response['uuid'] = notify_data.get('uuid', instance_uuid)
response['host-name'] = notify_data.get('hostname', host_name)
response['action-type'] = notify_data.get('action', action_type)
response['timeout'] = int(notify_data.get('timeout', '15'))
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
else:
DLOG.exception("Caught exception while trying to notify,"
"action_type=%s error=%s." % (action_type, e))
except Exception as e:
DLOG.exception("Caught exception while trying to notify "
"guest services, instance_uuid=%s, error=%s."
% (instance_uuid, e))
finally:
callback.send(response)
callback.close()
def host_services_rest_api_get_handler(self, request_dispatch):
"""
Host-Services Rest-API GET handler
"""
content_len = int(request_dispatch.headers.getheader('content-length',
0))
content = request_dispatch.rfile.read(content_len)
DLOG.info("Content=%s, len=%s" % (content, content_len))
http_payload = None
http_response = httplib.OK
if content:
host_data = json.loads(content)
if host_data['uuid'] is None:
DLOG.error("Invalid host uuid received")
http_response = httplib.BAD_REQUEST
elif host_data['hostname'] is None:
DLOG.info("Invalid host name received")
http_response = httplib.BAD_REQUEST
else:
(success, host_state) = \
self._host_services_query_callback(host_data['hostname'])
if not success:
http_response = httplib.BAD_REQUEST
else:
http_payload = dict()
http_payload['uuid'] = host_data['uuid']
http_payload['hostname'] = host_data['hostname']
http_payload['state'] = host_state
else:
http_response = httplib.NO_CONTENT
DLOG.debug("Host rest-api get path: %s." % request_dispatch.path)
request_dispatch.send_response(http_response)
if http_payload is not None:
request_dispatch.send_header('Content-Type', 'application/json')
request_dispatch.end_headers()
request_dispatch.wfile.write(json.dumps(http_payload))
request_dispatch.done()
def guest_services_rest_api_get_handler(self, request_dispatch):
"""
Guest-Services Rest-API GET handler
"""
# /nfvi-plugins/v1/instances/<instance-uuid>
# /nfvi-plugins/v1/instances/?host_uuid=<host-uuid>
host_uuid = None
instance_uuid = None
http_payload = None
path = request_dispatch.path
host_prefix = "host_uuid"
if host_prefix in path:
host_uuid = path.split('=')[-1]
else:
instance_uuid = path.split('/')[-1]
DLOG.debug("Guest-Services rest-api path=%s, host_uuid=%s, "
"instance_uuid=%s" % (path, host_uuid, instance_uuid))
http_response = httplib.OK
(success, result) = \
self._guest_services_query_callback(host_uuid, instance_uuid)
if not success:
http_response = httplib.BAD_REQUEST
else:
if instance_uuid:
result['services'] = \
get_services_with_guest_service_state(result['services'])
else:
for r in result['instances']:
r['services'] = \
get_services_with_guest_service_state(r['services'])
http_payload = result
DLOG.debug("Guest-Services rest-api get path: %s." %
request_dispatch.path)
request_dispatch.send_response(http_response)
if http_payload is not None:
request_dispatch.send_header('Content-Type', 'application/json')
request_dispatch.end_headers()
request_dispatch.wfile.write(json.dumps(http_payload))
request_dispatch.done()
def guest_services_rest_api_patch_handler(self, request_dispatch):
"""
Guest-Services Rest-API PATCH handler callback
"""
content_len = int(request_dispatch.headers.getheader('content-length',
0))
content = request_dispatch.rfile.read(content_len)
http_payload = None
http_response = httplib.OK
if content:
instance_data = json.loads(content)
instance_uuid = instance_data.get('uuid', None)
host_name = instance_data.get('hostname', None)
event_type = instance_data.get('event-type', None)
event_data = instance_data.get('event-data', None)
result = None
if instance_uuid is None:
DLOG.info("Invalid instance uuid received")
http_response = httplib.BAD_REQUEST
elif event_type is None:
DLOG.info("Invalid event-type received")
http_response = httplib.BAD_REQUEST
elif event_data is None:
DLOG.info("Invalid event-data received")
http_response = httplib.BAD_REQUEST
else:
if 'service' == event_type:
services = event_data.get('services', list())
service_objs = list()
for service in services:
restart_timeout = service.get('restart-timeout', None)
if restart_timeout is not None:
restart_timeout = int(restart_timeout)
service_obj = nfvi.objects.v1.GuestService(
guest_service_get_name(service['service']),
guest_service_get_admin_state(service['state']),
guest_service_get_oper_state(service['status']),
restart_timeout)
service_objs.append(service_obj)
for callback in self._guest_services_state_notify_callbacks:
callback(instance_uuid, host_name, service_objs)
elif 'alarm' == event_type:
services = event_data.get('services', list())
for service_data in services:
if guest.GUEST_SERVICE_NAME.HEARTBEAT == \
service_data['service']:
avail_status = service_data.get('state', None)
recovery_action = \
service_data.get('repair-action', None)
if 'reboot' == recovery_action:
recovery_action = \
nfvi.objects.v1.INSTANCE_ACTION_TYPE.REBOOT
elif 'stop' == recovery_action:
recovery_action = \
nfvi.objects.v1.INSTANCE_ACTION_TYPE.STOP
elif 'log' == recovery_action:
recovery_action = \
nfvi.objects.v1.INSTANCE_ACTION_TYPE.LOG
if 'failed' == avail_status:
avail_status = \
nfvi.objects.v1.INSTANCE_AVAIL_STATUS.FAILED
elif 'unhealthy' == avail_status:
avail_status = \
nfvi.objects.v1.INSTANCE_AVAIL_STATUS.UNHEALTHY
for callback in \
self._guest_services_alarm_notify_callbacks:
(success, result) = callback(instance_uuid,
avail_status,
recovery_action)
if not success:
DLOG.error("Callback failed for "
"instance_uuid=%s" % instance_uuid)
http_response = httplib.BAD_REQUEST
elif 'action' == event_type:
action_type = \
instance_get_action_type(event_data.get('action'))
guest_response = event_data.get('guest-response')
if guest.GUEST_VOTE_STATE.REJECT == guest_response:
action_state = \
nfvi.objects.v1.INSTANCE_ACTION_STATE.REJECTED
elif guest.GUEST_VOTE_STATE.ALLOW == guest_response:
action_state = \
nfvi.objects.v1.INSTANCE_ACTION_STATE.ALLOWED
elif guest.GUEST_VOTE_STATE.PROCEED == guest_response:
action_state = \
nfvi.objects.v1.INSTANCE_ACTION_STATE.PROCEED
else:
action_state = guest.GUEST_VOTE_STATE.PROCEED
DLOG.info("Invalid guest-response received, "
"defaulting to proceed, response=%s."
% guest_response)
reason = event_data.get('reason')
for callback in \
self._guest_services_action_notify_callbacks:
result = None
success = callback(instance_uuid, action_type,
action_state, reason)
if not success:
DLOG.error("callback failed for instance_uuid=%s"
% instance_uuid)
http_response = httplib.BAD_REQUEST
else:
DLOG.info("Invalid event-type %s received" % event_type)
http_response = httplib.BAD_REQUEST
if httplib.OK == http_response:
http_payload = result
else:
http_response = httplib.NO_CONTENT
DLOG.debug("Guest-Services rest-api patch path: %s."
% request_dispatch.path)
request_dispatch.send_response(http_response)
if http_payload is not None:
request_dispatch.send_header('Content-Type', 'application/json')
request_dispatch.end_headers()
request_dispatch.wfile.write(json.dumps(http_payload))
request_dispatch.done()
def register_host_services_query_callback(self, callback):
"""
Register for Host Services query
"""
self._host_services_query_callback = callback
def register_guest_services_query_callback(self, callback):
"""
Register for Guest Services query
"""
self._guest_services_query_callback = callback
def register_guest_services_state_notify_callback(self, callback):
"""
Register for Guest Services notify service type event
"""
self._guest_services_state_notify_callbacks.append(callback)
def register_guest_services_alarm_notify_callback(self, callback):
"""
Register for Guest Services notify for alarm type event
"""
self._guest_services_alarm_notify_callbacks.append(callback)
def register_guest_services_action_notify_callback(self, callback):
"""
Register for Guest Services notify for action type event
"""
self._guest_services_action_notify_callbacks.append(callback)
def initialize(self, config_file):
"""
Initialize the plugin
"""
config.load(config_file)
self._directory = openstack.get_directory(
config, openstack.SERVICE_CATEGORY.PLATFORM)
self._rest_api_server = rest_api.rest_api_get_server(
config.CONF['guest-rest-api']['host'],
config.CONF['guest-rest-api']['port'])
self._rest_api_server.add_handler(
'GET', '/nfvi-plugins/v1/hosts*',
self.host_services_rest_api_get_handler)
self._rest_api_server.add_handler(
'GET', '/nfvi-plugins/v1/instances*',
self.guest_services_rest_api_get_handler)
self._rest_api_server.add_handler(
'PATCH', '/nfvi-plugins/v1/instances*',
self.guest_services_rest_api_patch_handler)
def finalize(self):
"""
Finalize the plugin
"""
return