def _parser(self, content=None): LOG.debug('parsing data:\n%s', content) content = content.replace("\r", "") content = content.strip() json_string = content.replace("'", "\"") cli_data = json_string.splitlines()[2] if cli_data: try: data_dict = json.loads(cli_data) except Exception: msg = _('Failed to parse data: ' '%(cli_data)s to dictionary.') % { 'cli_data': cli_data} LOG.error(msg) raise exception.InfortrendNASException(err=msg) rc = int(data_dict['cliCode'][0]['Return'], 16) if rc == 0: result = data_dict['data'] else: result = data_dict['cliCode'][0]['CLI'] else: msg = _('No data is returned from NAS.') LOG.error(msg) raise exception.InfortrendNASException(err=msg) if rc != 0: msg = _('NASCLI error, returned: %(result)s.') % { 'result': result} LOG.error(msg) raise exception.InfortrendCLIException( err=msg, rc=rc, out=result) return rc, result
def manage_existing(self, share, driver_options): share_proto = share['share_proto'].lower() pool_name = share_utils.extract_host(share['host'], level='pool') pool_data = self._get_share_pool_data(pool_name) volume_name = self._extract_lv_name(pool_data) input_location = share['export_locations'][0]['path'] share_name = share['id'].replace('-', '') ch_ip, folder_name = self._parse_location(input_location, share_proto) if not self._check_channel_ip(ch_ip): msg = _('Export location ip: [%(ch_ip)s] ' 'is incorrect, please use data port ip.') % { 'ch_ip': ch_ip} LOG.error(msg) raise exception.InfortrendNASException(err=msg) if not self._check_share_exist(pool_name, folder_name): msg = _('Can not find folder [%(folder_name)s] ' 'in pool [%(pool_name)s].') % { 'folder_name': folder_name, 'pool_name': pool_name} LOG.error(msg) raise exception.InfortrendNASException(err=msg) share_path = pool_data['path'] + folder_name self._ensure_protocol_on(share_path, share_proto, share_name) share_size = self._get_share_size( pool_data['id'], pool_name, folder_name) if not share_size: msg = _('Folder [%(folder_name)s] has no size limitation, ' 'please set it first for Openstack management.') % { 'folder_name': folder_name} LOG.error(msg) raise exception.InfortrendNASException(err=msg) # rename folder name command_line = ['folder', 'options', pool_data['id'], volume_name, '-k', folder_name, share_name] self._execute(command_line) location = self._export_location( share_name, share_proto, pool_data['path']) LOG.info('Successfully Manage Infortrend Share [%(folder_name)s], ' 'Size: [%(size)s G], Protocol: [%(share_proto)s], ' 'new name: [%(share_name)s].', { 'folder_name': folder_name, 'size': share_size, 'share_proto': share_proto, 'share_name': share_name}) return {'size': share_size, 'export_locations': location}
def _parser(self, content=None): content = content.replace("\r", "") content = content.strip() LOG.debug(content) if content: try: content_dict = eval(content) except: msg = _('Failed to parse data: %(content)s to dictionary') % { 'content': content} LOG.error(msg) raise exception.InfortrendNASException(err=msg) rc = int(content_dict['cliCode'][0]['Return'], 16) if rc == 0: result = content_dict['data'] else: result = content_dict['cliCode'][0]['CLI'] else: rc = -1 result = None return rc, result
def _get_share_pool_data(self, pool_name): if not pool_name: msg = _("Pool is not available in the share host.") raise exception.InvalidHost(reason=msg) if pool_name in self.pool_dict.keys(): return self.pool_dict[pool_name] else: msg = _('Pool [%(pool_name)s] not set in conf.') % { 'pool_name': pool_name} LOG.error(msg) raise exception.InfortrendNASException(err=msg)
def _execute(self, command_line): commands = ' '.join(command_line) mutils.check_ssh_injection(commands) LOG.debug('Executing: %(command)s', {'command': commands}) rc, result = self._ssh_execute(commands) if rc != 0: msg = _('Failed to execute commands: [%(command)s].') % { 'command': commands} LOG.error(msg) raise exception.InfortrendNASException( err=msg, rc=rc, out=out) return result
def _ssh_execute(self, commands): try: out, err = processutils.ssh_execute( self.ssh, commands, timeout=self.ssh_timeout, check_exit_code=True) except processutils.ProcessExecutionError as pe: rc = pe.exit_code out = pe.stdout out = out.replace('\n', '\\n') msg = _('Error on execute ssh command. ' 'Exit code: %(rc)d, msg: %(out)s') % { 'rc': rc, 'out': out} raise exception.InfortrendNASException(err=msg) return out
def _allow_access(self, share, access, share_server=None): pool_name = share_utils.extract_host(share['host'], level='pool') pool_data = self._get_share_pool_data(pool_name) share_name = share['id'].replace('-', '') share_path = pool_data['path'] + share_name share_proto = share['share_proto'].lower() access_type = access['access_type'] access_level = access['access_level'] or constants.ACCESS_LEVEL_RW access_to = access['access_to'] ACCESS_LEVEL_MAP = {access_level: access_level} msg = self._check_access_legal(share_proto, access_type) if msg: raise exception.InvalidShareAccess(reason=msg) if share_proto == 'nfs': command_line = ['share', 'options', share_path, 'nfs', '-h', access_to, '-p', access_level] self._execute(command_line) elif share_proto == 'cifs': if not self._check_user_exist(access_to): msg = _('Please create user [%(user)s] in advance.') % { 'user': access_to} LOG.error(msg) raise exception.InfortrendNASException(err=msg) if access_level == constants.ACCESS_LEVEL_RW: cifs_access = 'f' elif access_level == constants.ACCESS_LEVEL_RO: cifs_access = 'r' try: access_level = ACCESS_LEVEL_MAP[access_level] except KeyError: msg = _('Unsupported access_level: [%s].') % access_level raise exception.InvalidInput(msg) command_line = ['acl', 'set', share_path, '-u', access_to, '-a', cifs_access] self._execute(command_line) LOG.info('Share [%(share)s] access to [%(access_to)s] ' 'level [%(level)s] protocol [%(share_proto)s] completed.', { 'share': share['id'], 'access_to': access_to, 'level': access_level, 'share_proto': share_proto})
def _check_pools_setup(self): pool_list = list(self.pool_dict.keys()) command_line = ['folder', 'status'] rc, pool_data = self._execute(command_line) for pool in pool_data: pool_name = self._extract_pool_name(pool) if pool_name in self.pool_dict.keys(): pool_list.remove(pool_name) self.pool_dict[pool_name]['id'] = pool['volumeId'] self.pool_dict[pool_name]['path'] = pool['directory'] + '/' if len(pool_list) == 0: break if len(pool_list) != 0: msg = _('Please create %(pool_list)s pool/s in advance!') % { 'pool_list': pool_list} LOG.error(msg) raise exception.InfortrendNASException(message=msg)
def _check_channels_status(self): channel_list = list(self.channel_dict.keys()) command_line = ['ifconfig', 'inet', 'show'] rc, channels_status = self._execute(command_line) for channel in channels_status: if 'CH' in channel['datalink']: ch = channel['datalink'].strip('CH') if ch in self.channel_dict.keys(): self.channel_dict[ch] = channel['IP'] channel_list.remove(ch) if channel['status'] == 'DOWN': LOG.warning('Channel [%(ch)s] status ' 'is down, please check.', { 'ch': ch}) if len(channel_list) != 0: msg = _('Channel setting %(channel_list)s is invalid!') % { 'channel_list': channel_list} LOG.error(msg) raise exception.InfortrendNASException(message=msg)
def _parse_location(self, input_location, share_proto): ip = None folder_name = None pattern_ip = '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' if share_proto == 'nfs': pattern_folder = '[^\/]+$' ip = "".join(re.findall(pattern_ip, input_location)) folder_name = "".join(re.findall(pattern_folder, input_location)) elif share_proto == 'cifs': pattern_folder = '[^\\\]+$' ip = "".join(re.findall(pattern_ip, input_location)) folder_name = "".join(re.findall(pattern_folder, input_location)) if not (ip and folder_name): msg = _('Export location error, please check ' 'ip: [%(ip)s], folder_name: [%(folder_name)s].') % { 'ip': ip, 'folder_name': folder_name} LOG.error(msg) raise exception.InfortrendNASException(err=msg) return ip, folder_name