class ApiDictType(wtypes.UserType): name = 'apidict' __name__ = name basetype = { wtypes.text: apiutils.ValidTypes(wtypes.text, six.integer_types) }
class JsonPatchType(wtypes.Base): """A complex type that represents a single json-patch operation.""" path = wtypes.wsattr(StringType(pattern='^(/[\w-]+)+$'), mandatory=True) op = wtypes.wsattr(wtypes.Enum(str, 'add', 'replace', 'remove'), mandatory=True) # TODO(jgauld): Should get most recent ironic JsonType/value_types value = apiutils.ValidTypes(wtypes.text, six.integer_types, float) @staticmethod def internal_attrs(): """Returns a list of internal attributes. Internal attributes can't be added, replaced or removed. This method may be overwritten by derived class. """ return ['/created_at', '/id', '/links', '/updated_at', '/uuid'] @staticmethod def mandatory_attrs(): """Retruns a list of mandatory attributes. Mandatory attributes can't be removed from the document. This method should be overwritten by derived class. """ return [] @staticmethod def validate(patch): if patch.path in patch.internal_attrs(): msg = _("'%s' is an internal attribute and can not be updated") raise wsme.exc.ClientSideError(msg % patch.path) if patch.path in patch.mandatory_attrs() and patch.op == 'remove': msg = _("'%s' is a mandatory attribute and can not be removed") raise wsme.exc.ClientSideError(msg % patch.path) if patch.op == 'add': if patch.path.count('/') == 1: msg = _('Adding a new attribute (%s) to the root of ' ' the resource is not allowed') raise wsme.exc.ClientSideError(msg % patch.path) if patch.op != 'remove': if not patch.value: msg = _("Edit and Add operation of the field requires " "non-empty value.") raise wsme.exc.ClientSideError(msg) ret = {'path': patch.path, 'op': patch.op} if patch.value: ret['value'] = patch.value return ret
class KubeRootCAHostUpdate(base.APIBase): """API representation of a Kubernetes RootCA Host Update.""" id = int "Unique ID for this entry" uuid = types.uuid "Unique UUID for this entry" target_rootca_cert = wtypes.text "The target certificate for the kubernetes rootCA host update" effective_rootca_cert = wtypes.text "The current certificate of the kubernetes rootCA on this host" state = wtypes.text "Kubernetes rootCA host update state" capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types) } "Additional properties to be used in kube_rootca_host_update operations" links = [link.Link] "A list containing a self link and associated kubernetes rootca host " "update links" def __init__(self, **kwargs): self.fields = objects.kube_rootca_host_update.fields.keys() for k in self.fields: if not hasattr(self, k): continue setattr(self, k, kwargs.get(k, wtypes.Unset)) @classmethod def convert_with_links(cls, kube_rootca_host_update, expand=True): kube_rootca_host_update = KubeRootCAHostUpdate( **kube_rootca_host_update.as_dict()) if not expand: kube_rootca_host_update.unset_fields_except([ 'uuid', 'target_rootca_cert', 'effective_rootca_cert', 'state' ]) kube_rootca_host_update.links = [ link.Link.make_link('self', pecan.request.host_url, 'kube_rootca_host_update', kube_rootca_host_update.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'kube_rootca_host_update', kube_rootca_host_update.uuid, bookmark=True) ] return kube_rootca_host_update
class Service(base.APIBase): """API representation of service. This class enforces type checking and value constraints, and converts between the internal object model and the API representation of a service. """ enabled = bool "Is this service enabled" name = wtypes.text "Name of the service" region_name = wtypes.text "Name of region where the service resides" capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, bool, six.integer_types) } "Service capabilities" def __init__(self, **kwargs): self.fields = objects.service.fields.keys() for k in self.fields: setattr(self, k, kwargs.get(k)) @classmethod def convert_with_links(cls, rpc_service, expand=True): service = Service(**rpc_service.as_dict()) if not expand: service.unset_fields_except( ['name', 'enabled', 'region_name', 'capabilities']) service.links = [ link.Link.make_link('self', pecan.request.host_url, 'services', service.name), link.Link.make_link('bookmark', pecan.request.host_url, 'services', service.name, bookmark=True) ] return service
class StorageLVM(base.APIBase): """API representation of a LVM storage. This class enforces type checking and value constraints, and converts between the internal object model and the API representation of a lvm storage. """ uuid = types.uuid "Unique UUID for this lvm storage backend." links = [link.Link] "A list containing a self link and associated storage backend links." created_at = wtypes.datetime.datetime updated_at = wtypes.datetime.datetime # Inherited attributes from the base class backend = wtypes.text "Represents the storage backend (file, lvm, or ceph)." name = wtypes.text "The name of the backend (to differentiate between multiple common backends)." state = wtypes.text "The state of the backend. It can be configured or configuring." task = wtypes.text "Current task of the corresponding cinder backend." services = wtypes.text "The openstack services that are supported by this storage backend." capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types) } "Meta data for the storage backend" # Confirmation parameter [API-only field] confirmed = types.boolean "Represent confirmation that the backend operation should proceed" def __init__(self, **kwargs): defaults = { 'uuid': uuidutils.generate_uuid(), 'state': constants.SB_STATE_CONFIGURING, 'task': constants.SB_TASK_NONE, 'capabilities': {}, 'services': None, 'confirmed': False } self.fields = list(objects.storage_lvm.fields.keys()) # 'confirmed' is not part of objects.storage_backend.fields # (it's an API-only attribute) self.fields.append('confirmed') # Set the value for any of the field for k in self.fields: setattr(self, k, kwargs.get(k, defaults.get(k))) @classmethod def convert_with_links(cls, rpc_storage_lvm, expand=True): stor_lvm = StorageLVM(**rpc_storage_lvm.as_dict()) if not expand: stor_lvm.unset_fields_except([ 'uuid', 'created_at', 'updated_at', 'isystem_uuid', 'backend', 'name', 'state', 'task', 'services', 'capabilities' ]) stor_lvm.links =\ [link.Link.make_link('self', pecan.request.host_url, 'storage_lvm', stor_lvm.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'storage_lvm', stor_lvm.uuid, bookmark=True)] return stor_lvm
class CPU(base.APIBase): """API representation of a host CPU. This class enforces type checking and value constraints, and converts between the internal object model and the API representation of a cpu. """ uuid = types.uuid "Unique UUID for this cpu" cpu = int "Represent the cpu id icpu" core = int "Represent the core id icpu" thread = int "Represent the thread id icpu" # coprocessors = wtypes.text # "Represent the coprocessors of the icpu" cpu_family = wtypes.text "Represent the cpu family of the icpu" cpu_model = wtypes.text "Represent the cpu model of the icpu" allocated_function = wtypes.text "Represent the allocated function of the icpu" function = wtypes.text "Represent the function of the icpu" num_cores_on_processor0 = wtypes.text "The number of cores on processors 0" num_cores_on_processor1 = wtypes.text "The number of cores on processors 1" num_cores_on_processor2 = wtypes.text "The number of cores on processors 2" num_cores_on_processor3 = wtypes.text "The number of cores on processors 3" numa_node = int "The numa node or zone the icpu. API only attribute" capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types) } "This cpu's meta data" forihostid = int "The ihostid that this icpu belongs to" forinodeid = int "The inodeId that this icpu belongs to" ihost_uuid = types.uuid "The UUID of the ihost this cpu belongs to" inode_uuid = types.uuid "The UUID of the inode this cpu belongs to" links = [link.Link] "A list containing a self link and associated cpu links" def __init__(self, **kwargs): self.fields = list(objects.cpu.fields.keys()) for k in self.fields: setattr(self, k, kwargs.get(k)) # API only attributes self.fields.append('function') setattr(self, 'function', kwargs.get('function', None)) self.fields.append('num_cores_on_processor0') setattr(self, 'num_cores_on_processor0', kwargs.get('num_cores_on_processor0', None)) self.fields.append('num_cores_on_processor1') setattr(self, 'num_cores_on_processor1', kwargs.get('num_cores_on_processor1', None)) self.fields.append('num_cores_on_processor2') setattr(self, 'num_cores_on_processor2', kwargs.get('num_cores_on_processor2', None)) self.fields.append('num_cores_on_processor3') setattr(self, 'num_cores_on_processor3', kwargs.get('num_cores_on_processor3', None)) @classmethod def convert_with_links(cls, rpc_port, expand=True): # fields = ['uuid', 'address'] if not expand else None # cpu = icpu.from_rpc_object(rpc_port, fields) cpu = CPU(**rpc_port.as_dict()) if not expand: cpu.unset_fields_except([ 'uuid', 'cpu', 'core', 'thread', 'cpu_family', 'cpu_model', 'allocated_function', 'numa_node', 'ihost_uuid', 'inode_uuid', 'forihostid', 'forinodeid', 'capabilities', 'created_at', 'updated_at' ]) # never expose the id attribute cpu.forihostid = wtypes.Unset cpu.forinodeid = wtypes.Unset cpu.links = [ link.Link.make_link('self', pecan.request.host_url, 'icpus', cpu.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'icpus', cpu.uuid, bookmark=True) ] return cpu
class Sensor(base.APIBase): """API representation of an Sensor This class enforces type checking and value constraints, and converts between the internal object model and the API representation of an isensor. """ uuid = types.uuid "Unique UUID for this isensor" sensorname = wtypes.text "Represent the name of the isensor. Unique with path per host" path = wtypes.text "Represent the path of the isensor. Unique with isensorname per host" sensortype = wtypes.text "Represent the type of isensor. e.g. Temperature, WatchDog" datatype = wtypes.text "Represent the entity monitored. e.g. discrete, analog" status = wtypes.text "Represent current sensor status: ok, minor, major, critical, disabled" state = wtypes.text "Represent the current state of the isensor" state_requested = wtypes.text "Represent the requested state of the isensor" audit_interval = int "Represent the audit_interval of the isensor." algorithm = wtypes.text "Represent the algorithm of the isensor." actions_minor = wtypes.text "Represent the minor configured actions of the isensor. CSV." actions_major = wtypes.text "Represent the major configured actions of the isensor. CSV." actions_critical = wtypes.text "Represent the critical configured actions of the isensor. CSV." suppress = wtypes.text "Represent supress isensor if True, otherwise not suppress isensor" value = wtypes.text "Represent current value of the discrete isensor" unit_base = wtypes.text "Represent the unit base of the analog isensor e.g. revolutions" unit_modifier = wtypes.text "Represent the unit modifier of the analog isensor e.g. 10**2" unit_rate = wtypes.text "Represent the unit rate of the isensor e.g. /minute" t_minor_lower = wtypes.text "Represent the minor lower threshold of the analog isensor" t_minor_upper = wtypes.text "Represent the minor upper threshold of the analog isensor" t_major_lower = wtypes.text "Represent the major lower threshold of the analog isensor" t_major_upper = wtypes.text "Represent the major upper threshold of the analog isensor" t_critical_lower = wtypes.text "Represent the critical lower threshold of the analog isensor" t_critical_upper = wtypes.text "Represent the critical upper threshold of the analog isensor" capabilities = {wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types)} "Represent meta data of the isensor" host_id = int "Represent the host_id the isensor belongs to" sensorgroup_id = int "Represent the isensorgroup_id the isensor belongs to" host_uuid = types.uuid "Represent the UUID of the host the isensor belongs to" sensorgroup_uuid = types.uuid "Represent the UUID of the sensorgroup the isensor belongs to" links = [link.Link] "Represent a list containing a self link and associated isensor links" def __init__(self, **kwargs): self.fields = objects.sensor.fields.keys() for k in self.fields: setattr(self, k, kwargs.get(k)) @classmethod def convert_with_links(cls, rpc_sensor, expand=True): sensor = Sensor(**rpc_sensor.as_dict()) sensor_fields_common = ['uuid', 'host_id', 'sensorgroup_id', 'sensortype', 'datatype', 'sensorname', 'path', 'status', 'state', 'state_requested', 'sensor_action_requested', 'actions_minor', 'actions_major', 'actions_critical', 'suppress', 'audit_interval', 'algorithm', 'capabilities', 'host_uuid', 'sensorgroup_uuid', 'created_at', 'updated_at', ] sensor_fields_analog = ['unit_base', 'unit_modifier', 'unit_rate', 't_minor_lower', 't_minor_upper', 't_major_lower', 't_major_upper', 't_critical_lower', 't_critical_upper', ] if rpc_sensor.datatype == 'discrete': sensor_fields = sensor_fields_common elif rpc_sensor.datatype == 'analog': sensor_fields = sensor_fields_common + sensor_fields_analog else: LOG.error(_("Invalid datatype=%s" % rpc_sensor.datatype)) if not expand: sensor.unset_fields_except(sensor_fields) # never expose the id attribute sensor.host_id = wtypes.Unset sensor.sensorgroup_id = wtypes.Unset sensor.links = [link.Link.make_link('self', pecan.request.host_url, 'isensors', sensor.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'isensors', sensor.uuid, bookmark=True) ] return sensor
class Memory(base.APIBase): """API representation of host memory. This class enforces type checking and value constraints, and converts between the internal object model and the API representation of a memory. """ _minimum_platform_reserved_mib = None def _get_minimum_platform_reserved_mib(self): return self._minimum_platform_reserved_mib def _set_minimum_platform_reserved_mib(self, value): if self._minimum_platform_reserved_mib is None: try: ihost = objects.host.get_by_uuid(pecan.request.context, value) self._minimum_platform_reserved_mib = \ cutils.get_minimum_platform_reserved_memory( pecan.request.dbapi, ihost, self.numa_node) except exception.NodeNotFound as e: # Change error code because 404 (NotFound) is inappropriate # response for a POST request to create a Port e.code = 400 # BadRequest raise e elif value == wtypes.Unset: self._minimum_platform_reserved_mib = wtypes.Unset uuid = types.uuid "Unique UUID for this memory" memtotal_mib = int "Represent the imemory total in MiB" memavail_mib = int "Represent the imemory available in MiB" platform_reserved_mib = int "Represent the imemory platform reserved in MiB" hugepages_configured = wtypes.text "Represent whether huge pages are configured" vswitch_hugepages_size_mib = int "Represent the imemory vswitch huge pages size in MiB" vswitch_hugepages_reqd = int "Represent the imemory vswitch required number of hugepages" vswitch_hugepages_nr = int "Represent the imemory vswitch number of hugepages" vswitch_hugepages_avail = int "Represent the imemory vswitch number of hugepages available" vm_pending_as_percentage = wtypes.text "Represents if the hugepages are represented by percentage (True) or by integer (False)." vm_hugepages_nr_2M_pending = int "Represent the imemory vm number of hugepages pending (2M pages)" vm_hugepages_2M_percentage = int "Represent the imemory vm percent of hugepages pending (2M pages)" vm_hugepages_nr_2M = int "Represent the imemory vm number of hugepages (2M pages)" vm_hugepages_avail_2M = int "Represent the imemory vm number of hugepages available (2M pages)" vm_hugepages_nr_1G_pending = int "Represent the imemory vm number of hugepages pending (1G pages)" vm_hugepages_1G_percentage = int "Represent the imemory vm percent of hugepages pending (1G pages)" vm_hugepages_nr_1G = int "Represent the imemory vm number of hugepages (1G pages)" vm_hugepages_nr_4K = int "Represent the imemory vm number of hugepages (4K pages)" vm_hugepages_use_1G = wtypes.text "1G hugepage is supported 'True' or not 'False' " vm_hugepages_avail_1G = int "Represent the imemory vm number of hugepages available (1G pages)" vm_hugepages_possible_2M = int "Represent the total possible number of vm hugepages available (2M pages)" vm_hugepages_possible_1G = int "Represent the total possible number of vm hugepages available (1G pages)" minimum_platform_reserved_mib = wsme.wsproperty( int, _get_minimum_platform_reserved_mib, _set_minimum_platform_reserved_mib, mandatory=True) "Represent the default platform reserved memory in MiB. API only attribute" numa_node = int "The numa node or zone the imemory. API only attribute" capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types) } "This memory's meta data" forihostid = int "The ihostid that this imemory belongs to" forinodeid = int "The inodeId that this imemory belongs to" ihost_uuid = types.uuid "The UUID of the ihost this memory belongs to" inode_uuid = types.uuid "The UUID of the inode this memory belongs to" links = [link.Link] "A list containing a self link and associated memory links" def __init__(self, **kwargs): self.fields = list(objects.memory.fields.keys()) for k in self.fields: setattr(self, k, kwargs.get(k)) # API only attributes self.fields.append('minimum_platform_reserved_mib') setattr(self, 'minimum_platform_reserved_mib', kwargs.get('forihostid', None)) @classmethod def convert_with_links(cls, rpc_port, expand=True): # fields = ['uuid', 'address'] if not expand else None # memory = imemory.from_rpc_object(rpc_port, fields) memory = Memory(**rpc_port.as_dict()) if not expand: memory.unset_fields_except([ 'uuid', 'memtotal_mib', 'memavail_mib', 'platform_reserved_mib', 'hugepages_configured', 'vswitch_hugepages_size_mib', 'vswitch_hugepages_nr', 'vswitch_hugepages_reqd', 'vswitch_hugepages_avail', 'vm_pending_as_percentage', 'vm_hugepages_nr_2M', 'vm_hugepages_nr_1G', 'vm_hugepages_use_1G', 'vm_hugepages_nr_2M_pending', 'vm_hugepages_avail_2M', 'vm_hugepages_2M_percentage', 'vm_hugepages_nr_1G_pending', 'vm_hugepages_avail_1G', 'vm_hugepages_1G_percentage', 'vm_hugepages_nr_4K', 'vm_hugepages_possible_2M', 'vm_hugepages_possible_1G', 'numa_node', 'ihost_uuid', 'inode_uuid', 'forihostid', 'forinodeid', 'capabilities', 'created_at', 'updated_at', 'minimum_platform_reserved_mib' ]) # never expose the id attribute memory.forihostid = wtypes.Unset memory.forinodeid = wtypes.Unset memory.links = [ link.Link.make_link('self', pecan.request.host_url, 'imemorys', memory.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'imemorys', memory.uuid, bookmark=True) ] return memory
class Partition(base.APIBase): uuid = types.uuid "Unique UUID for this partition" start_mib = int "Partition start" end_mib = int "Partition end" size_mib = int "The size of the partition" device_node = wtypes.text "The device node of the partition" device_path = wtypes.text "The device path of the partition" type_guid = types.uuid "Unique type UUID for this partition" type_name = wtypes.text "The type name for this partition" idisk_id = int "The disk's id on which the partition resides" idisk_uuid = types.uuid "The disk's id on which the partition resides" status = int "Shows the status of the partition" foripvid = int "The ipvid that this partition belongs to" forihostid = int "The ihostid that this partition belongs to" ihost_uuid = types.uuid "The UUID of the host this partition belongs to" ipv_uuid = types.uuid "The UUID of the physical volume this partition belongs to" links = [link.Link] "A list containing a self link and associated partition links" capabilities = {wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types)} "This partition's meta data" def __init__(self, **kwargs): self.fields = objects.partition.fields.keys() for k in self.fields: setattr(self, k, kwargs.get(k)) @classmethod def convert_with_links(cls, rpc_partition, expand=True): partition = Partition(**rpc_partition.as_dict()) if not expand: partition.unset_fields_except( ['uuid', 'start_mib', 'end_mib', 'size_mib', 'device_path', 'device_node', 'type_guid', 'type_name', 'idisk_id', 'foripvid', 'ihost_uuid', 'idisk_uuid', 'ipv_uuid', 'status', 'created_at', 'updated_at', 'capabilities']) # Never expose the id attribute. partition.forihostid = wtypes.Unset partition.idisk_id = wtypes.Unset partition.foripvid = wtypes.Unset partition.links = [link.Link.make_link('self', pecan.request.host_url, 'partitions', partition.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'partitions', partition.uuid, bookmark=True) ] return partition
class System(base.APIBase): """API representation of a system. This class enforces type checking and value constraints, and converts between the internal object model and the API representation of a isystem. """ uuid = types.uuid "The UUID of the isystem" name = wtypes.text "The name of the isystem" system_type = wtypes.text "The type of the isystem" system_mode = wtypes.text "The mode of the isystem" description = wtypes.text "The name of the isystem" contact = wtypes.text "The contact of the isystem" location = wtypes.text "The location of the isystem" services = int "The services of the isystem" software_version = wtypes.text "A textual description of the entity" timezone = wtypes.text "The timezone of the isystem" links = [link.Link] "A list containing a self link and associated isystem links" ihosts = [link.Link] "Links to the collection of ihosts contained in this isystem" capabilities = { wtypes.text: api_utils.ValidTypes(wtypes.text, bool, six.integer_types) } "System defined capabilities" region_name = wtypes.text "The region name of the isystem" distributed_cloud_role = wtypes.text "The distributed cloud role of the isystem" service_project_name = wtypes.text "The service project name of the isystem" security_feature = wtypes.text "Kernel arguments associated with exnabled spectre/meltdown fix features" def __init__(self, **kwargs): self.fields = objects.system.fields.keys() for k in self.fields: # Translate any special internal representation of data to its # customer facing form if k == 'security_feature': # look up which customer-facing-security-feature-string goes # with the kernel arguments tracked in sysinv kernel_args = kwargs.get(k) translated_string = kernel_args for user_string, args_string in \ constants.SYSTEM_SECURITY_FEATURE_SPECTRE_MELTDOWN_OPTS.items(): if args_string == kernel_args: translated_string = user_string break setattr(self, k, translated_string) else: # No translation required setattr(self, k, kwargs.get(k)) @classmethod def convert_with_links(cls, rpc_isystem, expand=True): # isystem = isystem(**rpc_isystem.as_dict()) minimum_fields = [ 'id', 'uuid', 'name', 'system_type', 'system_mode', 'description', 'capabilities', 'contact', 'location', 'software_version', 'created_at', 'updated_at', 'timezone', 'region_name', 'service_project_name', 'distributed_cloud_role', 'security_feature' ] fields = minimum_fields if not expand else None iSystem = System.from_rpc_object(rpc_isystem, fields) iSystem.links = [ link.Link.make_link('self', pecan.request.host_url, 'isystems', iSystem.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'isystems', iSystem.uuid, bookmark=True) ] if expand: iSystem.ihosts = [ link.Link.make_link('self', pecan.request.host_url, 'isystems', iSystem.uuid + "/ihosts"), link.Link.make_link('bookmark', pecan.request.host_url, 'isystems', iSystem.uuid + "/ihosts", bookmark=True) ] return iSystem
class PV(base.APIBase): """API representation of an LVM Physical Volume. This class enforces type checking and value constraints, and converts between the internal object model and the API representation of an pv. """ uuid = types.uuid "Unique UUID for this pv" pv_state = wtypes.text "Represent the transition state of the ipv" pv_type = wtypes.text "Represent the type of pv" disk_or_part_uuid = types.uuid "idisk or partition UUID for this pv" disk_or_part_device_node = wtypes.text "idisk or partition device node name for this pv on the ihost" disk_or_part_device_path = wtypes.text "idisk or partition device path for this pv on the ihost" lvm_pv_name = wtypes.text "LVM physical volume name" lvm_vg_name = wtypes.text "LVM physical volume's reported volume group name" lvm_pv_uuid = wtypes.text "LVM physical volume's reported uuid string" lvm_pv_size = int "LVM physical volume's size" lvm_pe_total = int "LVM physical volume's PE total" lvm_pe_alloced = int "LVM physical volume's allocated PEs" capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types) } "This pv's meta data" forihostid = int "The ihostid that this ipv belongs to" ihost_uuid = types.uuid "The UUID of the host this pv belongs to" forilvgid = int "The ilvgid that this ipv belongs to" ilvg_uuid = types.uuid "The UUID of the lvg this pv belongs to" links = [link.Link] "A list containing a self link and associated pv links" idisks = [link.Link] "Links to the collection of idisks on this pv" partitions = [link.Link] "Links to the collection of partitions on this pv" def __init__(self, **kwargs): self.fields = objects.pv.fields.keys() for k in self.fields: setattr(self, k, kwargs.get(k)) if not self.uuid: self.uuid = uuidutils.generate_uuid() @classmethod def convert_with_links(cls, rpc_pv, expand=True): pv = PV(**rpc_pv.as_dict()) if not expand: pv.unset_fields_except([ 'uuid', 'pv_state', 'pv_type', 'capabilities', 'disk_or_part_uuid', 'disk_or_part_device_node', 'disk_or_part_device_path', 'lvm_pv_name', 'lvm_vg_name', 'lvm_pv_uuid', 'lvm_pv_size', 'lvm_pe_alloced', 'lvm_pe_total', 'ilvg_uuid', 'forilvgid', 'ihost_uuid', 'forihostid', 'created_at', 'updated_at' ]) # never expose the ihost_id attribute, allow exposure for now pv.forihostid = wtypes.Unset pv.links = [ link.Link.make_link('self', pecan.request.host_url, 'ipvs', pv.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'ipvs', pv.uuid, bookmark=True) ] if expand: pv.idisks = [ link.Link.make_link('self', pecan.request.host_url, 'ipvs', pv.uuid + "/idisks"), link.Link.make_link('bookmark', pecan.request.host_url, 'ipvs', pv.uuid + "/idisks", bookmark=True) ] pv.partitions = [ link.Link.make_link('self', pecan.request.host_url, 'ipvs', pv.uuid + "/partitions"), link.Link.make_link('bookmark', pecan.request.host_url, 'ipvs', pv.uuid + "/partitions", bookmark=True) ] return pv
class Storage(base.APIBase): """API representation of host storage. This class enforces type checking and value constraints, and converts between the internal object model and the API representation of an stor. """ uuid = types.uuid "Unique UUID for this stor" osdid = int "The osdid assigned to this istor. osd function only." function = wtypes.text "Represent the function of the istor" state = wtypes.text "Represent the operational state of the istor" capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types) } "This stor's meta data" forihostid = int "The ihostid that this istor belongs to" ihost_uuid = types.uuid "The UUID of the host this stor belongs to" idisk_uuid = types.uuid "The UUID of the disk this stor belongs to. API-only attribute" links = [link.Link] "A list containing a self link and associated stor links" idisks = [link.Link] "Links to the collection of idisks on this stor" journal_location = wtypes.text "The stor UUID of the journal disk" journal_size_mib = int "The size in MiB of the journal for this stor" journal_path = wtypes.text "The partition's path on which the stor's journal is kept" journal_node = wtypes.text "The partition's name on which the stor's journal is kept" fortierid = int "The id of the tier that uses this stor." tier_uuid = types.uuid "The tier UUID of the tier that uses this stor." tier_name = wtypes.text "The name of the tier that uses this stor." def __init__(self, **kwargs): self.fields = list(objects.storage.fields.keys()) for k in self.fields: setattr(self, k, kwargs.get(k)) if not self.uuid: self.uuid = uuidutils.generate_uuid() self.fields.append('journal_node') setattr(self, 'journal_node', kwargs.get('journal_node', None)) @classmethod def convert_with_links(cls, rpc_stor, expand=True): stor = Storage(**rpc_stor.as_dict()) if not expand: stor.unset_fields_except([ 'uuid', 'osdid', 'function', 'state', 'capabilities', 'created_at', 'updated_at', 'ihost_uuid', 'idisk_uuid', 'forihostid', 'journal_location', 'journal_size_mib', 'journal_path', 'journal_node', 'tier_uuid', 'tier_name' ]) # never expose the ihost_id attribute # stor.ihost_id = wtypes.Unset # this should be forihostid if stor.function == constants.STOR_FUNCTION_OSD: disks = pecan.request.dbapi.idisk_get_by_ihost(stor.forihostid) if disks is not None: for d in disks: if (stor.journal_path is not None and d.device_path is not None and d.device_path in stor.journal_path): partition_number = (re.match( '.*?([0-9]+)$', stor.journal_path).group(1)) if (d.device_node is not None and constants.DEVICE_NAME_NVME in d.device_node): stor.journal_node = "{}p{}".format( d.device_node, partition_number) else: stor.journal_node = "{}{}".format( d.device_node, partition_number) break # never expose the ihost_id attribute, allow exposure for now stor.forihostid = wtypes.Unset stor.links = [ link.Link.make_link('self', pecan.request.host_url, 'istors', stor.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'istors', stor.uuid, bookmark=True) ] if expand: stor.idisks = [ link.Link.make_link('self', pecan.request.host_url, 'istors', stor.uuid + "/idisks"), link.Link.make_link('bookmark', pecan.request.host_url, 'istors', stor.uuid + "/idisks", bookmark=True) ] return stor
class LVG(base.APIBase): """API representation of a ilvg. This class enforces type checking and value constraints, and converts between the internal object model and the API representation of an lvg. """ uuid = types.uuid "Unique UUID for this lvg" vg_state = wtypes.text "Represent the transition state of the ilvg" lvm_vg_name = wtypes.text "LVM Volume Group's name" lvm_vg_uuid = wtypes.text "LVM Volume Group's UUID" lvm_vg_access = wtypes.text "LVM Volume Group access setting" lvm_max_lv = int "LVM Volume Group's max logical volumes" lvm_cur_lv = int "LVM Volume Group's current logical volumes" lvm_max_pv = int "LVM Volume Group's max physical volumes" lvm_cur_pv = int "LVM Volume Group's current physical volumes" lvm_vg_size = int "LVM Volume Group's total size" lvm_vg_avail_size = int "LVM Volume Group's available size. API only attribute" lvm_vg_total_pe = int "LVM Volume Group's total PEs" lvm_vg_free_pe = int "LVM Volume Group's free PEs" capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types) } "This lvg's meta data" forihostid = int "The ihostid that this ilvg belongs to" ihost_uuid = types.uuid "The UUID of the host this lvg belongs to" links = [link.Link] "A list containing a self link and associated lvg links" ipvs = [link.Link] "Links to the collection of ipvs on this lvg" def __init__(self, **kwargs): self.fields = list(objects.lvg.fields.keys()) for k in self.fields: setattr(self, k, kwargs.get(k)) if not self.uuid: self.uuid = uuidutils.generate_uuid() self.fields.append('lvm_vg_avail_size') setattr(self, 'lvm_vg_avail_size', kwargs.get('lvm_vg_avail_size', 0)) @classmethod def convert_with_links(cls, rpc_lvg, expand=True): lvg = LVG(**rpc_lvg.as_dict()) if not expand: lvg.unset_fields_except([ 'uuid', 'lvm_vg_name', 'vg_state', 'lvm_vg_uuid', 'lvm_vg_access', 'lvm_max_lv', 'lvm_cur_lv', 'lvm_max_pv', 'lvm_cur_pv', 'lvm_vg_size', 'lvm_vg_avail_size', 'lvm_vg_total_pe', 'lvm_vg_free_pe', 'capabilities', 'created_at', 'updated_at', 'ihost_uuid', 'forihostid' ]) # To calculate Volume Group's available size in byte: # lvm_vg_size is Volume Group's total size in byte # lvm_vg_free_pe is Volume Group's free Physical Extents # lvm_vg_total_pe is Volume Group's total Physical Extents if lvg.lvm_vg_total_pe and lvg.lvm_vg_total_pe > 0: lvg.lvm_vg_avail_size = \ lvg.lvm_vg_size * lvg.lvm_vg_free_pe // lvg.lvm_vg_total_pe else: lvg.lvm_vg_avail_size = 0 # never expose the ihost_id attribute, allow exposure for now lvg.forihostid = wtypes.Unset lvg.links = [ link.Link.make_link('self', pecan.request.host_url, 'ilvgs', lvg.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'ilvgs', lvg.uuid, bookmark=True) ] if expand: lvg.ipvs = [ link.Link.make_link('self', pecan.request.host_url, 'ilvgs', lvg.uuid + "/ipvs"), link.Link.make_link('bookmark', pecan.request.host_url, 'ilvgs', lvg.uuid + "/ipvs", bookmark=True) ] return lvg
class Node(base.APIBase): """API representation of a host node. This class enforces type checking and value constraints, and converts between the internal object model and the API representation of an node. """ uuid = types.uuid "Unique UUID for this node" numa_node = int "numa node zone for this inode" capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types) } "This node's meta data" forihostid = int "The ihostid that this inode belongs to" ihost_uuid = types.uuid "The UUID of the host this node belongs to" links = [link.Link] "A list containing a self link and associated node links" icpus = [link.Link] "Links to the collection of icpus on this node" imemorys = [link.Link] "Links to the collection of imemorys on this node" ports = [link.Link] "Links to the collection of ports on this node" def __init__(self, **kwargs): self.fields = objects.node.fields.keys() for k in self.fields: setattr(self, k, kwargs.get(k)) @classmethod def convert_with_links(cls, rpc_node, expand=True): minimum_fields = [ 'uuid', 'numa_node', 'capabilities', 'ihost_uuid', 'forihostid' ] if not expand else None fields = minimum_fields if not expand else None # node = inode.from_rpc_object(rpc_node, fields) # node = inode(**rpc_node.as_dict()) node = Node.from_rpc_object(rpc_node, fields) # if not expand: # node.unset_fields_except(['uuid', # 'numa_node', # 'capabilities', # 'ihost_uuid', 'forihostid']) # never expose the ihost_id attribute node.forihostid = wtypes.Unset node.links = [ link.Link.make_link('self', pecan.request.host_url, 'inodes', node.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'inodes', node.uuid, bookmark=True) ] if expand: node.icpus = [ link.Link.make_link('self', pecan.request.host_url, 'inodes', node.uuid + "/icpus"), link.Link.make_link('bookmark', pecan.request.host_url, 'inodes', node.uuid + "/icpus", bookmark=True) ] node.imemorys = [ link.Link.make_link('self', pecan.request.host_url, 'inodes', node.uuid + "/imemorys"), link.Link.make_link('bookmark', pecan.request.host_url, 'inodes', node.uuid + "/imemorys", bookmark=True) ] node.ports = [ link.Link.make_link('self', pecan.request.host_url, 'inodes', node.uuid + "/ports"), link.Link.make_link('bookmark', pecan.request.host_url, 'inodes', node.uuid + "/ports", bookmark=True) ] return node
class Disk(base.APIBase): """API representation of a host disk. This class enforces type checking and value constraints, and converts between the internal object model and the API representation of a disk. """ uuid = types.uuid "Unique UUID for this disk" device_node = wtypes.text "Represent the device node of the idisk. Unique per host" device_type = wtypes.text "Represent the device type of the idisk" device_num = int "The device number of the idisk" device_id = wtypes.text "The device ID of the idisk" device_path = wtypes.text "The device path of the idisk" device_wwn = wtypes.text "The device WWN of the idisk" size_mib = int "The numa node or zone sdevice of the idisk" available_mib = int "Unallocated space on the disk" serial_id = wtypes.text "link or duplex mode for this idisk" capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types) } "This disk's meta data" forihostid = int "The ihostid that this idisk belongs to" foristorid = int "The istorId that this idisk belongs to" foripvid = int "The ipvid that this idisk belongs to" ihost_uuid = types.uuid "The UUID of the host this disk belongs to" istor_uuid = types.uuid "The UUID of the interface this disk belongs to" ipv_uuid = types.uuid "The UUID of the physical volume this disk belongs to" partitions = [link.Link] "Links to the collection of partitions on this idisk" links = [link.Link] "A list containing a self link and associated disk links" rpm = wtypes.text "Revolutions per minute. 'Undetermined' if not specified. 'N/A', not " "applicable for SSDs." def __init__(self, **kwargs): self.fields = objects.disk.fields.keys() for k in self.fields: setattr(self, k, kwargs.get(k)) @classmethod def convert_with_links(cls, rpc_disk, expand=True): # fields = ['uuid', 'address'] if not expand else None # disk = idisk.from_rpc_object(rpc_disk, fields) disk = Disk(**rpc_disk.as_dict()) if not expand: disk.unset_fields_except([ 'uuid', 'device_node', 'device_num', 'device_type', 'device_id', 'device_path', 'device_wwn', 'size_mib', 'available_mib', 'rpm', 'serial_id', 'forihostid', 'foristorid', 'foripvid', 'ihost_uuid', 'istor_uuid', 'ipv_uuid', 'capabilities', 'created_at', 'updated_at' ]) # never expose the id attribute disk.forihostid = wtypes.Unset disk.foristorid = wtypes.Unset disk.foripvid = wtypes.Unset disk.links = [ link.Link.make_link('self', pecan.request.host_url, 'idisks', disk.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'idisks', disk.uuid, bookmark=True) ] if expand: disk.partitions = [ link.Link.make_link('self', pecan.request.host_url, 'idisks', disk.uuid + "/partitions"), link.Link.make_link('bookmark', pecan.request.host_url, 'idisks', disk.uuid + "/partitions", bookmark=True) ] return disk
class StorageTier(base.APIBase): """API representation of a Storage Tier. This class enforces type checking and value constraints, and converts between the internal object model and the API representation of a storage tier. """ uuid = types.uuid "Unique UUID for this storage tier" name = wtypes.text "Storage tier name" type = wtypes.text "Storage tier type" status = wtypes.text "Storage tier status" capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types) } "Storage tier meta data" forbackendid = int "The storage backend that is using this storage tier" backend_uuid = types.uuid "The UUID of the storage backend that is using this storage tier" forclusterid = int "The storage cluster that this storage tier belongs to" cluster_uuid = types.uuid "The UUID of the storage cluster this storage tier belongs to" stors = types.MultiType([list]) "List of OSD ids associated with this tier" links = [link.Link] "A list containing a self link and associated storage tier links" istors = [link.Link] "Links to the collection of OSDs on this storage tier" def __init__(self, **kwargs): self.fields = objects.storage_tier.fields.keys() for k in self.fields: setattr(self, k, kwargs.get(k)) if not self.uuid: self.uuid = uuidutils.generate_uuid() @classmethod def convert_with_links(cls, rpc_tier, expand=True): tier = StorageTier(**rpc_tier.as_dict()) if not expand: tier.unset_fields_except([ 'uuid', 'name', 'type', 'status', 'capabilities', 'backend_uuid', 'cluster_uuid', 'stors', 'created_at', 'updated_at' ]) # Don't expose ID attributes. tier.forbackendid = wtypes.Unset tier.forclusterid = wtypes.Unset tier.links = [ link.Link.make_link('self', pecan.request.host_url, 'storage_tiers', tier.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'storage_tiers', tier.uuid, bookmark=True) ] if expand: tier.istors = [ link.Link.make_link('self', pecan.request.host_url, 'storage_tiers', tier.uuid + "/istors"), link.Link.make_link('bookmark', pecan.request.host_url, 'storage_tiers', tier.uuid + "/istors", bookmark=True) ] return tier
class EthernetPort(base.APIBase): """API representation of an Ethernet port This class enforces type checking and value constraints, and converts between the internal object model and the API representation of an Ethernet port. """ uuid = types.uuid "Unique UUID for this port" type = wtypes.text "Represent the type of port" name = wtypes.text "Represent the name of the port. Unique per host" namedisplay = wtypes.text "Represent the display name of the port. Unique per host" pciaddr = wtypes.text "Represent the pci address of the port" dev_id = int "The unique identifier of PCI device" pclass = wtypes.text "Represent the pci class of the port" pvendor = wtypes.text "Represent the pci vendor of the port" pdevice = wtypes.text "Represent the pci device of the port" psvendor = wtypes.text "Represent the pci svendor of the port" psdevice = wtypes.text "Represent the pci sdevice of the port" numa_node = int "Represent the numa node or zone sdevice of the port" sriov_totalvfs = int "The total number of available SR-IOV VFs" sriov_numvfs = int "The number of configured SR-IOV VFs" sriov_vfs_pci_address = wtypes.text "The PCI Addresses of the VFs" driver = wtypes.text "The kernel driver for this device" mac = wsme.wsattr(types.macaddress, mandatory=False) "Represent the MAC Address of the port" mtu = int "Represent the MTU size (bytes) of the port" speed = int "Represent the speed (MBytes/sec) of the port" link_mode = int "Represent the link mode of the port" duplex = wtypes.text "Represent the duplex mode of the port" autoneg = wtypes.text "Represent the auto-negotiation mode of the port" bootp = wtypes.text "Represent the bootp port of the host" capabilities = {wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types)} "Represent meta data of the port" host_id = int "Represent the host_id the port belongs to" interface_id = int "Represent the interface_id the port belongs to" bootif = wtypes.text "Represent whether the port is a boot port" dpdksupport = bool "Represent whether or not the port supports DPDK acceleration" host_uuid = types.uuid "Represent the UUID of the host the port belongs to" interface_uuid = types.uuid "Represent the UUID of the interface the port belongs to" node_uuid = types.uuid "Represent the UUID of the node the port belongs to" links = [link.Link] "Represent a list containing a self link and associated port links" def __init__(self, **kwargs): self.fields = objects.ethernet_port.fields.keys() for k in self.fields: setattr(self, k, kwargs.get(k)) @classmethod def convert_with_links(cls, rpc_port, expand=True): port = EthernetPort(**rpc_port.as_dict()) if not expand: port.unset_fields_except(['uuid', 'host_id', 'node_id', 'interface_id', 'type', 'name', 'namedisplay', 'pciaddr', 'dev_id', 'pclass', 'pvendor', 'pdevice', 'psvendor', 'psdevice', 'numa_node', 'mac', 'sriov_totalvfs', 'sriov_numvfs', 'sriov_vfs_pci_address', 'driver', 'mtu', 'speed', 'link_mode', 'duplex', 'autoneg', 'bootp', 'capabilities', 'host_uuid', 'interface_uuid', 'node_uuid', 'dpdksupport', 'created_at', 'updated_at']) # never expose the id attribute port.host_id = wtypes.Unset port.interface_id = wtypes.Unset port.node_id = wtypes.Unset port.links = [link.Link.make_link('self', pecan.request.host_url, 'ethernet_ports', port.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'ethernet_ports', port.uuid, bookmark=True) ] return port
class Port(base.APIBase): """API representation of a host port This class enforces type checking and value constraints, and converts between the internal object model and the API representation of an port. """ uuid = types.uuid "Unique UUID for this port" type = wtypes.text "Represent the type of port" name = wtypes.text "Represent the name of the port. Unique per host" namedisplay = wtypes.text "Represent the display name of the port. Unique per host" pciaddr = wtypes.text "Represent the pci address of the port" dev_id = int "The unique identifier of PCI device" pclass = wtypes.text "Represent the pci class of the port" pvendor = wtypes.text "Represent the pci vendor of the port" pdevice = wtypes.text "Represent the pci device of the port" psvendor = wtypes.text "Represent the pci svendor of the port" psdevice = wtypes.text "Represent the pci sdevice of the port" numa_node = int "Represent the numa node or zone sdevice of the port" sriov_totalvfs = int "The total number of available SR-IOV VFs" sriov_numvfs = int "The number of configured SR-IOV VFs" sriov_vfs_pci_address = wtypes.text "The PCI Addresses of the VFs" driver = wtypes.text "The kernel driver for this device" capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types) } "Represent meta data of the port" host_id = int "Represent the host_id the port belongs to" interface_id = int "Represent the interface_id the port belongs to" dpdksupport = bool "Represent whether or not the port supports DPDK acceleration" host_uuid = types.uuid "Represent the UUID of the host the port belongs to" interface_uuid = types.uuid "Represent the UUID of the interface the port belongs to" node_uuid = types.uuid "Represent the UUID of the node the port belongs to" links = [link.Link] "Represent a list containing a self link and associated port links" lldp_agents = [link.Link] "Links to the collection of LldpAgents on this port" lldp_neighbours = [link.Link] "Links to the collection of LldpNeighbours on this port" def __init__(self, **kwargs): self.fields = objects.port.fields.keys() for k in self.fields: setattr(self, k, kwargs.get(k)) @classmethod def convert_with_links(cls, rpc_port, expand=True): port = Port(**rpc_port.as_dict()) if not expand: port.unset_fields_except([ 'uuid', 'host_id', 'node_id', 'interface_id', 'type', 'name', 'namedisplay', 'pciaddr', 'dev_id', 'pclass', 'pvendor', 'pdevice', 'psvendor', 'psdevice', 'numa_node', 'sriov_totalvfs', 'sriov_numvfs', 'sriov_vfs_pci_address', 'driver', 'capabilities', 'host_uuid', 'interface_uuid', 'node_uuid', 'dpdksupport', 'created_at', 'updated_at' ]) # never expose the id attribute port.host_id = wtypes.Unset port.interface_id = wtypes.Unset port.node_id = wtypes.Unset port.links = [ link.Link.make_link('self', pecan.request.host_url, 'ports', port.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'ports', port.uuid, bookmark=True) ] port.lldp_agents = [ link.Link.make_link('self', pecan.request.host_url, 'ports', port.uuid + "/lldp_agents"), link.Link.make_link('bookmark', pecan.request.host_url, 'ports', port.uuid + "/lldp_agents", bookmark=True) ] port.lldp_neighbours = [ link.Link.make_link('self', pecan.request.host_url, 'ports', port.uuid + "/lldp_neighbors"), link.Link.make_link('bookmark', pecan.request.host_url, 'ports', port.uuid + "/lldp_neighbors", bookmark=True) ] return port
class SensorGroup(base.APIBase): """API representation of an Sensor Group This class enforces type checking and value constraints, and converts between the internal object model and the API representation of an isensorgroup. """ uuid = types.uuid "Unique UUID for this isensorgroup" sensorgroupname = wtypes.text "Represent the name of the isensorgroup. Unique with path per host" path = wtypes.text "Represent the path of the isensor. Unique with isensorname per host" sensortype = wtypes.text "Represent the sensortype . e.g. Temperature, WatchDog" datatype = wtypes.text "Represent the datatype e.g. discrete or analog," state = wtypes.text "Represent the state of the isensorgroup" possible_states = wtypes.text "Represent the possible states of the isensorgroup" algorithm = wtypes.text "Represent the algorithm of the isensorgroup." audit_interval_group = int "Represent the audit interval of the isensorgroup." actions_critical_choices = wtypes.text "Represent the configurable critical severity actions of the isensorgroup. CSV." actions_major_choices = wtypes.text "Represent the configurable major severity actions of the isensorgroup. CSV." actions_minor_choices = wtypes.text "Represent the configurable minor severity actions of the isensorgroup. CSV." actions_minor_group = wtypes.text "Represent the minor configured actions of the isensorgroup. CSV." actions_major_group = wtypes.text "Represent the major configured actions of the isensorgroup. CSV." actions_critical_group = wtypes.text "Represent the critical configured actions of the isensorgroup. CSV." unit_base_group = wtypes.text "Represent the unit base of the analog isensorgroup e.g. revolutions" unit_modifier_group = wtypes.text "Represent the unit modifier of the analog isensorgroup e.g. 10**2" unit_rate_group = wtypes.text "Represent the unit rate of the isensorgroup e.g. /minute" t_minor_lower_group = wtypes.text "Represent the minor lower threshold of the analog isensorgroup" t_minor_upper_group = wtypes.text "Represent the minor upper threshold of the analog isensorgroup" t_major_lower_group = wtypes.text "Represent the major lower threshold of the analog isensorgroup" t_major_upper_group = wtypes.text "Represent the major upper threshold of the analog isensorgroup" t_critical_lower_group = wtypes.text "Represent the critical lower threshold of the analog isensorgroup" t_critical_upper_group = wtypes.text "Represent the critical upper threshold of the analog isensorgroup" capabilities = { wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types) } "Represent meta data of the isensorgroup" suppress = wtypes.text "Represent supress isensor if True, otherwise not suppress isensor" sensors = wtypes.text "Represent the sensors of the isensorgroup" host_id = int "Represent the host_id the isensorgroup belongs to" host_uuid = types.uuid "Represent the UUID of the host the isensorgroup belongs to" links = [link.Link] "Represent a list containing a self link and associated isensorgroup links" isensors = [link.Link] "Links to the collection of isensors on this isensorgroup" def __init__(self, **kwargs): self.fields = list(objects.sensorgroup.fields.keys()) for k in self.fields: setattr(self, k, kwargs.get(k)) # 'sensors' is not part of objects.SenorGroups.fields (it's an # API-only attribute) self.fields.append('sensors') setattr(self, 'sensors', kwargs.get('sensors', None)) @classmethod def convert_with_links(cls, rsensorgroup, expand=True): sensorgroup = SensorGroup(**rsensorgroup.as_dict()) sensorgroup_fields_common = [ 'uuid', 'host_id', 'host_uuid', 'sensortype', 'datatype', 'sensorgroupname', 'path', 'state', 'possible_states', 'audit_interval_group', 'algorithm', 'actions_critical_choices', 'actions_major_choices', 'actions_minor_choices', 'actions_minor_group', 'actions_major_group', 'actions_critical_group', 'sensors', 'suppress', 'capabilities', 'created_at', 'updated_at', ] sensorgroup_fields_analog = [ 'unit_base_group', 'unit_modifier_group', 'unit_rate_group', 't_minor_lower_group', 't_minor_upper_group', 't_major_lower_group', 't_major_upper_group', 't_critical_lower_group', 't_critical_upper_group', ] if rsensorgroup.datatype == 'discrete': sensorgroup_fields = sensorgroup_fields_common elif rsensorgroup.datatype == 'analog': sensorgroup_fields = sensorgroup_fields_common + sensorgroup_fields_analog else: LOG.error(_("Invalid datatype=%s" % rsensorgroup.datatype)) if not expand: sensorgroup.unset_fields_except(sensorgroup_fields) if sensorgroup.host_id and not sensorgroup.host_uuid: host = objects.host.get_by_uuid(pecan.request.context, sensorgroup.host_id) sensorgroup.host_uuid = host.uuid # never expose the id attribute sensorgroup.host_id = wtypes.Unset sensorgroup.id = wtypes.Unset sensorgroup.links = [ link.Link.make_link('self', pecan.request.host_url, 'isensorgroups', sensorgroup.uuid), link.Link.make_link('bookmark', pecan.request.host_url, 'isensorgroups', sensorgroup.uuid, bookmark=True) ] sensorgroup.isensors = [ link.Link.make_link('self', pecan.request.host_url, 'isensorgroups', sensorgroup.uuid + "/isensors"), link.Link.make_link('bookmark', pecan.request.host_url, 'isensorgroups', sensorgroup.uuid + "/isensors", bookmark=True) ] return sensorgroup