Internet of Things resource management service for OpenStack clouds.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

service.py 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. # coding=utf-8
  2. #
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  5. # not use this file except in compliance with the License. You may obtain
  6. # a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. # License for the specific language governing permissions and limitations
  14. # under the License.
  15. from oslo_utils import strutils
  16. from oslo_utils import uuidutils
  17. from iotronic.common import exception
  18. from iotronic.db import api as db_api
  19. from iotronic.objects import base
  20. from iotronic.objects import utils as obj_utils
  21. """
  22. ACTIONS = ['ServiceCall', 'ServiceStop', 'ServiceStart',
  23. 'ServiceStatus', 'ServiceReboot']
  24. CUSTOM_PARAMS = ['ServiceCall', 'ServiceStart', 'ServiceReboot']
  25. NO_PARAMS = ['ServiceStatus']
  26. def is_valid_action(action):
  27. if action not in ACTIONS:
  28. raise exception.InvalidServiceAction(action=action)
  29. return True
  30. def want_customs_params(action):
  31. return True if action in CUSTOM_PARAMS else False
  32. def want_params(action):
  33. return False if action in NO_PARAMS else True
  34. """
  35. class Service(base.IotronicObject):
  36. # Version 1.0: Initial version
  37. VERSION = '1.0'
  38. dbapi = db_api.get_instance()
  39. fields = {
  40. 'id': int,
  41. 'uuid': obj_utils.str_or_none,
  42. 'name': obj_utils.str_or_none,
  43. 'project': obj_utils.str_or_none,
  44. 'port': int,
  45. 'protocol': obj_utils.str_or_none,
  46. 'extra': obj_utils.dict_or_none,
  47. }
  48. @staticmethod
  49. def _from_db_object(service, db_service):
  50. """Converts a database entity to a formal object."""
  51. for field in service.fields:
  52. service[field] = db_service[field]
  53. service.obj_reset_changes()
  54. return service
  55. @base.remotable_classmethod
  56. def get(cls, context, service_id):
  57. """Find a service based on its id or uuid and return a Board object.
  58. :param service_id: the id *or* uuid of a service.
  59. :returns: a :class:`Board` object.
  60. """
  61. if strutils.is_int_like(service_id):
  62. return cls.get_by_id(context, service_id)
  63. elif uuidutils.is_uuid_like(service_id):
  64. return cls.get_by_uuid(context, service_id)
  65. else:
  66. raise exception.InvalidIdentity(identity=service_id)
  67. @base.remotable_classmethod
  68. def get_by_id(cls, context, service_id):
  69. """Find a service based on its integer id and return a Board object.
  70. :param service_id: the id of a service.
  71. :returns: a :class:`Board` object.
  72. """
  73. db_service = cls.dbapi.get_service_by_id(service_id)
  74. service = Service._from_db_object(cls(context), db_service)
  75. return service
  76. @base.remotable_classmethod
  77. def get_by_uuid(cls, context, uuid):
  78. """Find a service based on uuid and return a Board object.
  79. :param uuid: the uuid of a service.
  80. :returns: a :class:`Board` object.
  81. """
  82. db_service = cls.dbapi.get_service_by_uuid(uuid)
  83. service = Service._from_db_object(cls(context), db_service)
  84. return service
  85. @base.remotable_classmethod
  86. def get_by_name(cls, context, name):
  87. """Find a service based on name and return a Board object.
  88. :param name: the logical name of a service.
  89. :returns: a :class:`Board` object.
  90. """
  91. db_service = cls.dbapi.get_service_by_name(name)
  92. service = Service._from_db_object(cls(context), db_service)
  93. return service
  94. @base.remotable_classmethod
  95. def list(cls, context, limit=None, marker=None, sort_key=None,
  96. sort_dir=None, filters=None):
  97. """Return a list of Service objects.
  98. :param context: Security context.
  99. :param limit: maximum number of resources to return in a single result.
  100. :param marker: pagination marker for large data sets.
  101. :param sort_key: column to sort results by.
  102. :param sort_dir: direction to sort. "asc" or "desc".
  103. :param filters: Filters to apply.
  104. :returns: a list of :class:`Service` object.
  105. """
  106. db_services = cls.dbapi.get_service_list(filters=filters,
  107. limit=limit,
  108. marker=marker,
  109. sort_key=sort_key,
  110. sort_dir=sort_dir)
  111. return [Service._from_db_object(cls(context), obj)
  112. for obj in db_services]
  113. @base.remotable
  114. def create(self, context=None):
  115. """Create a Service record in the DB.
  116. Column-wise updates will be made based on the result of
  117. self.what_changed(). If target_power_state is provided,
  118. it will be checked against the in-database copy of the
  119. service before updates are made.
  120. :param context: Security context. NOTE: This should only
  121. be used internally by the indirection_api.
  122. Unfortunately, RPC requires context as the first
  123. argument, even though we don't use it.
  124. A context should be set when instantiating the
  125. object, e.g.: Service(context)
  126. """
  127. values = self.obj_get_changes()
  128. db_service = self.dbapi.create_service(values)
  129. self._from_db_object(self, db_service)
  130. @base.remotable
  131. def destroy(self, context=None):
  132. """Delete the Service from the DB.
  133. :param context: Security context. NOTE: This should only
  134. be used internally by the indirection_api.
  135. Unfortunately, RPC requires context as the first
  136. argument, even though we don't use it.
  137. A context should be set when instantiating the
  138. object, e.g.: Service(context)
  139. """
  140. self.dbapi.destroy_service(self.uuid)
  141. self.obj_reset_changes()
  142. @base.remotable
  143. def save(self, context=None):
  144. """Save updates to this Service.
  145. Column-wise updates will be made based on the result of
  146. self.what_changed(). If target_power_state is provided,
  147. it will be checked against the in-database copy of the
  148. service before updates are made.
  149. :param context: Security context. NOTE: This should only
  150. be used internally by the indirection_api.
  151. Unfortunately, RPC requires context as the first
  152. argument, even though we don't use it.
  153. A context should be set when instantiating the
  154. object, e.g.: Service(context)
  155. """
  156. updates = self.obj_get_changes()
  157. self.dbapi.update_service(self.uuid, updates)
  158. self.obj_reset_changes()
  159. @base.remotable
  160. def refresh(self, context=None):
  161. """Refresh the object by re-fetching from the DB.
  162. :param context: Security context. NOTE: This should only
  163. be used internally by the indirection_api.
  164. Unfortunately, RPC requires context as the first
  165. argument, even though we don't use it.
  166. A context should be set when instantiating the
  167. object, e.g.: Service(context)
  168. """
  169. current = self.__class__.get_by_uuid(self._context, self.uuid)
  170. for field in self.fields:
  171. if (hasattr(
  172. self, base.get_attrname(field))
  173. and self[field] != current[field]):
  174. self[field] = current[field]