def fill_slots(node_guid, osd_information, metadata=None): """ Creates 1 or more new OSDs :param node_guid: Guid of the node to which the disks belong :type node_guid: str :param osd_information: Information about the amount of OSDs to add to each Slot :type osd_information: list :param metadata: Metadata to add to the OSD (connection information for remote Backend, general Backend information) :type metadata: dict :return: None :rtype: NoneType """ metadata_type_validation = { 'integer': (int, None), 'osd_type': (str, AlbaOSD.OSD_TYPES.keys()), 'ip': (str, ExtensionsToolbox.regex_ip), 'port': (int, { 'min': 1, 'max': 65535 }) } node = AlbaNode(node_guid) required_params = {'slot_id': (str, None)} can_be_filled = False for flow in ['fill', 'fill_add']: if node.node_metadata[flow] is False: continue can_be_filled = True if flow == 'fill_add': required_params['alba_backend_guid'] = (str, None) for key, mtype in node.node_metadata['{0}_metadata'.format( flow)].iteritems(): if mtype in metadata_type_validation: required_params[key] = metadata_type_validation[mtype] if can_be_filled is False: raise ValueError('The given node does not support filling slots') validation_reasons = [] for osd_info in osd_information: # type: dict try: ExtensionsToolbox.verify_required_params( required_params=required_params, actual_params=osd_info) except RuntimeError as ex: validation_reasons.append(str(ex)) if len(validation_reasons) > 0: raise ValueError('Missing required parameter:\n *{0}'.format( '\n* '.join(validation_reasons))) for osd_info in osd_information: if node.node_metadata['fill'] is True: # Only filling is required AlbaNodeController._fill_slot( node, osd_info['slot_id'], dict((key, osd_info[key]) for key in node.node_metadata['fill_metadata'])) elif node.node_metadata['fill_add'] is True: # Fill the slot created_osds = AlbaNodeController._fill_slot( node, osd_info['slot_id'], dict((key, osd_info[key]) for key in node.node_metadata['fill_add_metadata'])) # And add/claim the OSD if node.type == AlbaNode.NODE_TYPES.S3: # The S3 manager returns the information about the osd when filling it for created_osd_info in created_osds: osd_info.update( created_osd_info ) # Add additional information about the osd AlbaController.add_osds( alba_backend_guid=osd_info['alba_backend_guid'], osds=[osd_info], alba_node_guid=node_guid, metadata=metadata) else: AlbaController.add_osds( alba_backend_guid=osd_info['alba_backend_guid'], osds=[osd_info], alba_node_guid=node_guid, metadata=metadata) node.invalidate_dynamics('stack')
def fill_slots(node_cluster_guid, node_guid, osd_information, metadata=None): # type: (str, str, List[Dict[str, Any]]) -> None """ Creates 1 or more new OSDs :param node_cluster_guid: Guid of the node cluster to which the disks belong :type node_cluster_guid: basestring :param node_guid: Guid of the AlbaNode to act as the 'active' side :type node_guid: basestring :param osd_information: Information about the amount of OSDs to add to each Slot :type osd_information: list :param metadata: Metadata to add to the OSD (connection information for remote Backend, general Backend information) :type metadata: dict :return: None :rtype: NoneType """ metadata_type_validation = { 'integer': (int, None), 'osd_type': (str, AlbaOSD.OSD_TYPES.keys()), 'ip': (str, ExtensionsToolbox.regex_ip), 'port': (int, { 'min': 1, 'max': 65535 }) } node_cluster = AlbaNodeCluster(node_cluster_guid) # Check for the active side if it's part of the cluster active_node = AlbaNode(node_guid) if active_node not in node_cluster.alba_nodes: raise ValueError( 'The requested active AlbaNode is not part of AlbaNodeCluster {0}' .format(node_cluster.guid)) required_params = {'slot_id': (str, None)} can_be_filled = False for flow in ['fill', 'fill_add']: if node_cluster.cluster_metadata[flow] is False: continue can_be_filled = True if flow == 'fill_add': required_params['alba_backend_guid'] = (str, None) for key, mtype in node_cluster.cluster_metadata[ '{0}_metadata'.format(flow)].iteritems(): if mtype in metadata_type_validation: required_params[key] = metadata_type_validation[mtype] if can_be_filled is False: raise ValueError( 'The given node cluster does not support filling slots') validation_reasons = [] for slot_info in osd_information: try: ExtensionsToolbox.verify_required_params( required_params=required_params, actual_params=slot_info) except RuntimeError as ex: validation_reasons.append(str(ex)) if len(validation_reasons) > 0: raise ValueError('Missing required parameter:\n *{0}'.format( '\n* '.join(validation_reasons))) for slot_info in osd_information: if node_cluster.cluster_metadata['fill'] is True: # Only filling is required active_node.client.fill_slot( slot_id=slot_info['slot_id'], extra=dict((key, slot_info[key]) for key in node_cluster.cluster_metadata['fill_metadata'])) elif node_cluster.cluster_metadata['fill_add'] is True: # Fill the slot active_node.client.fill_slot( slot_id=slot_info['slot_id'], extra=dict( (key, slot_info[key]) for key in node_cluster.cluster_metadata['fill_add_metadata'])) # And add/claim the OSD AlbaController.add_osds( alba_backend_guid=slot_info['alba_backend_guid'], osds=[slot_info], alba_node_guid=node_guid, metadata=metadata) # Invalidate the stack and sync towards all passive sides active_node.invalidate_dynamics('stack') for node in node_cluster.alba_nodes: if node != active_node: try: node.client.sync_stack(active_node.stack) except: AlbaNodeClusterController._logger.exception( 'Error while syncing stacks to the passive side') node_cluster.invalidate_dynamics('stack')