text:
import copy
import re

from lxml import builder
from lxml import etree as ET
from oslo_concurrency import processutils
from oslo_log import log
import six

from manila.common import constants as const
from manila import exception
from manila.i18n import _, _LE, _LI, _LW
from manila.share.drivers.dell_emc.plugins.vnx import connector
from manila.share.drivers.dell_emc.plugins.vnx import constants
from manila.share.drivers.dell_emc.plugins.vnx import utils as vnx_utils
from manila.share.drivers.dell_emc.plugins.vnx import xml_api_parser as parser
from manila import utils

LOG = log.getLogger(__name__)

@vnx_utils.decorate_all_methods(vnx_utils.log_enter_exit,
                                debug_only=True)
class StorageObjectManager(object):
    def __init__(self, configuration):
        self.context = dict()

        self.connectors = dict()
        self.connectors['XML'] = connector.XMLAPIConnector(configuration)
        self.connectors['SSH'] = connector.SSHConnector(configuration)

        elt_maker = builder.ElementMaker(nsmap={None: constants.XML_NAMESPACE})
        xml_parser = parser.XMLAPIParser()

        obj_types = StorageObject.__subclasses__()  # pylint: disable=E1101
        for item in obj_types:
            key = item.__name__
            self.context[key] = eval(key)(self.connectors,
                                          elt_maker,
                                          xml_parser,
                                          self)

    def getStorageContext(self, type):
        if type in self.context:
            return self.context[type]
        else:
            message = (_("Invalid storage object type %s.") % type)
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

class StorageObject(object):
    def __init__(self, conn, elt_maker, xml_parser, manager):
        self.conn = conn
        self.elt_maker = elt_maker
        self.xml_parser = xml_parser
        self.manager = manager
        self.xml_retry = False
        self.ssh_retry_patterns = [
            (
                constants.SSH_DEFAULT_RETRY_PATTERN,
                exception.EMCVnxLockRequiredException()
            ),
        ]

    def _translate_response(self, response):
        """Translate different status to ok/error status."""
        if (constants.STATUS_OK == response['maxSeverity'] or
                constants.STATUS_ERROR == response['maxSeverity']):
            return

        old_Severity = response['maxSeverity']
        if response['maxSeverity'] in (constants.STATUS_DEBUG,
                                       constants.STATUS_INFO):
            response['maxSeverity'] = constants.STATUS_OK

            LOG.warning(_LW("Translated status from %(old)s to %(new)s. "
                            "Message: %(info)s."),
                        {'old': old_Severity,
                         'new': response['maxSeverity'],
                         'info': response})

    def _response_validation(self, response, error_code):
        """Validates whether a response includes a certain error code."""
        msg_codes = self._get_problem_message_codes(response['problems'])

        for code in msg_codes:
            if code == error_code:
                return True

        return False

    def _get_problem_message_codes(self, problems):
        message_codes = []
        for problem in problems:
            if 'messageCode' in problem:
                message_codes.append(problem['messageCode'])

        return message_codes

    def _get_problem_messages(self, problems):
        messages = []
        for problem in problems:
            if 'message' in problem:
                messages.append(problem['message'])

        return messages

    def _get_problem_diags(self, problems):
        diags = []

        for problem in problems:
            if 'Diagnostics' in problem:
                diags.append(problem['Diagnostics'])

        return diags

    def _build_query_package(self, body):
        return self.elt_maker.RequestPacket(
            self.elt_maker.Request(
                self.elt_maker.Query(body)
            )
        )

    def _build_task_package(self, body):
        return self.elt_maker.RequestPacket(
            self.elt_maker.Request(
                self.elt_maker.StartTask(body, timeout='300')
            )
        )

    @utils.retry(exception.EMCVnxLockRequiredException)
    def _send_request(self, req):
        req_xml = constants.XML_HEADER + ET.tostring(req).decode('utf-8')

        rsp_xml = self.conn['XML'].request(str(req_xml))

        response = self.xml_parser.parse(rsp_xml)

        self._translate_response(response)

        if (response['maxSeverity'] != constants.STATUS_OK and
                self._response_validation(response,
                                          constants.MSG_CODE_RETRY)):
            raise exception.EMCVnxLockRequiredException

        return response

    @utils.retry(exception.EMCVnxLockRequiredException)
    def _execute_cmd(self, cmd, retry_patterns=None, check_exit_code=False):
        """Execute NAS command via SSH.

        :param retry_patterns: list of tuples,where each tuple contains a reg
            expression and a exception.
        :param check_exit_code: Boolean. Raise
            processutils.ProcessExecutionError if the command failed to
            execute and this parameter is set to True.
        """
        if retry_patterns is None:
            retry_patterns = self.ssh_retry_patterns

        try:
            out, err = self.conn['SSH'].run_ssh(cmd, check_exit_code)
        except processutils.ProcessExecutionError as e:
            for pattern in retry_patterns:
                if re.search(pattern[0], e.stdout):
                    raise pattern[1]

            raise e

        return out, err

    def _copy_properties(self, source, target, property_map, deep_copy=True):
        for property in property_map:
            if isinstance(property, tuple):
                target_key, src_key = property
            else:
                target_key = src_key = property

            if src_key in source:
                if deep_copy and isinstance(source[src_key], list):
                    target[target_key] = copy.deepcopy(source[src_key])
                else:
                    target[target_key] = source[src_key]
            else:
                target[target_key] = None

    def _get_mover_id(self, mover_name, is_vdm):
        if is_vdm:
            return self.get_context('VDM').get_id(mover_name)
        else:
            return self.get_context('Mover').get_id(mover_name,
                                                    self.xml_retry)

    def get_context(self, type):
        return self.manager.getStorageContext(type)

@vnx_utils.decorate_all_methods(vnx_utils.log_enter_exit,
                                debug_only=True)
class FileSystem(StorageObject):
    def __init__(self, conn, elt_maker, xml_parser, manager):
        super(FileSystem, self).__init__(conn, elt_maker, xml_parser, manager)
        self.filesystem_map = dict()

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def create(self, name, size, pool_name, mover_name, is_vdm=True):
        pool_id = self.get_context('StoragePool').get_id(pool_name)

        mover_id = self._get_mover_id(mover_name, is_vdm)
        if is_vdm:
            mover = self.elt_maker.Vdm(vdm=mover_id)
        else:
            mover = self.elt_maker.Mover(mover=mover_id)

        if self.xml_retry:
            self.xml_retry = False

        request = self._build_task_package(
            self.elt_maker.NewFileSystem(
                mover,
                self.elt_maker.StoragePool(
                    pool=pool_id,
                    size=six.text_type(size),
                    mayContainSlices='true'
                ),
                name=name
            )
        )

        response = self._send_request(request)

        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif self._response_validation(
                response, constants.MSG_FILESYSTEM_EXIST):
            LOG.warning(_LW("File system %s already exists. "
                            "Skip the creation."), name)
            return
        elif constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to create file system %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

    def get(self, name):
        if name not in self.filesystem_map:
            request = self._build_query_package(
                self.elt_maker.FileSystemQueryParams(
                    self.elt_maker.AspectSelection(
                        fileSystems='true',
                        fileSystemCapacityInfos='true'
                    ),
                    self.elt_maker.Alias(name=name)
                )
            )

            response = self._send_request(request)

            if constants.STATUS_OK != response['maxSeverity']:
                if self._is_filesystem_nonexistent(response):
                    return constants.STATUS_NOT_FOUND, response['problems']
                else:
                    return response['maxSeverity'], response['problems']

            if not response['objects']:
                return constants.STATUS_NOT_FOUND, response['problems']

            src = response['objects'][0]
            filesystem = {}
            property_map = (
                'name',
                ('pools_id', 'storagePools'),
                ('volume_id', 'volume'),
                ('size', 'volumeSize'),
                ('id', 'fileSystem'),
                'type',
                'dataServicePolicies',
            )

            self._copy_properties(src, filesystem, property_map)

            self.filesystem_map[name] = filesystem

        return constants.STATUS_OK, self.filesystem_map[name]

    def delete(self, name):
        status, out = self.get(name)
        if constants.STATUS_NOT_FOUND == status:
            LOG.warning(_LW("File system %s not found. Skip the deletion."),
                        name)
            return
        elif constants.STATUS_OK != status:
            message = (_("Failed to get file system by name %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': out})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        id = self.filesystem_map[name]['id']

        request = self._build_task_package(
            self.elt_maker.DeleteFileSystem(fileSystem=id)
        )

        response = self._send_request(request)

        if constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to delete file system %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        self.filesystem_map.pop(name)

    def extend(self, name, pool_name, new_size):
        status, out = self.get(name)
        if constants.STATUS_OK != status:
            message = (_("Failed to get file system by name %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': out})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        id = out['id']
        size = int(out['size'])
        if new_size < size:
            message = (_("Failed to extend file system %(name)s because new "
                         "size %(new_size)d is smaller than old size "
                         "%(size)d.") %
                       {'name': name, 'new_size': new_size, 'size': size})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
        elif new_size == size:
            return

        pool_id = self.get_context('StoragePool').get_id(pool_name)

        request = self._build_task_package(
            self.elt_maker.ExtendFileSystem(
                self.elt_maker.StoragePool(
                    pool=pool_id,
                    size=six.text_type(new_size - size)
                ),
                fileSystem=id,
            )
        )

        response = self._send_request(request)

        if constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to extend file system %(name)s to new size "
                         "%(new_size)d. Reason: %(err)s.") %
                       {'name': name,
                        'new_size': new_size,
                        'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

    def get_id(self, name):
        status, out = self.get(name)
        if constants.STATUS_OK != status:
            message = (_("Failed to get file system by name %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': out})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        return self.filesystem_map[name]['id']

    def _is_filesystem_nonexistent(self, response):
        """Translate different status to ok/error status."""
        msg_codes = self._get_problem_message_codes(response['problems'])
        diags = self._get_problem_diags(response['problems'])

        for code, diagnose in zip(msg_codes, diags):
            if (code == constants.MSG_FILESYSTEM_NOT_FOUND and
                    diagnose.find('File system not found.') != -1):
                return True

        return False

    def create_from_snapshot(self, name, snap_name, source_fs_name, pool_name,
                             mover_name, connect_id):
        create_fs_cmd = [
            'env', 'NAS_DB=/nas', '/nas/bin/nas_fs',
            '-name', name,
            '-type', 'uxfs',
            '-create',
            'samesize=' + source_fs_name,
            'pool=%s' % pool_name,
            'storage=SINGLE',
            'worm=off',
            '-thin', 'no',
            '-option', 'slice=y',
        ]

        self._execute_cmd(create_fs_cmd)

        ro_mount_cmd = [
            'env', 'NAS_DB=/nas', '/nas/bin/server_mount', mover_name,
            '-option', 'ro',
            name,
            '/%s' % name,
        ]
        self._execute_cmd(ro_mount_cmd)

        session_name = name + ':' + snap_name
        copy_ckpt_cmd = [
            'env', 'NAS_DB=/nas', '/nas/bin/nas_copy',
            '-name', session_name[0:63],
            '-source', '-ckpt', snap_name,
            '-destination', '-fs', name,
            '-interconnect',
            'id=%s' % connect_id,
            '-overwrite_destination',
            '-full_copy',
        ]

        try:
            self._execute_cmd(copy_ckpt_cmd, check_exit_code=True)
        except processutils.ProcessExecutionError:
            LOG.exception(_LE("Failed to copy content from snapshot %(snap)s "
                              "to file system %(filesystem)s."),
                          {'snap': snap_name,
                           'filesystem': name})

        # When an error happens during nas_copy, we need to continue
        # deleting the checkpoint of the target file system if it exists.
        query_fs_cmd = [
            'env', 'NAS_DB=/nas', '/nas/bin/nas_fs',
            '-info', name,
        ]
        out, err = self._execute_cmd(query_fs_cmd)
        re_ckpts = r'ckpts\s*=\s*(.*)\s*'
        m = re.search(re_ckpts, out)
        if m is not None:
            ckpts = m.group(1)
            for ckpt in re.split(',', ckpts):
                umount_ckpt_cmd = [
                    'env', 'NAS_DB=/nas',
                    '/nas/bin/server_umount', mover_name,
                    '-perm', ckpt,
                ]
                self._execute_cmd(umount_ckpt_cmd)
                delete_ckpt_cmd = [
                    'env', 'NAS_DB=/nas', '/nas/bin/nas_fs',
                    '-delete', ckpt,
                    '-Force',
                ]
                self._execute_cmd(delete_ckpt_cmd)

        rw_mount_cmd = [
            'env', 'NAS_DB=/nas', '/nas/bin/server_mount', mover_name,
            '-option', 'rw',
            name,
            '/%s' % name,
        ]
        self._execute_cmd(rw_mount_cmd)

@vnx_utils.decorate_all_methods(vnx_utils.log_enter_exit,
                                debug_only=True)
class StoragePool(StorageObject):
    def __init__(self, conn, elt_maker, xml_parser, manager):
        super(StoragePool, self).__init__(conn, elt_maker, xml_parser, manager)
        self.pool_map = dict()

    def get(self, name, force=False):
        if name not in self.pool_map or force:
            status, out = self.get_all()
            if constants.STATUS_OK != status:
                return status, out

        if name not in self.pool_map:
            return constants.STATUS_NOT_FOUND, None

        return constants.STATUS_OK, self.pool_map[name]

    def get_all(self):
        self.pool_map.clear()

        request = self._build_query_package(
            self.elt_maker.StoragePoolQueryParams()
        )

        response = self._send_request(request)

        if constants.STATUS_OK != response['maxSeverity']:
            return response['maxSeverity'], response['problems']

        if not response['objects']:
            return constants.STATUS_NOT_FOUND, response['problems']

        for item in response['objects']:
            pool = {}
            property_map = (
                'name',
                ('movers_id', 'movers'),
                ('total_size', 'autoSize'),
                ('used_size', 'usedSize'),
                'diskType',
                'dataServicePolicies',
                ('id', 'pool'),
            )
            self._copy_properties(item, pool, property_map)
            self.pool_map[item['name']] = pool

        return constants.STATUS_OK, self.pool_map

    def get_id(self, name):
        status, out = self.get(name)

        if constants.STATUS_OK != status:
            message = (_("Failed to get storage pool by name %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': out})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        return out['id']

@vnx_utils.decorate_all_methods(vnx_utils.log_enter_exit,
                                debug_only=True)
class MountPoint(StorageObject):
    def __init__(self, conn, elt_maker, xml_parser, manager):
        super(MountPoint, self).__init__(conn, elt_maker, xml_parser, manager)

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def create(self, mount_path, fs_name, mover_name, is_vdm=True):
        fs_id = self.get_context('FileSystem').get_id(fs_name)

        mover_id = self._get_mover_id(mover_name, is_vdm)

        if self.xml_retry:
            self.xml_retry = False

        request = self._build_task_package(
            self.elt_maker.NewMount(
                self.elt_maker.MoverOrVdm(
                    mover=mover_id,
                    moverIdIsVdm='true' if is_vdm else 'false',
                ),
                fileSystem=fs_id,
                path=mount_path
            )
        )

        response = self._send_request(request)

        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif self._is_mount_point_already_existent(response):
            LOG.warning(_LW("Mount Point %(mount)s already exists. "
                            "Skip the creation."), {'mount': mount_path})
            return
        elif constants.STATUS_OK != response['maxSeverity']:
            message = (_('Failed to create Mount Point %(mount)s for '
                         'file system %(fs_name)s. Reason: %(err)s.') %
                       {'mount': mount_path,
                        'fs_name': fs_name,
                        'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def get(self, mover_name, is_vdm=True):
        mover_id = self._get_mover_id(mover_name, is_vdm)

        if self.xml_retry:
            self.xml_retry = False

        request = self._build_query_package(
            self.elt_maker.MountQueryParams(
                self.elt_maker.MoverOrVdm(
                    mover=mover_id,
                    moverIdIsVdm='true' if is_vdm else 'false'
                )
            )
        )

        response = self._send_request(request)

        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif constants.STATUS_OK != response['maxSeverity']:
            return response['maxSeverity'], response['objects']

        if not response['objects']:
            return constants.STATUS_NOT_FOUND, None
        else:
            return constants.STATUS_OK, response['objects']

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def delete(self, mount_path, mover_name, is_vdm=True):
        mover_id = self._get_mover_id(mover_name, is_vdm)

        if self.xml_retry:
            self.xml_retry = False

        request = self._build_task_package(
            self.elt_maker.DeleteMount(
                mover=mover_id,
                moverIdIsVdm='true' if is_vdm else 'false',
                path=mount_path
            )
        )

        response = self._send_request(request)

        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif self._is_mount_point_nonexistent(response):
            LOG.warning(_LW('Mount point %(mount)s on mover %(mover_name)s '
                            'not found.'),
                        {'mount': mount_path, 'mover_name': mover_name})

            return
        elif constants.STATUS_OK != response['maxSeverity']:
            message = (_('Failed to delete mount point %(mount)s on mover '
                         '%(mover_name)s. Reason: %(err)s.') %
                       {'mount': mount_path,
                        'mover_name': mover_name,
                        'err': response})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

    def _is_mount_point_nonexistent(self, response):
        """Translate different status to ok/error status."""
        msg_codes = self._get_problem_message_codes(response['problems'])
        message = self._get_problem_messages(response['problems'])

        for code, msg in zip(msg_codes, message):
            if ((code == constants.MSG_GENERAL_ERROR and msg.find(
                    'No such path or invalid operation') != -1) or
                    code == constants.MSG_INVALID_VDM_ID or
                    code == constants.MSG_INVALID_MOVER_ID):
                return True

        return False

    def _is_mount_point_already_existent(self, response):
        """Translate different status to ok/error status."""
        msg_codes = self._get_problem_message_codes(response['problems'])
        message = self._get_problem_messages(response['problems'])

        for code, msg in zip(msg_codes, message):
            if ((code == constants.MSG_GENERAL_ERROR and msg.find(
                    'Mount already exists') != -1)):
                return True

        return False

@vnx_utils.decorate_all_methods(vnx_utils.log_enter_exit,
                                debug_only=True)
class Mover(StorageObject):
    def __init__(self, conn, elt_maker, xml_parser, manager):
        super(Mover, self).__init__(conn, elt_maker, xml_parser, manager)
        self.mover_map = dict()
        self.mover_ref_map = dict()

    def get_ref(self, name, force=False):
        if name not in self.mover_ref_map or force:
            self.mover_ref_map.clear()

            request = self._build_query_package(
                self.elt_maker.MoverQueryParams(
                    self.elt_maker.AspectSelection(movers='true')
                )
            )

            response = self._send_request(request)

            if constants.STATUS_ERROR == response['maxSeverity']:
                return response['maxSeverity'], response['problems']

            for item in response['objects']:
                mover = {}
                property_map = ('name', ('id', 'mover'))
                self._copy_properties(item, mover, property_map)
                if mover:
                    self.mover_ref_map[mover['name']] = mover

        if (name not in self.mover_ref_map or
                self.mover_ref_map[name]['id'] == ''):
            return constants.STATUS_NOT_FOUND, None

        return constants.STATUS_OK, self.mover_ref_map[name]

    def get(self, name, force=False):
        if name not in self.mover_map or force:
            if name in self.mover_ref_map and not force:
                mover_id = self.mover_ref_map[name]['id']
            else:
                mover_id = self.get_id(name, force)

            if name in self.mover_map:
                self.mover_map.pop(name)

            request = self._build_query_package(
                self.elt_maker.MoverQueryParams(
                    self.elt_maker.AspectSelection(
                        moverDeduplicationSettings='true',
                        moverDnsDomains='true',
                        moverInterfaces='true',
                        moverNetworkDevices='true',
                        moverNisDomains='true',
                        moverRoutes='true',
                        movers='true',
                        moverStatuses='true'
                    ),
                    mover=mover_id
                )
            )

            response = self._send_request(request)
            if constants.STATUS_ERROR == response['maxSeverity']:
                return response['maxSeverity'], response['problems']

            if not response['objects']:
                return constants.STATUS_NOT_FOUND, response['problems']

            mover = {}
            src = response['objects'][0]
            property_map = (
                'name',
                ('id', 'mover'),
                ('Status', 'maxSeverity'),
                'version',
                'uptime',
                'role',
                ('interfaces', 'MoverInterface'),
                ('devices', 'LogicalNetworkDevice'),
                ('dns_domain', 'MoverDnsDomain'),
            )

            self._copy_properties(src, mover, property_map)

            internal_devices = []
            if mover['interfaces']:
                for interface in mover['interfaces']:
                    if self._is_internal_device(interface['device']):
                        internal_devices.append(interface)

                mover['interfaces'] = [var for var in mover['interfaces'] if
                                       var not in internal_devices]

            self.mover_map[name] = mover

        return constants.STATUS_OK, self.mover_map[name]

    def get_id(self, name, force=False):
        status, mover_ref = self.get_ref(name, force)
        if constants.STATUS_OK != status:
            message = (_("Failed to get mover by name %(name)s.") %
                       {'name': name})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        return mover_ref['id']

    def _is_internal_device(self, device):
        for device_type in ('mge', 'fxg', 'tks', 'fsn'):
            if device.find(device_type) == 0:
                return True
        return False

    def get_interconnect_id(self, source, destination):
        header = [
            'id',
            'name',
            'source_server',
            'destination_system',
            'destination_server',
        ]

        conn_id = None

        command_nas_cel = [
            'env', 'NAS_DB=/nas', '/nas/bin/nas_cel',
            '-interconnect', '-l',
        ]
        out, err = self._execute_cmd(command_nas_cel)

        lines = out.strip().split('\n')
        for line in lines:
            if line.strip().split() == header:
                LOG.info(_LI('Found the header of the command '
                             '/nas/bin/nas_cel -interconnect -l.'))
            else:
                interconn = line.strip().split()
                if interconn[2] == source and interconn[4] == destination:
                    conn_id = interconn[0]

        return conn_id

    def get_physical_devices(self, mover_name):

        physical_network_devices = []

        cmd_sysconfig = [
            'env', 'NAS_DB=/nas', '/nas/bin/server_sysconfig', mover_name,
            '-pci'
        ]

        out, err = self._execute_cmd(cmd_sysconfig)

        re_pattern = ('0:\s*(?P<name>\S+)\s*IRQ:\s*(?P<irq>\d+)\n'
                      '.*\n'
                      '\s*Link:\s*(?P<link>[A-Za-z]+)')

        for device in re.finditer(re_pattern, out):
            if 'Up' in device.group('link'):
                physical_network_devices.append(device.group('name'))

        return physical_network_devices

@vnx_utils.decorate_all_methods(vnx_utils.log_enter_exit,
                                debug_only=True)
class VDM(StorageObject):
    def __init__(self, conn, elt_maker, xml_parser, manager):
        super(VDM, self).__init__(conn, elt_maker, xml_parser, manager)
        self.vdm_map = dict()

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def create(self, name, mover_name):
        mover_id = self._get_mover_id(mover_name, False)

        if self.xml_retry:
            self.xml_retry = False

        request = self._build_task_package(
            self.elt_maker.NewVdm(mover=mover_id, name=name)
        )

        response = self._send_request(request)

        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif self._response_validation(response, constants.MSG_VDM_EXIST):
            LOG.warning(_LW("VDM %(name)s already exists. Skip the creation."),
                        {'name': name})
        elif constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to create VDM %(name)s on mover "
                         "%(mover_name)s. Reason: %(err)s.") %
                       {'name': name,
                        'mover_name': mover_name,
                        'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

    def get(self, name):
        if name not in self.vdm_map:
            request = self._build_query_package(
                self.elt_maker.VdmQueryParams()
            )

            response = self._send_request(request)

            if constants.STATUS_OK != response['maxSeverity']:
                return response['maxSeverity'], response['problems']
            elif not response['objects']:
                return constants.STATUS_NOT_FOUND, response['problems']

            for item in response['objects']:
                vdm = {}
                property_map = (
                    'name',
                    ('id', 'vdm'),
                    'state',
                    ('host_mover_id', 'mover'),
                    ('interfaces', 'Interfaces'),
                )
                self._copy_properties(item, vdm, property_map)
                self.vdm_map[item['name']] = vdm

        if name not in self.vdm_map:
            return constants.STATUS_NOT_FOUND, None

        return constants.STATUS_OK, self.vdm_map[name]

    def delete(self, name):
        status, out = self.get(name)
        if constants.STATUS_NOT_FOUND == status:
            LOG.warning(_LW("VDM %s not found. Skip the deletion."),
                        name)
            return
        elif constants.STATUS_OK != status:
            message = (_("Failed to get VDM by name %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': out})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        vdm_id = self.vdm_map[name]['id']

        request = self._build_task_package(
            self.elt_maker.DeleteVdm(vdm=vdm_id)
        )

        response = self._send_request(request)

        if constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to delete VDM %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        self.vdm_map.pop(name)

    def get_id(self, name):
        status, vdm = self.get(name)
        if constants.STATUS_OK != status:
            message = (_("Failed to get VDM by name %(name)s.") %
                       {'name': name})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        return vdm['id']

    def attach_nfs_interface(self, vdm_name, if_name):

        command_attach_nfs_interface = [
            'env', 'NAS_DB=/nas', '/nas/bin/nas_server',
            '-vdm', vdm_name,
            '-attach', if_name,
        ]

        self._execute_cmd(command_attach_nfs_interface)

    def detach_nfs_interface(self, vdm_name, if_name):

        command_detach_nfs_interface = [
            'env', 'NAS_DB=/nas', '/nas/bin/nas_server',
            '-vdm', vdm_name,
            '-detach', if_name,
        ]

        try:
            self._execute_cmd(command_detach_nfs_interface,
                              check_exit_code=True)
        except processutils.ProcessExecutionError:
            interfaces = self.get_interfaces(vdm_name)
            if if_name not in interfaces['nfs']:
                LOG.debug("Failed to detach interface %(interface)s "
                          "from mover %(mover_name)s.",
                          {'interface': if_name, 'mover_name': vdm_name})
            else:
                message = (_("Failed to detach interface %(interface)s "
                             "from mover %(mover_name)s.") %
                           {'interface': if_name, 'mover_name': vdm_name})
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)

    def get_interfaces(self, vdm_name):
        interfaces = {
            'cifs': [],
            'nfs': [],
        }

        re_pattern = ('Interfaces to services mapping:'
                      '\s*(?P<interfaces>(\s*interface=.*)*)')

        command_get_interfaces = [
            'env', 'NAS_DB=/nas', '/nas/bin/nas_server',
            '-i',
            '-vdm', vdm_name,
        ]

        out, err = self._execute_cmd(command_get_interfaces)

        m = re.search(re_pattern, out)
        if m:
            if_list = m.group('interfaces').split('\n')
            for i in if_list:
                m_if = re.search('\s*interface=(?P<if>.*)\s*:'
                                 '\s*(?P<type>.*)\s*', i)
                if m_if:
                    if_name = m_if.group('if').strip()
                    if 'cifs' == m_if.group('type') and if_name != '':
                        interfaces['cifs'].append(if_name)
                    elif 'vdm' == m_if.group('type') and if_name != '':
                        interfaces['nfs'].append(if_name)

        return interfaces

@vnx_utils.decorate_all_methods(vnx_utils.log_enter_exit,
                                debug_only=True)
class Snapshot(StorageObject):
    def __init__(self, conn, elt_maker, xml_parser, manager):
        super(Snapshot, self).__init__(conn, elt_maker, xml_parser, manager)
        self.snap_map = dict()

    def create(self, name, fs_name, pool_id, ckpt_size=None):
        fs_id = self.get_context('FileSystem').get_id(fs_name)

        if ckpt_size:
            elt_pool = self.elt_maker.StoragePool(
                pool=pool_id,
                size=six.text_type(ckpt_size)
            )
        else:
            elt_pool = self.elt_maker.StoragePool(pool=pool_id)

        new_ckpt = self.elt_maker.NewCheckpoint(
            self.elt_maker.SpaceAllocationMethod(
                elt_pool
            ),
            checkpointOf=fs_id,
            name=name
        )

        request = self._build_task_package(new_ckpt)

        response = self._send_request(request)

        if self._response_validation(response, constants.MSG_SNAP_EXIST):
            LOG.warning(_LW("Snapshot %(name)s already exists. "
                            "Skip the creation."),
                        {'name': name})
        elif constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to create snapshot %(name)s on "
                         "filesystem %(fs_name)s. Reason: %(err)s.") %
                       {'name': name,
                        'fs_name': fs_name,
                        'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

    def get(self, name):
        if name not in self.snap_map:
            request = self._build_query_package(
                self.elt_maker.CheckpointQueryParams(
                    self.elt_maker.Alias(name=name)
                )
            )

            response = self._send_request(request)

            if constants.STATUS_OK != response['maxSeverity']:
                return response['maxSeverity'], response['problems']

            if not response['objects']:
                return constants.STATUS_NOT_FOUND, response['problems']

            src = response['objects'][0]
            snap = {}
            property_map = (
                'name',
                ('id', 'checkpoint'),
                'checkpointOf',
                'state',
            )
            self._copy_properties(src, snap, property_map)

            self.snap_map[name] = snap

        return constants.STATUS_OK, self.snap_map[name]

    def delete(self, name):
        status, out = self.get(name)
        if constants.STATUS_NOT_FOUND == status:
            LOG.warning(_LW("Snapshot %s not found. Skip the deletion."),
                        name)
            return
        elif constants.STATUS_OK != status:
            message = (_("Failed to get snapshot by name %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': out})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        chpt_id = self.snap_map[name]['id']

        request = self._build_task_package(
            self.elt_maker.DeleteCheckpoint(checkpoint=chpt_id)
        )

        response = self._send_request(request)
        if constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to delete snapshot %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        self.snap_map.pop(name)

    def get_id(self, name):
        status, out = self.get(name)

        if constants.STATUS_OK != status:
            message = (_("Failed to get snapshot by %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': out})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        return self.snap_map[name]['id']

@vnx_utils.decorate_all_methods(vnx_utils.log_enter_exit,
                                debug_only=True)
class MoverInterface(StorageObject):
    def __init__(self, conn, elt_maker, xml_parser, manager):
        super(MoverInterface, self).__init__(conn, elt_maker, xml_parser,
                                             manager)

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def create(self, interface):
        # Maximum of 32 characters for mover interface name
        name = interface['name']
        if len(name) > 32:
            name = name[0:31]

        device_name = interface['device_name']
        ip_addr = interface['ip']
        mover_name = interface['mover_name']
        net_mask = interface['net_mask']
        vlan_id = interface['vlan_id'] if interface['vlan_id'] else -1

        mover_id = self._get_mover_id(mover_name, False)

        if self.xml_retry:
            self.xml_retry = False

        request = self._build_task_package(
            self.elt_maker.NewMoverInterface(
                device=device_name,
                ipAddress=six.text_type(ip_addr),
                mover=mover_id,
                name=name,
                netMask=net_mask,
                vlanid=six.text_type(vlan_id)
            )
        )

        response = self._send_request(request)

        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif self._response_validation(
                response, constants.MSG_INTERFACE_NAME_EXIST):
            LOG.warning(_LW("Mover interface name %s already exists. "
                            "Skip the creation."), name)
            return
        elif self._response_validation(
                response, constants.MSG_INTERFACE_EXIST):
            LOG.warning(_LW("Mover interface IP %s already exists. "
                            "Skip the creation."), ip_addr)
            return
        elif self._response_validation(
                response, constants.MSG_INTERFACE_INVALID_VLAN_ID):
            # When fail to create a mover interface with the specified
            # vlan id, VNX will leave a interface with vlan id 0 in the
            # backend. So we should explicitly remove the interface.
            try:
                self.delete(six.text_type(ip_addr), mover_name)
            except exception.EMCVnxXMLAPIError:
                pass
            message = (_("Invalid vlan id %s. Other interfaces on this "
                         "subnet are in a different vlan.") % vlan_id)
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
        elif constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to create mover interface %(interface)s. "
                         "Reason: %(err)s.") %
                       {'interface': interface,
                        'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

    def get(self, name, mover_name):
        # Maximum of 32 characters for mover interface name
        if len(name) > 32:
            name = name[0:31]

        status, mover = self.manager.getStorageContext('Mover').get(
            mover_name, True)
        if constants.STATUS_OK == status:
            for interface in mover['interfaces']:
                if name == interface['name']:
                    return constants.STATUS_OK, interface

        return constants.STATUS_NOT_FOUND, None

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def delete(self, ip_addr, mover_name):
        mover_id = self._get_mover_id(mover_name, False)

        if self.xml_retry:
            self.xml_retry = False

        request = self._build_task_package(
            self.elt_maker.DeleteMoverInterface(
                ipAddress=six.text_type(ip_addr),
                mover=mover_id
            )
        )

        response = self._send_request(request)

        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif self._response_validation(
                response, constants.MSG_INTERFACE_NON_EXISTENT):
            LOG.warning(_LW("Mover interface %s not found. "
                            "Skip the deletion."), ip_addr)
            return
        elif constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to delete mover interface %(ip)s on mover "
                         "%(mover)s. Reason: %(err)s.") %
                       {'ip': ip_addr,
                        'mover': mover_name,
                        'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

@vnx_utils.decorate_all_methods(vnx_utils.log_enter_exit,
                                debug_only=True)
class DNSDomain(StorageObject):
    def __init__(self, conn, elt_maker, xml_parser, manager):
        super(DNSDomain, self).__init__(conn, elt_maker, xml_parser, manager)

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def create(self, mover_name, name, servers, protocol='udp'):
        mover_id = self._get_mover_id(mover_name, False)

        if self.xml_retry:
            self.xml_retry = False

        request = self._build_task_package(
            self.elt_maker.NewMoverDnsDomain(
                mover=mover_id,
                name=name,
                servers=servers,
                protocol=protocol
            )
        )

        response = self._send_request(request)

        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to create DNS domain %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def delete(self, mover_name, name):
        mover_id = self._get_mover_id(mover_name, False)

        if self.xml_retry:
            self.xml_retry = False

        request = self._build_task_package(
            self.elt_maker.DeleteMoverDnsDomain(
                mover=mover_id,
                name=name
            )
        )

        response = self._send_request(request)
        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif constants.STATUS_OK != response['maxSeverity']:
            LOG.warning(_LW("Failed to delete DNS domain %(name)s. "
                            "Reason: %(err)s."),
                        {'name': name, 'err': response['problems']})

@vnx_utils.decorate_all_methods(vnx_utils.log_enter_exit,
                                debug_only=True)
class CIFSServer(StorageObject):
    def __init__(self, conn, elt_maker, xml_parser, manager):
        super(CIFSServer, self).__init__(conn, elt_maker, xml_parser, manager)
        self.cifs_server_map = dict()

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def create(self, server_args):
        compName = server_args['name']
        # Maximum of 14 characters for netBIOS name
        name = server_args['name'][-14:]
        # Maximum of 12 characters for alias name
        alias_name = server_args['name'][-12:]
        interfaces = server_args['interface_ip']
        domain_name = server_args['domain_name']
        user_name = server_args['user_name']
        password = server_args['password']
        mover_name = server_args['mover_name']
        is_vdm = server_args['is_vdm']

        mover_id = self._get_mover_id(mover_name, is_vdm)

        if self.xml_retry:
            self.xml_retry = False

        alias_name_list = [self.elt_maker.li(alias_name)]

        request = self._build_task_package(
            self.elt_maker.NewW2KCifsServer(
                self.elt_maker.MoverOrVdm(
                    mover=mover_id,
                    moverIdIsVdm='true' if server_args['is_vdm'] else 'false'
                ),
                self.elt_maker.Aliases(*alias_name_list),
                self.elt_maker.JoinDomain(userName=user_name,
                                          password=password),
                compName=compName,
                domain=domain_name,
                interfaces=interfaces,
                name=name
            )
        )

        response = self._send_request(request)

        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        if constants.STATUS_OK != response['maxSeverity']:
            status, out = self.get(compName, mover_name, is_vdm)
            if constants.STATUS_OK == status and out['domainJoined'] == 'true':
                return
            else:
                message = (_("Failed to create CIFS server %(name)s. "
                             "Reason: %(err)s.") %
                           {'name': name,
                            'err': response['problems']})
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def get_all(self, mover_name, is_vdm=True):
        mover_id = self._get_mover_id(mover_name, is_vdm)

        if self.xml_retry:
            self.xml_retry = False

        request = self._build_query_package(
            self.elt_maker.CifsServerQueryParams(
                self.elt_maker.MoverOrVdm(
                    mover=mover_id,
                    moverIdIsVdm='true' if is_vdm else 'false'
                )
            )
        )

        response = self._send_request(request)
        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif constants.STATUS_OK != response['maxSeverity']:
            return response['maxSeverity'], response['objects']

        if mover_name in self.cifs_server_map:
            self.cifs_server_map.pop(mover_name)

        self.cifs_server_map[mover_name] = dict()

        for item in response['objects']:
            self.cifs_server_map[mover_name][item['compName'].lower()] = item

        return constants.STATUS_OK, self.cifs_server_map[mover_name]

    def get(self, name, mover_name, is_vdm=True, force=False):
        # name is compName
        name = name.lower()

        if (mover_name in self.cifs_server_map and
                name in self.cifs_server_map[mover_name]) and not force:
            return constants.STATUS_OK, self.cifs_server_map[mover_name][name]

        self.get_all(mover_name, is_vdm)

        if mover_name in self.cifs_server_map:
            for compName, server in self.cifs_server_map[mover_name].items():
                if name == compName:
                    return constants.STATUS_OK, server

        return constants.STATUS_NOT_FOUND, None

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def modify(self, server_args):
        """Make CIFS server join or un-join the domain.

        :param server_args: Dictionary for CIFS server modification
            name: CIFS server name instead of compName
            join_domain: True for joining the domain, false for un-joining
            user_name: User name under which the domain is joined
            password: Password associated with the user name
            mover_name: mover or VDM name
            is_vdm: Boolean to indicate mover or VDM
        :raises exception.EMCVnxXMLAPIError: if modification fails.
        """
        name = server_args['name']
        join_domain = server_args['join_domain']
        user_name = server_args['user_name']
        password = server_args['password']
        mover_name = server_args['mover_name']

        if 'is_vdm' in server_args.keys():
            is_vdm = server_args['is_vdm']
        else:
            is_vdm = True

        mover_id = self._get_mover_id(mover_name, is_vdm)

        if self.xml_retry:
            self.xml_retry = False

        request = self._build_task_package(
            self.elt_maker.ModifyW2KCifsServer(
                self.elt_maker.DomainSetting(
                    joinDomain='true' if join_domain else 'false',
                    password=password,
                    userName=user_name,
                ),
                mover=mover_id,
                moverIdIsVdm='true' if is_vdm else 'false',
                name=name
            )
        )

        response = self._send_request(request)

        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif self._ignore_modification_error(response, join_domain):
            return
        elif constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to modify CIFS server %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name,
                        'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

    def _ignore_modification_error(self, response, join_domain):
        if self._response_validation(response, constants.MSG_JOIN_DOMAIN):
            return join_domain
        elif self._response_validation(response, constants.MSG_UNJOIN_DOMAIN):
            return not join_domain

        return False

    def delete(self, computer_name, mover_name, is_vdm=True):
        try:
            status, out = self.get(
                computer_name.lower(), mover_name, is_vdm, self.xml_retry)
            if constants.STATUS_NOT_FOUND == status:
                LOG.warning(_LW("CIFS server %(name)s on mover %(mover_name)s "
                                "not found. Skip the deletion."),
                            {'name': computer_name, 'mover_name': mover_name})
                return
        except exception.EMCVnxXMLAPIError:
            LOG.warning(_LW("CIFS server %(name)s on mover %(mover_name)s "
                            "not found. Skip the deletion."),
                        {'name': computer_name, 'mover_name': mover_name})
            return

        server_name = out['name']

        mover_id = self._get_mover_id(mover_name, is_vdm)

        request = self._build_task_package(
            self.elt_maker.DeleteCifsServer(
                mover=mover_id,
                moverIdIsVdm='true' if is_vdm else 'false',
                name=server_name
            )
        )

        response = self._send_request(request)

        if constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to delete CIFS server %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': computer_name, 'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        self.cifs_server_map[mover_name].pop(computer_name)

@vnx_utils.decorate_all_methods(vnx_utils.log_enter_exit,
                                debug_only=True)
class CIFSShare(StorageObject):
    def __init__(self, conn, elt_maker, xml_parser, manager):
        super(CIFSShare, self).__init__(conn, elt_maker, xml_parser, manager)
        self.cifs_share_map = dict()

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def create(self, name, server_name, mover_name, is_vdm=True):
        mover_id = self._get_mover_id(mover_name, is_vdm)

        if self.xml_retry:
            self.xml_retry = False

        share_path = '/' + name

        request = self._build_task_package(
            self.elt_maker.NewCifsShare(
                self.elt_maker.MoverOrVdm(
                    mover=mover_id,
                    moverIdIsVdm='true' if is_vdm else 'false'
                ),
                self.elt_maker.CifsServers(self.elt_maker.li(server_name)),
                name=name,
                path=share_path
            )
        )

        response = self._send_request(request)

        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to create file share %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

    def get(self, name):
        if name not in self.cifs_share_map:
            request = self._build_query_package(
                self.elt_maker.CifsShareQueryParams(name=name)
            )

            response = self._send_request(request)

            if constants.STATUS_OK != response['maxSeverity']:
                return response['maxSeverity'], response['problems']

            if not response['objects']:
                return constants.STATUS_NOT_FOUND, None

            self.cifs_share_map[name] = response['objects'][0]

        return constants.STATUS_OK, self.cifs_share_map[name]

    @utils.retry(exception.EMCVnxInvalidMoverID)
    def delete(self, name, mover_name, is_vdm=True):
        status, out = self.get(name)
        if constants.STATUS_NOT_FOUND == status:
            LOG.warning(_LW("CIFS share %s not found. Skip the deletion."),
                        name)
            return
        elif constants.STATUS_OK != status:
            message = (_("Failed to get CIFS share by name %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': out})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        mover_id = self._get_mover_id(mover_name, is_vdm)

        if self.xml_retry:
            self.xml_retry = False

        netbios_names = self.cifs_share_map[name]['CifsServers']

        request = self._build_task_package(
            self.elt_maker.DeleteCifsShare(
                self.elt_maker.CifsServers(*map(lambda a: self.elt_maker.li(a),
                                                netbios_names)),
                mover=mover_id,
                moverIdIsVdm='true' if is_vdm else 'false',
                name=name
            )
        )

        response = self._send_request(request)

        if (self._response_validation(response,
                                      constants.MSG_INVALID_MOVER_ID) and
                not self.xml_retry):
            self.xml_retry = True
            raise exception.EMCVnxInvalidMoverID(id=mover_id)
        elif constants.STATUS_OK != response['maxSeverity']:
            message = (_("Failed to delete file system %(name)s. "
                         "Reason: %(err)s.") %
                       {'name': name, 'err': response['problems']})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        self.cifs_share_map.pop(name)

    def disable_share_access(self, share_name, mover_name):
        cmd_str = 'sharesd %s set noaccess' % share_name
        disable_access = [
            'env', 'NAS_DB=/nas', '/nas/bin/.server_config', mover_name,
            '-v', "%s" % cmd_str,
        ]

        try:
            self._execute_cmd(disable_access, check_exit_code=True)
        except processutils.ProcessExecutionError as expt:
            message = (_('Failed to disable the access to CIFS share '
                         '%(name)s. Reason: %(err)s.') %
                       {'name': share_name, 'err': expt})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

    def allow_share_access(self, mover_name, share_name, user_name, domain,
                           access=constants.CIFS_ACL_FULLCONTROL):
        account = user_name + "@" + domain
        allow_str = ('sharesd %(share_name)s grant %(account)s=%(access)s'
                     % {'share_name': share_name,
                        'account': account,
                        'access': access})

        allow_access = [
            'env', 'NAS_DB=/nas', '/nas/bin/.server_config', mover_name,
            '-v', "%s" % allow_str,
        ]

        try:
            self._execute_cmd(allow_access, check_exit_code=True)
        except processutils.ProcessExecutionError as expt:
            dup_msg = re.compile(r'ACE for %(domain)s\\%(user)s unchanged' %
                                 {'domain': domain, 'user': user_name}, re.I)
            if re.search(dup_msg, expt.stdout):
                LOG.warning(_LW("Duplicate access control entry, "
                                "skipping allow..."))
            else:
                message = (_('Failed to allow the access %(access)s to '
                             'CIFS share %(name)s. Reason: %(err)s.') %
                           {'access': access, 'name': share_name, 'err': expt})
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)

    def deny_share_access(self, mover_name, share_name, user_name, domain,
                          access=constants.CIFS_ACL_FULLCONTROL):
        account = user_name + "@" + domain
        revoke_str = ('sharesd %(share_name)s revoke %(account)s=%(access)s'
                      % {'share_name': share_name,
                         'account': account,
                         'access': access})

        allow_access = [
            'env', 'NAS_DB=/nas', '/nas/bin/.server_config', mover_name,
            '-v', "%s" % revoke_str,
        ]
        try:
            self._execute_cmd(allow_access, check_exit_code=True)
        except processutils.ProcessExecutionError as expt:
            not_found_msg = re.compile(
                r'No ACE found for %(domain)s\\%(user)s'
                % {'domain': domain, 'user': user_name}, re.I)
            user_err_msg = re.compile(
                r'Cannot get mapping for %(domain)s\\%(user)s'
                % {'domain': domain, 'user': user_name}, re.I)

            if re.search(not_found_msg, expt.stdout):
                LOG.warning(_LW("No access control entry found, "
                                "skipping deny..."))
            elif re.search(user_err_msg, expt.stdout):
                LOG.warning(_LW("User not found on domain, skipping deny..."))
            else:
                message = (_('Failed to deny the access %(access)s to '
                             'CIFS share %(name)s. Reason: %(err)s.') %
                           {'access': access, 'name': share_name, 'err': expt})
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)

    def get_share_access(self, mover_name, share_name):
        get_str = 'sharesd %s dump' % share_name
        get_access = [
            'env', 'NAS_DB=/nas', '/nas/bin/.server_config', mover_name,
            '-v', "%s" % get_str,
        ]

        try:
            out, err = self._execute_cmd(get_access, check_exit_code=True)
        except processutils.ProcessExecutionError:
            msg = _('Failed to get access list of CIFS share %s.') % share_name
            LOG.exception(msg)
            raise exception.EMCVnxXMLAPIError(err=msg)

        ret = {}
        name_pattern = re.compile(r"Unix user '(.+?)'")
        access_pattern = re.compile(r"ALLOWED:(.+?):")

        name = None
        for line in out.splitlines():
            if name is None:
                names = name_pattern.findall(line)
                if names:
                    name = names[0].lower()
            else:
                accesses = access_pattern.findall(line)
                if accesses:
                    ret[name] = accesses[0].lower()
                    name = None
        return ret

    def clear_share_access(self, mover_name, share_name, domain,
                           white_list_users):
        existing_users = self.get_share_access(mover_name, share_name)
        white_list_users_set = set(user.lower() for user in white_list_users)
        users_to_remove = set(existing_users.keys()) - white_list_users_set
        for user in users_to_remove:
            self.deny_share_access(mover_name, share_name, user, domain,
                                   existing_users[user])
        return users_to_remove

@vnx_utils.decorate_all_methods(vnx_utils.log_enter_exit,
                                debug_only=True)
class NFSShare(StorageObject):
    def __init__(self, conn, elt_maker, xml_parser, manager):
        super(NFSShare, self).__init__(conn, elt_maker, xml_parser, manager)
        self.nfs_share_map = {}

    def create(self, name, mover_name):
        share_path = '/' + name
        create_nfs_share_cmd = [
            'env', 'NAS_DB=/nas', '/nas/bin/server_export', mover_name,
            '-option', 'access=-0.0.0.0/0.0.0.0',
            share_path,
        ]

        try:
            self._execute_cmd(create_nfs_share_cmd, check_exit_code=True)
        except processutils.ProcessExecutionError as expt:
            message = (_('Failed to create NFS share %(name)s on mover '
                         '%(mover_name)s. Reason: %(err)s.') %
                       {'name': name, 'mover_name': mover_name, 'err': expt})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

    def delete(self, name, mover_name):
        path = '/' + name

        status, out = self.get(name, mover_name)
        if constants.STATUS_NOT_FOUND == status:
            LOG.warning(_LW("NFS share %s not found. Skip the deletion."),
                        path)
            return

        delete_nfs_share_cmd = [
            'env', 'NAS_DB=/nas', '/nas/bin/server_export', mover_name,
            '-unexport',
            '-perm',
            path,
        ]

        try:
            self._execute_cmd(delete_nfs_share_cmd, check_exit_code=True)
        except processutils.ProcessExecutionError as expt:
            message = (_('Failed to delete NFS share %(name)s on '
                         '%(mover_name)s. Reason: %(err)s.') %
                       {'name': name, 'mover_name': mover_name, 'err': expt})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        self.nfs_share_map.pop(name)

    def get(self, name, mover_name, force=False, check_exit_code=False):
        if name in self.nfs_share_map and not force:
            return constants.STATUS_OK, self.nfs_share_map[name]

        path = '/' + name

        nfs_share = {
            "mover_name": '',
            "path": '',
            'AccessHosts': [],
            'RwHosts': [],
            'RoHosts': [],
            'RootHosts': [],
            'readOnly': '',
        }

        nfs_query_cmd = [
            'env', 'NAS_DB=/nas', '/nas/bin/server_export', mover_name,
            '-P', 'nfs',
            '-list', path,
        ]

        try:
            out, err = self._execute_cmd(nfs_query_cmd,
                                         check_exit_code=check_exit_code)
        except processutils.ProcessExecutionError as expt:
            dup_msg = (r'%(mover_name)s : No such file or directory' %
                       {'mover_name': mover_name})
            if re.search(dup_msg, expt.stdout):
                LOG.warning(_LW("NFS share %s not found."), name)
                return constants.STATUS_NOT_FOUND, None
            else:
                message = (_('Failed to list NFS share %(name)s on '
                             '%(mover_name)s. Reason: %(err)s.') %
                           {'name': name,
                            'mover_name': mover_name,
                            'err': expt})
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)

        re_exports = '%s\s*:\s*\nexport\s*(.*)\n' % mover_name
        m = re.search(re_exports, out)
        if m is not None:
            nfs_share['path'] = path
            nfs_share['mover_name'] = mover_name
            export = m.group(1)
            fields = export.split(" ")
            for field in fields:
                field = field.strip()
                if field.startswith('rw='):
                    nfs_share['RwHosts'] = field[3:].split(":")
                elif field.startswith('access='):
                    nfs_share['AccessHosts'] = field[7:].split(":")
                elif field.startswith('root='):
                    nfs_share['RootHosts'] = field[5:].split(":")
                elif field.startswith('ro='):
                    nfs_share['RoHosts'] = field[3:].split(":")

            self.nfs_share_map[name] = nfs_share
        else:
            return constants.STATUS_NOT_FOUND, None

        return constants.STATUS_OK, self.nfs_share_map[name]

    def allow_share_access(self, share_name, host_ip, mover_name,
                           access_level=const.ACCESS_LEVEL_RW):
        @utils.synchronized('emc-shareaccess-' + share_name)
        def do_allow_access(share_name, host_ip, mover_name, access_level):
            status, share = self.get(share_name, mover_name)
            if constants.STATUS_NOT_FOUND == status:
                message = (_('NFS share %s not found.') % share_name)
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)

            changed = False
            rwhosts = share['RwHosts']
            rohosts = share['RoHosts']
            if access_level == const.ACCESS_LEVEL_RW:
                if host_ip not in rwhosts:
                    rwhosts.append(host_ip)
                    changed = True
                if host_ip in rohosts:
                    rohosts.remove(host_ip)
                    changed = True
            if access_level == const.ACCESS_LEVEL_RO:
                if host_ip not in rohosts:
                    rohosts.append(host_ip)
                    changed = True
                if host_ip in rwhosts:
                    rwhosts.remove(host_ip)
                    changed = True

            roothosts = share['RootHosts']
            if host_ip not in roothosts:
                roothosts.append(host_ip)
                changed = True
            accesshosts = share['AccessHosts']
            if host_ip not in accesshosts:
                accesshosts.append(host_ip)
                changed = True

            if not changed:
                LOG.debug("%(host)s is already in access list of share "
                          "%(name)s.", {'host': host_ip, 'name': share_name})
            else:
                path = '/' + share_name
                self._set_share_access(path,
                                       mover_name,
                                       rwhosts,
                                       rohosts,
                                       roothosts,
                                       accesshosts)

                # Update self.nfs_share_map
                self.get(share_name, mover_name, force=True,
                         check_exit_code=True)

        do_allow_access(share_name, host_ip, mover_name, access_level)

    def deny_share_access(self, share_name, host_ip, mover_name):

        @utils.synchronized('emc-shareaccess-' + share_name)
        def do_deny_access(share_name, host_ip, mover_name):
            status, share = self.get(share_name, mover_name)
            if constants.STATUS_OK != status:
                message = (_('Query nfs share %(path)s failed. '
                             'Reason %(err)s.') %
                           {'path': share_name, 'err': share})
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)

            changed = False
            rwhosts = set(share['RwHosts'])
            if host_ip in rwhosts:
                rwhosts.remove(host_ip)
                changed = True
            roothosts = set(share['RootHosts'])
            if host_ip in roothosts:
                roothosts.remove(host_ip)
                changed = True
            accesshosts = set(share['AccessHosts'])
            if host_ip in accesshosts:
                accesshosts.remove(host_ip)
                changed = True
            rohosts = set(share['RoHosts'])
            if host_ip in rohosts:
                rohosts.remove(host_ip)
                changed = True
            if not changed:
                LOG.debug("%(host)s is already in access list of share "
                          "%(name)s.", {'host': host_ip, 'name': share_name})
            else:
                path = '/' + share_name
                self._set_share_access(path,
                                       mover_name,
                                       rwhosts,
                                       rohosts,
                                       roothosts,
                                       accesshosts)

                # Update self.nfs_share_map
                self.get(share_name, mover_name, force=True,
                         check_exit_code=True)

        do_deny_access(share_name, host_ip, mover_name)

    def clear_share_access(self, share_name, mover_name, white_list_hosts):
        @utils.synchronized('emc-shareaccess-' + share_name)
        def do_clear_access(share_name, mover_name, white_list_hosts):
            def hosts_to_remove(orig_list):
                if white_list_hosts is None:
                    ret = set()
                else:
                    ret = set(white_list_hosts).intersection(set(orig_list))
                return ret

            status, share = self.get(share_name, mover_name)
            if constants.STATUS_OK != status:
                message = (_('Query nfs share %(path)s failed. '
                             'Reason %(err)s.') %
                           {'path': share_name, 'err': status})
                raise exception.EMCVnxXMLAPIError(err=message)

            self._set_share_access('/' + share_name,
                                   mover_name,
                                   hosts_to_remove(share['RwHosts']),
                                   hosts_to_remove(share['RoHosts']),
                                   hosts_to_remove(share['RootHosts']),
                                   hosts_to_remove(share['AccessHosts']))

            # Update self.nfs_share_map
            self.get(share_name, mover_name, force=True,
                     check_exit_code=True)

        do_clear_access(share_name, mover_name, white_list_hosts)

    def _set_share_access(self, path, mover_name, rw_hosts, ro_hosts,
                          root_hosts, access_hosts):

        if access_hosts is None:
            access_hosts = set()

        if '-0.0.0.0/0.0.0.0' not in access_hosts:
            access_hosts.add('-0.0.0.0/0.0.0.0')

        access_str = ('access=%(access)s'
                      % {'access': ':'.join(access_hosts)})
        if root_hosts:
            access_str += (',root=%(root)s' % {'root': ':'.join(root_hosts)})
        if rw_hosts:
            access_str += ',rw=%(rw)s' % {'rw': ':'.join(rw_hosts)}
        if ro_hosts:
            access_str += ',ro=%(ro)s' % {'ro': ':'.join(ro_hosts)}

        set_nfs_share_access_cmd = [
            'env', 'NAS_DB=/nas', '/nas/bin/server_export', mover_name,
            '-ignore',
            '-option', access_str,
            path,
        ]

        try:
            self._execute_cmd(set_nfs_share_access_cmd, check_exit_code=True)
        except processutils.ProcessExecutionError as expt:
            message = (_('Failed to set NFS share %(name)s access on '
                         '%(mover_name)s. Reason: %(err)s.') %
                       {'name': path[1:],
                        'mover_name': mover_name,
                        'err': expt})
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

redpajama_set_name: RedPajamaGithub


This past Saturday, we held two alumni events on campus, which made for a fun day.
The day started off with a panel discussion, led by Director of College Counseling Tim Cheney and featuring nine young alumni. Collectively, they represented eight different colleges and universities: Yale, Wesleyan, Northeastern, Smith, Connecticut College, Hobart William Smith, Davidson and Boston College.
As students in either their first or second years at college, the alumni came back to speak with our current juniors and seniors about their experiences, particularly with college selection process. The group— Henry Lombino, Brendan Hellweg, Cameron Hill, Elyssa Katz, Brittany Collins, Hannah King, Loren Po, Marie Innarelli, Jenna Phelan—spoke for almost two hours on a variety of college-related topics.
The workload doesn't get easier in college but Williston does a great job of preparing you so you know what to do and how to do it.
College doesn't offer the same built-in community available at Williston, so you have to make an effort to get to know your advisor and professors. Luckily, Williston has given you the ability and confidence to do that!
Don't box yourself in with your choices. Look at a wide range of schools since you never know what might ultimately attract you. You don't want to have any regrets!
When you are writing your college essays, be yourself and speak from the heart.
Your college experience is what you make of it no matter where you ultimately go. You can be as involved or as disengaged as you choose to be. The choice is yours.
Attention, sophomores! When you are selecting classes for your junior year at Williston be sure to consult with college counseling on your long range goals, which can help dictate which classes to take.
In the afternoon, following the boys varsity basketball game versus Deerfield (a rousing 25-point victory), eight alumni and one faculty member took on the varsity players in a jovial, albeit shortened game.
The Class of 1991 was well represented and Malcolm Brown even drove out from Boston just to catch the Deerfield game. Behind the outstanding coaching of Mike Jackson '90 (okay, so it did take him a while to realize everyone had the number 175 on their backs and that it stood for the school's 175th anniversary, but still…) and the scoring touch of Ben Harlee '91—after travelling all the way up from Maryland for the first time since he graduated—the alumni were able to keep the game close throughout.
Trailing by five with less than a minute to go, the varsity put together a run of baskets and the game finished deadlocked. The alumni should have called it quits then, but elected to play a three-minute overtime. The young legs proved too much for the old guard as the varsity pulled away for a 61-57 victory.
Following the game, Ben Harlee '91 was chosen as the winner of the Tiger Craig Award, given to the MVP of the game. There was a reception for the alumni and the current players in the lobby of the athletic center. There were even special basketball cookies.
Many thanks to Mike Jackson '90, Reid Sterrett '91, David Mederrick '91, Ben Harlee '91, Steve Hoyt '95, Paul McNeil '01, Will McLaughlin '05, Sam Slezek '12 and faculty member Jacob Rivers for coming out to play.
Thank you to Monique Conroy and Brittany Weiss '07 for running the clock as well as Michael Shelton and his entire coaching staff and team for all they did. Next year we hope to have more alumni back!


June 28, 2017 • We visited a libertarian summer paradise. What we found: People paying in gold. Exotic bacon dishes. A nine-year-old selling alcohol.
June 22, 2017 • President Trump's budget proposal assumes the U.S. economy will grow at 3 percent a year. Most economists call that improbable. We try to figure out what it would take to hit the magic 3 percent.
Episode 778: What the Falcon's Up With Qatar?
June 16, 2017 • Qatar was on top of the world. Seemingly overnight, it became a pariah. On this episode, we drill into a rift years in the making: It's a tale of falcons, kidnapping, and a glowing Saudi Arabian orb.
June 7, 2017 • The president's budget promises 3% growth. Is that doable? Yes, but he won't like what it would take.
May 11, 2017 • Economists don't look for jobs in the same way the rest of us do. They are way too rational. They have a system that looks a lot like speed dating.
May 5, 2017 • We visit a job market created by economists, for economists. It's a hyper-efficient, optimized system, tested by game theorists, tweaked by a Nobel Prize winner, but it requires comfortable shoes.
April 12, 2017 • One man figured out how to reproduce the magic of an Irish pub, and ship it in a container to anywhere in the world.
April 7, 2017 • NPR's Planet Money team explores why Irish bars look so similar all over the world and what happens when you take an authentic national experience and turn it into an export.
April 5, 2017 • The tricks and mind games tax collectors use to get people to pay up.
March 9, 2017 • Each year, millions upon millions of honey bees go on a cross country road trip to make the California almond harvest possible.
February 10, 2017 • President Trump has made American manufacturing a central concern. Can a complicated approach called a border adjustment tax make it happen? Planet Money looks at how it's supposed to work.
November 10, 2016 • There are two possible versions of a Trump tax plan. He hasn't confirmed which one he plans to pursue. There's a $1.5 trillion difference between the two of them over 10 years.
November 2, 2016 • Venezuela has one of the worst economies in the world with food shortages and massive inflation. NPR's Planet Money team explains how it got so bad.
October 14, 2016 • Planet Money digs into the complex economics of international postage. When we send a letter to a foreign country, how should the stamp money be shared with the people delivering the letter?


Published 04/24/2019 06:23:52 pm at 04/24/2019 06:23:52 pm in Kobalt Jobsite Tool Box.
kobalt jobsite tool box kobalt 24 in w x 48 in l x 28 in steel jobsite box kobalt tools and outdoor power equipment.
kobalt full size contractor truck tool box from lowes tools in kobalt full size contractor truck tool box from lowes tools in action power tool reviews, elegant kobalt tool box locking mechanism kobalt tool box locking mechanism new kobalt tool box drawer of elegant, kobalt radio toolbox husky drawer steel portable job site tool box kobalt radio toolbox tool toolbox foam home depot kobalt radio toolbox , kobalt in stainless steel tool chest cabinet my hobby room kobalt in stainless steel tool chest cabinet, tools hardware buy power tools hand tools drills tool kits kobalt piece standard sae and metric mechanics tool set na no case, tool storage costco whalen piece workbench cabinet set, tool storage kobalt tool storage kobalt tool storage pictures, kobalt zerust in black plastic lockable tool box amazoncom kobalt zerust in black plastic lockable tool box,, best portable jobsite table saw shootout pro tool reviews best portable jobsite table saw shootout featured image, dewalt super heavy duty jobsite tool boxes dewalt dxjb inch jobsite box.


text:
What Happened in Sri Lanka? Here's What You Need to Know
These attacks come at a precarious political moment.
by Kate Cronin-Furman, The Washington Post's Monkey Cage, April 23, 2019
Police officers survey graves prepared for the victims of the Easter Sunday attacks in Sri Lanka. (Atul Loke/Getty Images)
Bombs ripped through three churches and four hotels in a series of attacks in Sri Lanka on Sunday morning. The casualty count currently stands at more than 300 dead and more than 500 injured. What do we know about the attacks, and their impact?
For many Sri Lankans, the bombings brought back the trauma of the country's 26-year-long civil war between government forces and the Liberation Tigers of Tamil Eelam (LTTE), commonly known as the Tamil Tigers. For some, it was the ever-present fear of suicide attacks; for others, the terror of checkpoints and an unfettered security state.
On Monday, the Sri Lankan government blamed National Thowheed Jamaath (NTJ), a homegrown Muslim extremist group. The attribution came as a surprise to both domestic and international analysts, who had assumed that the scale and level of coordination required by the attacks indicated the direct involvement of a foreign terrorist group. Early Tuesday, the Islamic State claimed the attacks, appearing to confirm this suspicion.
Why were Catholic churches a target?
The inclusion of Catholic churches as targets was another factor that led experts to speculate about foreign involvement. While some in the West were quick to interpret the attacks through the lens of Muslim-Christian clashes elsewhere, this is not a salient divide in Sri Lanka.
Identity in Sri Lanka is complex and does not map cleanly onto familiar frameworks from other contexts. The island's small Christian population — most of whom are Catholic — hails from both the majority Sinhalese and minority Tamil ethnicities. Muslims, while generally Tamil-speaking, identify as a distinct ethnic group from Tamils.
Both communities have been targeted by Sinhala-Buddhist extremists and marginalized by the state. There was also terrible violence between the Muslim and Tamil communities during the war, including the expulsion of thousands of Muslims from LTTE-controlled territory. Muslims and Christians, however, have not previously come into significant conflict with each other.
[Sri Lanka's bloody civil war finally ended. But moving on from the past is not easy.]
Does Sri Lanka have a history of Muslim extremism?
During the five years that the autocratic regime of President Mahinda Rajapaksa remained in powerafter the end of the war in 2009, militant Buddhist organizations were allowed to persecute Muslims with impunity, including whipping up riots in 2014 that left four people dead and thousands displaced. Just last year, inflammatory rhetoric from extremist monks and politicians, along with anti-Muslim propaganda spread on social media, fueled violent riots in multiple locations.
Sri Lanka's Muslims have remained peaceful in the face of escalating hate speech and violence against them. Nevertheless, there have been rumors of radicalization in the community since 2009, tied to the increasing adoption of the burqa by Sri Lankan Muslim women and assumptions about the "Arab attitudes" that migrant workers brought home when returning from the Persian Gulf. Notably, Muslim leaders claimed on Monday that they specifically warned government officials about the NTJ three years ago.
Was there any warning of these attacks?
The Sri Lankan government acknowledged that it had also received a highly specific warning earlier this month of potential attacks on Catholic churches from U.S. and Indian intelligence officials. Sri Lankan officials are now engaged in a round of recriminations that highlights the divisions within Sri Lanka's coalition government. For those who fear an uptick in human rights abuses in the name of counterterrorism, Defense Secretary Hemasiri Fernando on Monday set off alarm bells with his claimthat even with full information, the government could not have acted to prevent the attacks, due to democratic restrictions on its emergency powers.
How is the government responding?
In a controversial move, the government quickly shut down social media on Sunday to contain the spread of rumors about the attacks. On Monday, President Maithripala Sirisena declared a state of emergency and gave the military broad powers to arrest and detain — a move that dismayed human rights activists and members of the Muslim and Tamil communities.
[Sri Lanka's surprise political transition]
Sri Lanka's post-Rajapaksa government promised the international community in 2015 that it would vet the security forces, removing those who had committed wartime abuses, and repeal the oppressive Prevention of Terror Act. It has done neither. Instead, northeastern Sri Lanka (where most Tamils and Muslims live) remains heavily militarized, ostensibly to guard against LTTE resurgence. Given the military's overwhelmingly Sinhala-Buddhist makeup, and the presence of alleged war criminals within both the rank-and-file and high command, granting additional license to the security sector could pose a serious threat to minority communities.
What does this mean for the upcoming presidential election?
Sunday's devastating attacks suggest the arrival of a new type of violence to Sri Lanka. But their impact will be filtered through the island's complex history of conflict and state repression. These events come at a precarious political moment. Sri Lankans will elect a president sometime in the next seven months. The current government narrowly survived an attempted soft coup by former leader Rajapaksa last fall. Although his rule was characterized by Sinhala-Buddhist supremacism, rampant human rights abuses and corruption, he remains the most popular politician in the country, largely because Sinhala-Buddhists credit him personally with the defeat of the LTTE in 2009.
Rajapaksa is constitutionally barred from running for president again, but his brother Gotabaya, who masterminded the end of the civil war as defense secretary, can. The Rajapaksas' bid to be restored to office, tied as it is to the appeal of their chauvinistic, strongman politics, will only benefit from a national security crisis. They will undoubtedly make political hay out of their "victory over terror" and the current government's failure to prevent Sunday's attacks.
Kate Cronin-Furman is an assistant professor in the Department of Political Science at University College London.
https://www.washingtonpost.com/politics/2019/04/23/what-happened-sri-lanka-heres-what-you-need-know/?utm_term=.60cc3dbcbcb2
ICES: Sex Ratio and Vulnerability in Northern and Eastern Provinces in Sri Lanka
Posted April 24th, 2019 .
Filed under Demography, Government, Human Rights, Military, Politics.

redpajama_set_name: RedPajamaCommonCrawl


text:
Aid, Business, Foreign Aid, Global Poverty
Private Businesses Speak Up on Cutting of Foreign Aid Budget
Shortly after taking office in 2017, the Trump administration released its proposed budget cuts for FY 2018. Among the proposed cuts was a 31 percent decrease in the foreign aid budget, which includes cutting funding to the United Nations, the World Bank and other diplomatic institutions. With the already low foreign aid budget potentially decreasing, impoverished nations still do have dependable allies in the U.S. other than the government.
After the release of the proposed foreign aid budget cuts, American business leaders from companies such as Walmart, Nike and Coca-Cola signed a letter to Secretary of State Rex Tillerson urging him to reevaluate the proposed cuts. The May 22 letter highlights the fact that 95 percent of the world's consumers live outside of the U.S. and that "eleven of America's top fifteen export markets are in countries that have been recipients of U.S. foreign assistance."
Not only are private businesses lobbying the government to take responsibility when it comes to stepping up foreign aid policy, but they have also stepped up in their own funding to developing countries and their economies.
According to The Guardian, private sectors have invested money to developing countries at a faster rate than government foreign aid; they receive 27 percent more foreign business investments than development aid. The investments, which have increased nine-fold since the year 2000, are starting to bring countries out of poverty with increasing business capital flow into their economies.
As businesses see more market potential in countries where citizens could come out of poverty and would have more money to spend on luxury goods, they have an incentive to invest in development.
For example, The Coca-Cola Company and The Bill and Melinda Gates Foundation teamed up with TechnoServe to invest in eastern African farmers to produce fruit for their Minute Maid drinks. As a result, local farmers were educated on how to produce better crop yields that would benefit both Coca Cola's production and the farmers' incomes. This venture was titled Project Nurture and increased the incomes of 54,000 farmers.
"We are committed to working with you in your role as Secretary of State to share our perspectives on the importance of U.S. international affairs programs to boost our exports abroad and our jobs here at home," read the May 22 letter to Tillerson. Whether the proposed 31 percent foreign aid budget cut goes into effect or not, private businesses will continue to invest in foreign markets and give aid to developing countries. It is also important to note that, in budgetary matters, Congress holds the power of the purse. While the President is able to propose budgetary cuts, they must be approved by Congress before going into effect.
– Vicente Vera
Photo: Flickr
July 4, 2017 /by Borgen Project
Tags: Budget, Foreign Aid, Foreign Aid Budget, Private Businesses
https://borgenproject.org/wp-content/uploads/The_Borgen_Project_Logo_small.jpg 0 0 Borgen Project https://borgenproject.org/wp-content/uploads/The_Borgen_Project_Logo_small.jpg Borgen Project2017-07-04 07:30:532019-10-29 10:27:07Private Businesses Speak Up on Cutting of Foreign Aid Budget
Facts and Figures About Cuba A Snapshot of the Current State of Poverty in Luxembourg


Breaking News: Bloomberg reported on September 11 that a US Judge has ruled that ICOs are covered under US securities laws, handing US regulators a legal victory in their effort to regulate the burgeoning ICO market.
IPOs (Initial Public Offering) and ICOs (Initial Coin Offering) are basically the same thing. When a company goes public and sell shares on the stock exchange for the first time IPO is created. This is the same with ICOs but it is a digital asset representing the ownership of a company. ICOs have been created on the blockchain which is decentralized and transparent, secure and tamper-free. There are no middleman/banks involved.
Almost all ICOs are a sort of crowdfunding on the blockchain but there is a difference. ICO is where an enterprise or project has its own tokens or coins (like shares). It is to produce and procure funds. These tokens and coins will then be listed on the Cryptographic Currency Exchange, which uses the blockchain technology to do that. The creation of ICO is also much cheaper than an IPO.
Bitcoin paved the way for other cryptocurrencies. Altcoins (Alternative Coins) are cryptocurrencies which were launched after Bitcoin and are similar to Bitcoin. Both of them need the blockchain to work on. Altcoins are also peer-to-peer like Bitcoin which means, each computer have notes on and act as a server. It also involves mining (the process by which transactions are verified and added on the blockchain). Altcoins are all cryptocurrencies which are not Bitcoin, like Litecoin, Ethereum, Cardano and Ripple. Many altcoins are trying to target the limitations of Bitcoin and come up with newer versions and better functionality.
Altcoin crowdfunding is now becoming very popular and mainstream for raising capital for all types of investments. It brings together many individuals who want to invest money in companies and projects. Crowdfunding makes it possible to launch projects and sell their projects online, with little cost. Many startup companies have ICOs to raise money and to avoid the standard capital-raising process through banks.
With pre-mined coins, you can get involved with the blockchain. This method is a unique way of crowdfunding using alternative coins. The coins are sold in an initial coin offering or what we also call ICO, to the public. Investors can now purchase coins with the expectation that prices will increase at some point.
For more advice please feel free to contact me on 081 269 3916 - for a Consultation.


text:
WHY DO COUNTRIES RACE ON MARS? ... AN IPA EXPERT ANSWERS
Previous Article A shocking study of the Earth's atmosphere
Next Article NASA delays the launch of the James Webb telescope again
2020 is the Year of Mars. The United Arab Emirates and China have successfully launched missions to Mars, and the United States is also planning to launch their missions to Mars.
You may wonder why many countries launch missions to Mars!
Dr. Ashraf Tadros, former head of the astronomy department at the National Institute of Astronomical and Geophysical Research, said, "We must know that the rocky planets are Mercury, Venus, Earth, and Mars only. After the moon that states are racing to discover and reach, which is the second rocky planet after the Earth on which it can stand and live (under certain conditions) "
He added through his Facebook page, "As for Venus, it is the hottest planet ever, and they call it the hell of the solar system due to the intensity of global warming in it, and Mercury is very close to the sun and its speed in its orbit makes its day longer than its year! Or the formation of the first cell of a human society there, but traveling to Mars needs approximately seven months and the journey to it is a journey that goes only without return, in which a person travels a distance of 493 million km.
He continued: "Therefore, all necessary measures and measures reached by the science must be taken to ensure safety or at least to ensure life for the longest possible period. Hence, the race of countries to explore the depths of Mars such as the United States, Russia, the European Space Agency, India, and China (very soon). May there be hope for humankind to survive or complete life there if that is not possible on the ground! "


text:
Astronomia
 7215 Gerhard – asteroide della fascia principale

Onomastica
 Gerhard – variante del nome proprio di persona Gerardo

Persone
 Gerhard – fumettista e illustratore canadese
 Eduard Gerhard – archeologo tedesco
 Ephraim Gerhard – giurista e storico della filosofia tedesco
 Friedrich Gerhard – cavaliere tedesco
 Hubert Gerhard – scultore olandese
 Nina Gerhard – cantante, cantautrice e conduttrice radiofonica tedesca

redpajama_set_name: RedPajamaWikipedia