class Controller(rest.RestController): """Version 1 API controller root.""" isystems = system.SystemController() ihosts = host.HostController() helm_charts = helm_charts.HelmChartsController() inodes = node.NodeController() icpus = cpu.CPUController() imemorys = memory.MemoryController() iinterfaces = interface.InterfaceController() ports = port.PortController() ethernet_ports = ethernet_port.EthernetPortController() istors = storage.StorageController() ilvgs = lvg.LVGController() ipvs = pv.PVController() idisks = disk.DiskController() partitions = partition.PartitionController() iprofile = profile.ProfileController() itrapdest = trapdest.TrapDestController() icommunity = community.CommunityController() iuser = user.UserController() idns = dns.DNSController() intp = ntp.NTPController() ptp = ptp.PTPController() iextoam = network_oam.OAMNetworkController() controller_fs = controller_fs.ControllerFsController() storage_backend = storage_backend.StorageBackendController() storage_lvm = storage_lvm.StorageLVMController() storage_file = storage_file.StorageFileController() storage_external = storage_external.StorageExternalController() storage_ceph = storage_ceph.StorageCephController() storage_tiers = storage_tier.StorageTierController() storage_ceph_external = \ storage_ceph_external.StorageCephExternalController() ceph_mon = ceph_mon.CephMonController() drbdconfig = drbdconfig.drbdconfigsController() addresses = address.AddressController() addrpools = address_pool.AddressPoolController() routes = route.RouteController() certificate = certificate.CertificateController() isensors = sensor.SensorController() isensorgroups = sensorgroup.SensorGroupController() loads = load.LoadController() pci_devices = pci_device.PCIDeviceController() upgrade = upgrade.UpgradeController() networks = network.NetworkController() interface_networks = interface_network.InterfaceNetworkController() service_parameter = service_parameter.ServiceParameterController() clusters = cluster.ClusterController() lldp_agents = lldp_agent.LLDPAgentController() lldp_neighbours = lldp_neighbour.LLDPNeighbourController() services = service.SMServiceController() servicenodes = servicenode.SMServiceNodeController() servicegroup = servicegroup.SMServiceGroupController() health = health.HealthController() registry_image = registry_image.RegistryImageController() remotelogging = remotelogging.RemoteLoggingController() sdn_controller = sdn_controller.SDNControllerController() license = license.LicenseController() labels = label.LabelController() fernet_repo = fernet_repo.FernetKeyController() apps = kube_app.KubeAppController() datanetworks = datanetwork.DataNetworkController() interface_datanetworks = interface_datanetwork.InterfaceDataNetworkController() host_fs = host_fs.HostFsController() @wsme_pecan.wsexpose(V1) def get(self): # NOTE: The reason why convert() it's being called for every # request is because we need to get the host url from # the request object to make the links. return V1.convert()
class NodeController(rest.RestController): """REST controller for inodes.""" icpus = cpu.CPUController(from_inode=True) "Expose icpus as a sub-element of inodes" imemorys = memory.MemoryController(from_inode=True) "Expose imemorys as a sub-element of inodes" ports = port.PortController(from_inode=True) "Expose ports as a sub-element of inodes" _custom_actions = { 'detail': ['GET'], } def __init__(self, from_ihosts=False): self._from_ihosts = from_ihosts def _get_nodes_collection(self, ihost_uuid, marker, limit, sort_key, sort_dir, expand=False, resource_url=None): if self._from_ihosts and not ihost_uuid: raise exception.InvalidParameterValue(_("Host id not specified.")) limit = utils.validate_limit(limit) sort_dir = utils.validate_sort_dir(sort_dir) marker_obj = None if marker: marker_obj = objects.node.get_by_uuid(pecan.request.context, marker) if ihost_uuid: nodes = pecan.request.dbapi.inode_get_by_ihost(ihost_uuid, limit, marker_obj, sort_key=sort_key, sort_dir=sort_dir) else: nodes = pecan.request.dbapi.inode_get_list(limit, marker_obj, sort_key=sort_key, sort_dir=sort_dir) return NodeCollection.convert_with_links(nodes, limit, url=resource_url, expand=expand, sort_key=sort_key, sort_dir=sort_dir) @wsme_pecan.wsexpose(NodeCollection, types.uuid, types.uuid, int, wtypes.text, wtypes.text) def get_all(self, ihost_uuid=None, marker=None, limit=None, sort_key='id', sort_dir='asc'): """Retrieve a list of nodes.""" return self._get_nodes_collection(ihost_uuid, marker, limit, sort_key, sort_dir) @wsme_pecan.wsexpose(NodeCollection, types.uuid, types.uuid, int, wtypes.text, wtypes.text) def detail(self, ihost_uuid=None, marker=None, limit=None, sort_key='id', sort_dir='asc'): """Retrieve a list of nodes with detail.""" # NOTE(lucasagomes): /detail should only work agaist collections parent = pecan.request.path.split('/')[:-1][-1] if parent != "inodes": raise exception.HTTPNotFound expand = True resource_url = '/'.join(['nodes', 'detail']) return self._get_nodes_collection(ihost_uuid, marker, limit, sort_key, sort_dir, expand, resource_url) @wsme_pecan.wsexpose(Node, types.uuid) def get_one(self, node_uuid): """Retrieve information about the given node.""" if self._from_ihosts: raise exception.OperationNotPermitted rpc_node = objects.node.get_by_uuid(pecan.request.context, node_uuid) return Node.convert_with_links(rpc_node) @cutils.synchronized(LOCK_NAME) @wsme_pecan.wsexpose(Node, body=Node) def post(self, node): """Create a new node.""" if self._from_ihosts: raise exception.OperationNotPermitted try: node = node.as_dict() # Get host ihostId = node.get('forihostid') or node.get('ihost_uuid') if uuidutils.is_uuid_like(ihostId): ihost = pecan.request.dbapi.ihost_get(ihostId) forihostid = ihost['id'] node.update({'forihostid': forihostid}) else: forihostid = ihostId LOG.debug("inode post nodes ihostid: %s" % forihostid) new_node = pecan.request.dbapi.inode_create(forihostid, node) except exception.SysinvException as e: LOG.exception(e) raise wsme.exc.ClientSideError(_("Invalid data")) return Node.convert_with_links(new_node) @cutils.synchronized(LOCK_NAME) @wsme.validate(types.uuid, [NodePatchType]) @wsme_pecan.wsexpose(Node, types.uuid, body=[NodePatchType]) def patch(self, node_uuid, patch): """Update an existing node.""" if self._from_ihosts: raise exception.OperationNotPermitted rpc_node = objects.node.get_by_uuid(pecan.request.context, node_uuid) # replace ihost_uuid and inode_uuid with corresponding patch_obj = jsonpatch.JsonPatch(patch) for p in patch_obj: if p['path'] == '/ihost_uuid': p['path'] = '/forihostid' ihost = objects.host.get_by_uuid(pecan.request.context, p['value']) p['value'] = ihost.id try: node = Node(**jsonpatch.apply_patch(rpc_node.as_dict(), patch_obj)) except utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) # Update only the fields that have changed for field in objects.node.fields: if rpc_node[field] != getattr(node, field): rpc_node[field] = getattr(node, field) rpc_node.save() return Node.convert_with_links(rpc_node) @wsme_pecan.wsexpose(None, types.uuid, status_code=204) def delete(self, node_uuid): """Delete a node.""" if self._from_ihosts: raise exception.OperationNotPermitted pecan.request.dbapi.inode_destroy(node_uuid)