def delete_preset(alba_backend_guid, name): """ Deletes a preset from the Alba backend :param alba_backend_guid: Guid of the ALBA backend :type alba_backend_guid: str :param name: Name of the preset :type name: str :return: None """ # VALIDATIONS alba_backend = AlbaBackend(alba_backend_guid) preset_default_map = dict((preset['name'], preset['is_default']) for preset in alba_backend.presets) if name not in preset_default_map: AlbaPresetController._logger.warning( 'Preset with name {0} for ALBA Backend {1} could not be found, so not deleting' .format(name, alba_backend.name)) return if preset_default_map[name] is True: raise RuntimeError('Cannot delete the default preset') # DELETE PRESET AlbaPresetController._logger.debug('Deleting preset {0}'.format(name)) config = Configuration.get_configuration_path( alba_backend.abm_cluster.config_location) AlbaCLI.run(command='delete-preset', config=config, extra_params=[name]) alba_backend.invalidate_dynamics()
def create(self, request, version, abm_cluster=None, nsm_clusters=None): """ Creates an AlbaBackend :param request: Data regarding ALBA backend to create :type request: request :param version: version requested by the client :type version: int :param abm_cluster: ABM cluster to claim for this new ALBA Backend :type abm_cluster: str :param nsm_clusters: NSM clusters to claim for this new ALBA Backend :type nsm_clusters: list :return: The newly created ALBA Backend object :rtype: ovs.dal.hybrids.albabackend.AlbaBackend """ if version < 3: request.DATA['scaling'] = 'LOCAL' if nsm_clusters is None: nsm_clusters = [] serializer = FullSerializer(AlbaBackend, instance=AlbaBackend(), data=request.DATA, allow_passwords=True) alba_backend = serializer.deserialize() alba_backend.save() alba_backend.backend.status = 'INSTALLING' alba_backend.backend.save() AlbaController.add_cluster.delay(alba_backend.guid, abm_cluster, nsm_clusters) return alba_backend
def update_preset(alba_backend_guid, name, policies): """ Updates policies for an existing preset to Alba :param alba_backend_guid: Guid of the ALBA backend :type alba_backend_guid: str :param name: Name of preset :type name: str :param policies: New policy list to be sent to alba :type policies: list :return: None """ # VALIDATIONS AlbaPresetController._validate_policies_param(policies=policies) alba_backend = AlbaBackend(alba_backend_guid) if name not in [preset['name'] for preset in alba_backend.presets]: raise RuntimeError( 'Could not find a preset with name {0} for ALBA Backend {1}'. format(name, alba_backend.name)) # UPDATE PRESET AlbaPresetController._logger.debug( 'Updating preset {0} with policies {1}'.format(name, policies)) config = Configuration.get_configuration_path( alba_backend.abm_cluster.config_location) temp_config_file = tempfile.mktemp() with open(temp_config_file, 'wb') as data_file: data_file.write(json.dumps({'policies': policies})) data_file.flush() AlbaCLI.run(command='update-preset', config=config, named_params={'input-url': temp_config_file}, extra_params=[name]) alba_backend.invalidate_dynamics() os.remove(temp_config_file)
def remove_alba_arakoon_clusters(cls, alba_backend_guid, validate_clusters_reachable=True): # type: (basestring, bool) -> None """ Removes all backend related Arakoon clusters :param alba_backend_guid: Guid of the ALBA Backend :type alba_backend_guid: str :param validate_clusters_reachable: Validate if all clusters are reachable :type validate_clusters_reachable: bool :return: None :rtype: NoneType """ alba_backend = AlbaBackend(alba_backend_guid) if validate_clusters_reachable: AlbaArakoonController.abms_reachable(alba_backend) AlbaArakoonController.nsms_reachable(alba_backend) if alba_backend.abm_cluster is not None: AlbaArakoonController._logger.debug( 'Removing clusters for ALBA Backend {0}'.format( alba_backend.name)) arakoon_clusters = list(Configuration.list('/ovs/arakoon')) # Remove the ABM cluster ABMInstaller.remove_abm_cluster(alba_backend.abm_cluster, arakoon_clusters) # Remove NSM Arakoon clusters and services for nsm_cluster in alba_backend.nsm_clusters: NSMInstaller.remove_nsm_cluster(nsm_cluster, arakoon_clusters)
def get_albabackend_by_guid(albabackend_guid): """ Get a albabackend by albabackend guid :param albabackend_guid: albabackend guid :type albabackend_guid: str :return: alba backend object :rtype: ovs.dal.hybrids.albabackend """ return AlbaBackend(albabackend_guid)
def _stack(self): """ Returns an overview of this node's storage stack """ from ovs.dal.hybrids.albabackend import AlbaBackend from ovs.dal.lists.albabackendlist import AlbaBackendList def _move(info): for move in [('state', 'status'), ('state_detail', 'status_detail')]: if move[0] in info: info[move[1]] = info[move[0]] del info[move[0]] stack = {} node_down = False # Fetch stack from asd-manager try: remote_stack = self.client.get_stack() for slot_id, slot_data in remote_stack.iteritems(): stack[slot_id] = {'status': 'ok'} stack[slot_id].update(slot_data) # Migrate state > status _move(stack[slot_id]) for osd_data in slot_data.get('osds', {}).itervalues(): _move(osd_data) except (requests.ConnectionError, requests.Timeout, InvalidCredentialsError): self._logger.warning( 'Error during stack retrieval. Assuming that the node is down') node_down = True model_osds = {} found_osds = {} # Apply own model to fetched stack for osd in self.osds: model_osds[osd.osd_id] = osd # Initially set the info if osd.slot_id not in stack: stack[osd.slot_id] = { 'status': self.OSD_STATUSES.UNKNOWN if node_down is True else self.OSD_STATUSES.MISSING, 'status_detail': self.OSD_STATUS_DETAILS.NODEDOWN if node_down is True else '', 'osds': {} } osd_data = stack[osd.slot_id]['osds'].get(osd.osd_id, {}) stack[osd.slot_id]['osds'][ osd.osd_id] = osd_data # Initially set the info in the stack osd_data.update(osd.stack_info) if node_down is True: osd_data['status'] = self.OSD_STATUSES.UNKNOWN osd_data['status_detail'] = self.OSD_STATUS_DETAILS.NODEDOWN elif osd.alba_backend_guid is not None: # Osds has been claimed # Load information from alba if osd.alba_backend_guid not in found_osds: found_osds[osd.alba_backend_guid] = {} if osd.alba_backend.abm_cluster is not None: config = Configuration.get_configuration_path( osd.alba_backend.abm_cluster.config_location) try: for found_osd in AlbaCLI.run( command='list-all-osds', config=config): found_osds[osd.alba_backend_guid][ found_osd['long_id']] = found_osd except (AlbaError, RuntimeError): self._logger.exception( 'Listing all osds has failed') osd_data['status'] = self.OSD_STATUSES.UNKNOWN osd_data[ 'status_detail'] = self.OSD_STATUS_DETAILS.ALBAERROR continue if osd.osd_id not in found_osds[osd.alba_backend_guid]: # Not claimed by any backend thus not in use continue found_osd = found_osds[osd.alba_backend_guid][osd.osd_id] if found_osd['decommissioned'] is True: osd_data['status'] = self.OSD_STATUSES.UNAVAILABLE osd_data[ 'status_detail'] = self.OSD_STATUS_DETAILS.DECOMMISSIONED continue backend_interval_key = '/ovs/alba/backends/{0}/gui_error_interval'.format( osd.alba_backend_guid) if Configuration.exists(backend_interval_key): interval = Configuration.get(backend_interval_key) else: interval = Configuration.get( '/ovs/alba/backends/global_gui_error_interval') read = found_osd['read'] or [0] write = found_osd['write'] or [0] errors = found_osd['errors'] osd_data['status'] = self.OSD_STATUSES.WARNING osd_data['status_detail'] = self.OSD_STATUS_DETAILS.ERROR if len(errors) == 0 or (len(read + write) > 0 and max(min(read), min(write)) > max(error[0] for error in errors) + interval): osd_data['status'] = self.OSD_STATUSES.OK osd_data['status_detail'] = '' statistics = {} for slot_info in stack.itervalues(): for osd_id, osd in slot_info['osds'].iteritems(): if osd.get( 'status_detail') == self.OSD_STATUS_DETAILS.ACTIVATING: osd['claimed_by'] = 'unknown' # We won't be able to connect to it just yet continue if osd_id not in model_osds: # The osd is known by the remote node but not in the model # In that case, let's connect to the OSD to see whether we get some info from it try: ips = osd['hosts'] if 'hosts' in osd and len( osd['hosts']) > 0 else osd.get('ips', []) port = osd['port'] claimed_by = 'unknown' for ip in ips: try: # Output will be None if it is not claimed claimed_by = AlbaCLI.run('get-osd-claimed-by', named_params={ 'host': ip, 'port': port }) break except (AlbaError, RuntimeError): self._logger.warning( 'get-osd-claimed-by failed for IP:port {0}:{1}' .format(ip, port)) alba_backend = AlbaBackendList.get_by_alba_id( claimed_by) osd['claimed_by'] = alba_backend.guid if alba_backend is not None else claimed_by except KeyError: osd['claimed_by'] = 'unknown' except: self._logger.exception( 'Could not load OSD info: {0}'.format(osd_id)) osd['claimed_by'] = 'unknown' if osd.get('status') not in ['error', 'warning']: osd['status'] = self.OSD_STATUSES.ERROR osd['status_detail'] = self.OSD_STATUS_DETAILS.UNREACHABLE claimed_by = osd.get('claimed_by', 'unknown') if claimed_by == 'unknown': continue try: alba_backend = AlbaBackend(claimed_by) except ObjectNotFoundException: continue # Add usage information if alba_backend not in statistics: statistics[alba_backend] = alba_backend.osd_statistics osd_statistics = statistics[alba_backend] if osd_id not in osd_statistics: continue stats = osd_statistics[osd_id] osd['usage'] = { 'size': int(stats['capacity']), 'used': int(stats['disk_usage']), 'available': int(stats['capacity'] - stats['disk_usage']) } return stack
def add_preset(alba_backend_guid, name, compression, policies, encryption, fragment_size=None): """ Adds a preset to Alba :param alba_backend_guid: Guid of the ALBA backend :type alba_backend_guid: str :param name: Name of the preset :type name: str :param compression: Compression type for the preset (none | snappy | bz2) :type compression: str :param policies: Policies for the preset :type policies: list :param encryption: Encryption for the preset (none | aes-cbc-256 | aes-ctr-256) :type encryption: str :param fragment_size: Size of a fragment in bytes (e.g. 1048576) :type fragment_size: int :return: None """ # VALIDATIONS if not re.match(Toolbox.regex_preset, name): raise ValueError('Invalid preset name specified') compression_options = ['snappy', 'bz2', 'none'] if compression not in compression_options: raise ValueError( 'Invalid compression format specified, please choose from: "{0}"' .format('", "'.join(compression_options))) encryption_options = ['aes-cbc-256', 'aes-ctr-256', 'none'] if encryption not in encryption_options: raise ValueError( 'Invalid encryption format specified, please choose from: "{0}"' .format('", "'.join(encryption_options))) if fragment_size is not None and (not isinstance(fragment_size, int) or not 16 <= fragment_size <= 1024**3): raise ValueError( 'Fragment size should be a positive integer smaller than 1 GiB' ) AlbaPresetController._validate_policies_param(policies=policies) alba_backend = AlbaBackend(alba_backend_guid) if name in [preset['name'] for preset in alba_backend.presets]: raise RuntimeError( 'Preset with name {0} already exists'.format(name)) # ADD PRESET preset = { 'compression': compression, 'object_checksum': { 'default': ['crc-32c'], 'verify_upload': True, 'allowed': [['none'], ['sha-1'], ['crc-32c']] }, 'osds': ['all'], 'fragment_size': 16 * 1024**2 if fragment_size is None else int(fragment_size), 'policies': policies, 'fragment_checksum': ['crc-32c'], 'fragment_encryption': ['none'], 'in_use': False, 'name': name } # Generate encryption key temp_key_file = None if encryption != 'none': encryption_key = ''.join( random.choice(chr(random.randint(32, 126))) for _ in range(32)) temp_key_file = tempfile.mktemp() with open(temp_key_file, 'wb') as temp_file: temp_file.write(encryption_key) temp_file.flush() preset['fragment_encryption'] = [ '{0}'.format(encryption), '{0}'.format(temp_key_file) ] # Dump preset content on filesystem config = Configuration.get_configuration_path( alba_backend.abm_cluster.config_location) temp_config_file = tempfile.mktemp() with open(temp_config_file, 'wb') as data_file: data_file.write(json.dumps(preset)) data_file.flush() # Create preset AlbaPresetController._logger.debug( 'Adding preset {0} with compression {1} and policies {2}'.format( name, compression, policies)) AlbaCLI.run(command='create-preset', config=config, named_params={'input-url': temp_config_file}, extra_params=[name]) # Cleanup alba_backend.invalidate_dynamics() for filename in [temp_key_file, temp_config_file]: if filename and os.path.exists(filename) and os.path.isfile( filename): os.remove(filename)
def nsm_checkup(alba_backend_guid=None, min_internal_nsms=1, external_nsm_cluster_names=None): # type: (Optional[str], Optional[int], Optional[List[str]]) -> None """ Validates the current NSM setup/configuration and takes actions where required. Assumptions: * A 2 node NSM is considered safer than a 1 node NSM. * When adding an NSM, the nodes with the least amount of NSM participation are preferred :param alba_backend_guid: Run for a specific ALBA Backend :type alba_backend_guid: str :param min_internal_nsms: Minimum amount of NSM hosts that need to be provided :type min_internal_nsms: int :param external_nsm_cluster_names: Information about the additional clusters to claim (only for externally managed Arakoon clusters) :type external_nsm_cluster_names: list :return: None :rtype: NoneType """ ############### # Validations # ############### if external_nsm_cluster_names is None: external_nsm_cluster_names = [] AlbaArakoonController._logger.info('NSM checkup started') if min_internal_nsms < 1: raise ValueError( 'Minimum amount of NSM clusters must be 1 or more') if not isinstance(external_nsm_cluster_names, list): raise ValueError( "'external_nsm_cluster_names' must be of type 'list'") if len(external_nsm_cluster_names) > 0: if alba_backend_guid is None: raise ValueError( 'Additional NSMs can only be configured for a specific ALBA Backend' ) if min_internal_nsms > 1: raise ValueError( "'min_internal_nsms' and 'external_nsm_cluster_names' are mutually exclusive" ) external_nsm_cluster_names = list(set( external_nsm_cluster_names)) # Remove duplicate cluster names for cluster_name in external_nsm_cluster_names: try: ArakoonInstaller.get_arakoon_metadata_by_cluster_name( cluster_name=cluster_name) except NotFoundException: raise ValueError( 'Arakoon cluster with name {0} does not exist'.format( cluster_name)) if alba_backend_guid is None: alba_backends = [ alba_backend for alba_backend in AlbaBackendList.get_albabackends() if alba_backend.backend.status == 'RUNNING' ] else: alba_backends = [AlbaBackend(alba_backend_guid)] masters = StorageRouterList.get_masters() storagerouters = set() for alba_backend in alba_backends: if alba_backend.abm_cluster is None: raise ValueError( 'No ABM cluster found for ALBA Backend {0}'.format( alba_backend.name)) if len(alba_backend.abm_cluster.abm_services) == 0: raise ValueError( 'ALBA Backend {0} does not have any registered ABM services' .format(alba_backend.name)) if len(alba_backend.nsm_clusters) + len( external_nsm_cluster_names) > MAX_NSM_AMOUNT: raise ValueError( 'The maximum of {0} NSM Arakoon clusters will be exceeded. Amount of clusters that can be deployed for this ALBA Backend: {1}' .format(MAX_NSM_AMOUNT, MAX_NSM_AMOUNT - len(alba_backend.nsm_clusters))) # Validate enough externally managed Arakoon clusters are available if alba_backend.abm_cluster.abm_services[ 0].service.is_internal is False: unused_cluster_names = set([ cluster_info['cluster_name'] for cluster_info in ArakoonInstaller.get_unused_arakoon_clusters( cluster_type=ServiceType.ARAKOON_CLUSTER_TYPES.NSM) ]) if set(external_nsm_cluster_names).difference( unused_cluster_names): raise ValueError( 'Some of the provided cluster_names have already been claimed before' ) storagerouters.update( set(masters) ) # For externally managed we need an available master node else: for abm_service in alba_backend.abm_cluster.abm_services: # For internally managed we need all StorageRouters online storagerouters.add(abm_service.service.storagerouter) for nsm_cluster in alba_backend.nsm_clusters: # For internally managed we need all StorageRouters online for nsm_service in nsm_cluster.nsm_services: storagerouters.add(nsm_service.service.storagerouter) ssh_clients = {} for storagerouter in storagerouters: try: ssh_clients[storagerouter] = SSHClient(endpoint=storagerouter) except UnableToConnectException: raise RuntimeError( 'StorageRouter {0} with IP {1} is not reachable'.format( storagerouter.name, storagerouter.ip)) version_str = AlbaArakoonInstaller.get_alba_version_string() nsm_installer = NSMInstaller(version_str=version_str, ssh_clients=ssh_clients) ################## # Check Clusters # ################## safety = Configuration.get( '/ovs/framework/plugins/alba/config|nsm.safety') maxload = Configuration.get( '/ovs/framework/plugins/alba/config|nsm.maxload') AlbaArakoonController._logger.debug( 'NSM safety is configured at: {0}'.format(safety)) AlbaArakoonController._logger.debug( 'NSM max load is configured at: {0}'.format(maxload)) master_client = None failed_backends = [] for alba_backend in alba_backends: try: # Gather information AlbaArakoonController._logger.info( 'ALBA Backend {0} - Ensuring NSM safety'.format( alba_backend.name)) internal = AlbaArakoonInstaller.is_internally_managed( alba_backend) nsm_loads = AlbaArakoonController.get_nsm_loads(alba_backend) nsm_storagerouters = AlbaArakoonController.get_nsms_per_storagerouter( alba_backend) sorted_nsm_clusters = sorted(alba_backend.nsm_clusters, key=lambda k: k.number) if not internal and len(external_nsm_cluster_names) > 0: for sr, cl in ssh_clients.iteritems(): if sr.node_type == 'MASTER': master_client = cl break if master_client is None: # Internal is False and we specified the NSM clusters to claim, but no MASTER nodes online raise ValueError( 'Could not find an online master node') AlbaArakoonController._logger.debug( 'ALBA Backend {0} - Arakoon clusters are {1} managed'. format(alba_backend.name, 'internally' if internal is True else 'externally')) for nsm_number, nsm_load in nsm_loads.iteritems(): AlbaArakoonController._logger.debug( 'ALBA Backend {0} - NSM Cluster {1} - Load {2}'.format( alba_backend.name, nsm_number, nsm_load)) for sr, count in nsm_storagerouters.iteritems(): AlbaArakoonController._logger.debug( 'ALBA Backend {0} - StorageRouter {1} - NSM Services {2}' .format(alba_backend.name, sr.name, count)) if internal: # Extend existing NSM clusters if safety not met for nsm_cluster in sorted_nsm_clusters: AlbaArakoonController._logger.debug( 'ALBA Backend {0} - Processing NSM {1} - Expected safety {2} - Current safety {3}' .format(alba_backend.name, nsm_cluster.number, safety, len(nsm_cluster.nsm_services))) AlbaArakoonController.ensure_nsm_cluster_safety( nsm_cluster, nsm_storagerouters, nsm_installer=nsm_installer) AlbaArakoonController.ensure_nsm_clusters_load( alba_backend, nsms_per_storagerouter=nsm_storagerouters, ssh_clients=ssh_clients, version_str=version_str, min_internal_nsms=min_internal_nsms, external_nsm_cluster_names=external_nsm_cluster_names) except Exception: AlbaArakoonController._logger.exception( 'NSM Checkup failed for Backend {0}'.format( alba_backend.name)) failed_backends.append(alba_backend.name)
def _alba_arakoon_checkup(cls, alba_backend_guid=None, abm_cluster=None, nsm_clusters=None): # type: (Optional[str], Optional[str], Optional[List[str]]) -> None """ Creates a new Arakoon cluster if required and extends cluster if possible on all available master nodes :param alba_backend_guid: Guid of the ALBA Backend :type alba_backend_guid: str :param nsm_clusters: NSM clusters for this ALBA Backend The code will claim the Arakoon clusters for this backend when provided :type nsm_clusters: list[str] :param abm_cluster: ABM cluster for this ALBA Backend The code will claim the Arakoon cluster for this backend when provided :type abm_cluster: str|None :return:None :rtype: NoneType """ slaves = StorageRouterList.get_slaves() masters = StorageRouterList.get_masters() clients = {} for storagerouter in masters + slaves: try: clients[storagerouter] = SSHClient(storagerouter) except UnableToConnectException: cls._logger.warning( 'Storage Router with IP {0} is not reachable'.format( storagerouter.ip)) available_storagerouters = cls.get_available_arakoon_storagerouters( clients) # Call here, because this potentially raises error, which should happen before actually making changes abm_installer = ABMInstaller(ssh_clients=clients) nsm_installer = NSMInstaller(version_str=abm_installer.version_str, ssh_clients=clients) # Cluster creation if alba_backend_guid is not None: alba_backend = AlbaBackend(alba_backend_guid) # @todo revisit. This might enforce the ABM name for externals (might be unintended) abm_cluster_name = '{0}-abm'.format(alba_backend.name) # ABM Arakoon cluster creation if alba_backend.abm_cluster is None: # Fallback to installing the cluster on an available storagerouter storagerouter, partition = available_storagerouters.items()[0] abm_installer.deploy_abm_cluster( alba_backend, abm_cluster_name, requested_abm_cluster_name=abm_cluster, storagerouter=storagerouter) # NSM Arakoon cluster creation if len(alba_backend.nsm_clusters ) == 0 and nsm_clusters is not None: storagerouter, partition = available_storagerouters.items()[0] nsm_installer.deploy_nsm_cluster(alba_backend, storagerouter=storagerouter, nsm_clusters=nsm_clusters) # ABM Cluster extension for alba_backend in AlbaBackendList.get_albabackends(): if alba_backend.abm_cluster is None: AlbaArakoonController._logger.warning( 'ALBA Backend {0} does not have an ABM cluster registered'. format(alba_backend.name)) continue cls.ensure_abm_cluster_safety(alba_backend.abm_cluster, available_storagerouters, abm_installer=abm_installer)
def build_dal_structure(structure, previous_structure=None): """ Builds a service structure Example: structure = AlbaDalHelper.build_service_structure({ 'alba_backends': [1], 'alba_nodes': [1] }) """ if previous_structure is None: previous_structure = {} alba_osds = previous_structure.get('alba_osds', {}) alba_nodes = previous_structure.get('alba_nodes', {}) backend_types = previous_structure.get('backend_types', {}) service_types = previous_structure.get('service_types', {}) alba_backends = previous_structure.get('alba_backends', {}) alba_abm_clusters = previous_structure.get('alba_abm_clusters', {}) alba_nsm_clusters = previous_structure.get('alba_nsm_clusters', {}) if 1 not in backend_types: backend_type = BackendType() backend_type.code = 'alba' backend_type.name = 'ALBA' backend_type.save() backend_types[1] = backend_type if 'AlbaManager' not in service_types: service_type = ServiceTypeList.get_by_name('AlbaManager') if service_type is None: service_type = ServiceType() service_type.name = 'AlbaManager' service_type.save() service_types['AlbaManager'] = service_type if 'NamespaceManager' not in service_types: service_type = ServiceTypeList.get_by_name('NamespaceManager') if service_type is None: service_type = ServiceType() service_type.name = 'NamespaceManager' service_type.save() service_types['NamespaceManager'] = service_type for ab_id, scaling in structure.get('alba_backends', ()): if ab_id not in alba_backends: backend = Backend() backend.name = 'backend_{0}'.format(ab_id) backend.backend_type = backend_types[1] backend.save() alba_backend = AlbaBackend() alba_backend.backend = backend alba_backend.scaling = getattr(AlbaBackend.SCALINGS, scaling) alba_backend.alba_id = str(ab_id) alba_backend.save() alba_backends[ab_id] = alba_backend for ab_id in structure.get('alba_abm_clusters', ()): if ab_id not in alba_abm_clusters: if ab_id not in alba_backends: raise ValueError('Non-existing ALBA Backend ID provided') alba_backend = alba_backends[ab_id] abm_cluster = ABMCluster() abm_cluster.name = '{0}-abm'.format(alba_backend.name) abm_cluster.alba_backend = alba_backend abm_cluster.config_location = '/ovs/arakoon/{0}-abm/config'.format( alba_backend.name) abm_cluster.save() abm_service = Service() abm_service.name = 'arakoon-{0}-abm'.format(alba_backend.name) abm_service.type = service_types['AlbaManager'] abm_service.ports = [] abm_service.storagerouter = None abm_service.save() abm_junction_service = ABMService() abm_junction_service.service = abm_service abm_junction_service.abm_cluster = abm_cluster abm_junction_service.save() alba_abm_clusters[ab_id] = abm_cluster for ab_id, amount in structure.get('alba_nsm_clusters', ()): if ab_id not in alba_nsm_clusters or amount != len( alba_nsm_clusters[ab_id]): if ab_id not in alba_backends: raise ValueError('Non-existing ALBA Backend ID provided') alba_backend = alba_backends[ab_id] alba_nsm_clusters[ab_id] = [] nsm_clusters = dict( (nsm_cluster.number, nsm_cluster) for nsm_cluster in alba_backend.nsm_clusters) for number in range(amount): if number in nsm_clusters: alba_nsm_clusters[ab_id].append(nsm_clusters[number]) continue nsm_cluster = NSMCluster() nsm_cluster.name = '{0}-nsm_{1}'.format( alba_backend.name, number) nsm_cluster.number = number nsm_cluster.alba_backend = alba_backend nsm_cluster.config_location = '/ovs/arakoon/{0}-nsm_{1}/config'.format( alba_backend.name, number) nsm_cluster.save() nsm_service = Service() nsm_service.name = 'arakoon-{0}-nsm_{1}'.format( alba_backend.name, number) nsm_service.type = service_types['NamespaceManager'] nsm_service.ports = [] nsm_service.storagerouter = None nsm_service.save() nsm_junction_service = NSMService() nsm_junction_service.service = nsm_service nsm_junction_service.nsm_cluster = nsm_cluster nsm_junction_service.save() alba_nsm_clusters[ab_id].append(nsm_cluster) for an_id in structure.get('alba_nodes', []): if an_id not in alba_nodes: alba_node = AlbaNode() alba_node.ip = '10.1.0.{0}'.format(an_id) alba_node.port = 8500 alba_node.username = str(an_id) alba_node.password = str(an_id) alba_node.node_id = 'node_{0}'.format(an_id) alba_node.save() alba_nodes[an_id] = alba_node if alba_node in ManagerClientMockup.test_results: ManagerClientMockup.test_results[alba_node].update( {'get_metadata': { '_version': 3 }}) else: ManagerClientMockup.test_results[alba_node] = { 'get_metadata': { '_version': 3 } } for ao_id, ab_id, an_id, slot_id in structure.get('alba_osds', ()): if ao_id not in alba_osds: osd = AlbaOSD() osd.osd_id = 'alba_osd_{0}'.format(ao_id) osd.osd_type = AlbaOSD.OSD_TYPES.ASD osd.alba_backend = alba_backends[ab_id] osd.alba_node = alba_nodes[an_id] osd.slot_id = 'alba_slot_{0}'.format(slot_id) osd.ips = ['127.0.0.{0}'.format(ao_id)] osd.port = 35000 + ao_id osd.save() alba_osds[ao_id] = osd return { 'alba_osds': alba_osds, 'alba_nodes': alba_nodes, 'backend_types': backend_types, 'service_types': service_types, 'alba_backends': alba_backends, 'alba_abm_clusters': alba_abm_clusters, 'alba_nsm_clusters': alba_nsm_clusters }