Esempio n. 1
0
def _run_prep_vol_to_cluster_script(fs):
    # TODO: move to run
    # TODO: handle the cases where fs.get_winid is None
    from smb import PROJECTROOT
    from os import path
    vol_to_cluster_script = path.realpath(
        path.join(PROJECTROOT, 'src', 'smb', 'cli', 'powershell',
                  'prep_vol_to_cluster.ps1'))
    if fs.get_winid() is None:
        log_n_raise(logger,
                    "Can't prepare volume {}".format(fs.get_name()),
                    level=ERROR,
                    color="red")
    try:
        cmd = execute_assert_success([
            'powershell', '.', '"' + vol_to_cluster_script.replace('\\', '/') +
            '"' + " -DiskNumber {} -MountPath {}".format(
                fs.get_winid(), fs.get_mountpoint())
        ])
    except:
        error = sys.exc_info()[1]
        log_n_raise(logger,
                    "{} failed with error: {}".format(vol_to_cluster_script,
                                                      error),
                    disable_print=True)
Esempio n. 2
0
def exit_if_vol_not_mapped(volume):
    ''' receives an infinisdk volume type and checks if mapped'''
    def _is_vol_mapped(volume_serial, timeout=3):
        from time import sleep
        for n in range(0, timeout):
            execute_assert_success(['powershell', '-c', 'Update-HostStorageCache'])
            try:
                execute_assert_success(['powershell', '-c', 'Get-Disk', '-SerialNumber', str(volume_serial)])
                return True
            except:
                sleep(1)
                continue
        return False

    def _rescan():
        ''' From what I saw on 90% of the times the volume just apear on both nodes
        If it doesn't we'll rescan
        '''
        HPT_BIN_FILE = 'infinihost.exe'
        # to do need to think if we'd like to scan on remote and verify
        hpt_bin = path.realpath(path.join(PROJECTROOT, pardir, 'Host Power Tools', 'bin', HPT_BIN_FILE))
        execute([hpt_bin, 'rescan'])

    if not _is_vol_mapped(volume.get_serial()):
        _rescan()
        if not _is_vol_mapped(volume.get_serial()):
            log_n_raise(logger, "Windows couldn't gain access to volume {} which was just mapped".format(volume.get_name()))
Esempio n. 3
0
def _validate_max_amount_of_volumes(sdk):
    from smb.cli.__version__ import __version__
    cluster = sdk.get_cluster()
    if len(cluster.get_luns()) >= MAX_ATTACHED_VOLUMES:
        message = "Version: {} Supports only up to {} simultaneously attached Volumes"
        log_n_raise(logger,
                    message.format(__version__, MAX_ATTACHED_VOLUMES),
                    level=WARNING)
Esempio n. 4
0
def approve_operation():
    if sys.version_info > (3, 0):
        _input = input
    else:
        _input = raw_input

    proceed = _input("Choose yes or no [y/N] ").lower() in ('y', 'yes')
    if not proceed:
        log_n_raise(logger, "user didn't confirm operation")
Esempio n. 5
0
def am_I_master():
    from platform import node
    config = config_get(silent=True)
    cmd = execute_assert_success(['powershell', '-c', 'Get-ClusterGroup', '-name', config['FSRoleName'], '|', 'Select-Object',
                            '-ExpandProperty', 'OwnerNode', '|', 'Select-Object', '-ExpandProperty', 'name'])
    if cmd.get_stdout().strip() == node():
        return True
    else:
        log_n_raise(logger, "The Node you are running on is NOT the Active Cluster Node")
Esempio n. 6
0
def _validate_vol(ibox_sdk, volume_name):
    from infinisdk.core.type_binder import ObjectNotFound
    try:
        return ibox_sdk.volumes.choose(name=volume_name)
    except ObjectNotFound:
        log_n_raise(
            logger,
            "Volume {} couldn't be found on {}".format(volume_name,
                                                       ibox_sdk.get_name()))
Esempio n. 7
0
def _validate_pool_name(pool_name, ibox_sdk):
    from infinisdk.core.type_binder import ObjectNotFound
    try:
        pool = ibox_sdk.pools.choose(name=pool_name)
        return pool
    except ObjectNotFound:
        log_n_raise(
            logger,
            "Pool {} couldn't be found on {}".format(pool_name,
                                                     ibox_sdk.get_name()))
Esempio n. 8
0
def _validate_pool(pool_name, ibox_sdk, size):
    from capacity import GiB
    pool = _validate_pool_name(pool_name, ibox_sdk)
    spare_size = 1 * GiB
    new_free = pool.get_free_virtual_capacity() - size - spare_size
    if int(new_free <= 0):
        log_n_raise(
            logger,
            "Pool {} doesn't have enough space to provision {!r}".format(
                pool_name, size))
    return pool
Esempio n. 9
0
def run(cmd, error_prefix):
    result = execute(cmd)
    if result.get_returncode() == 0:
        return result.get_stdout()
    if "You do not have administrative privileges on the cluster" in result.get_stderr(
    ):
        log_n_raise(logger,
                    "{} Cluster Permissions issue".format(error_prefix))
    log_n_raise(logger,
                "{} {}".format(error_prefix, result.get_stderr()),
                disable_print=True)
Esempio n. 10
0
def map_vol_to_cluster_infinibox(volume, sdk):
    cluster = sdk.get_cluster()
    try:
        mapping = cluster.map_volume(volume)
    except:
        error = sys.exc_info()[1]
        log_n_raise(
            logger, "Couldn't Map Volume {} to {}! {!r}".format(
                volume.get_name(), cluster.get_name(), str(error.message)))
    log(logger,
        "Mapping {} to {}".format(volume.get_name(), cluster.get_name()),
        level=INFO)
Esempio n. 11
0
def _validate_vol_name(volume_name):
    '''Spaces in names aren't allowed'''
    if ' ' in volume_name:
        log_n_raise(
            logger,
            "Spaces aren't allowed in FS names. Please rename '{}'".format(
                volume_name),
            level=WARNING)
    if len(volume_name) > MAX_VOL_NAME_LENGTH:
        log_n_raise(
            logger,
            "'{}' FileSystem name is too long! (can be up to {} characters)".
            format(volume_name, MAX_VOL_NAME_LENGTH),
            level=WARNING)
Esempio n. 12
0
 def ibox_login(self):
     '''tries to connect using credintal store'''
     from smb.cli.smb_log import get_logger, log_n_raise
     logger = get_logger()
     store = initiate_store(self.config['IboxAddress'])
     ibox = infinisdk.InfiniBox(str(self.config['IboxAddress']),
                                auth=(store.get_username(),
                                      store.get_password()))
     response = ibox.login()
     if response.status_code == 200:
         return ibox
     else:
         log_n_raise(
             logger,
             "Couldn't connect to InfiniBox with current credentials")
Esempio n. 13
0
def _validate_size(size_str, roundup=False):
    import capacity
    from capacity import byte
    if size_str == '0' or size_str is None:
        return 0
    try:
        size = capacity.from_string(size_str)
    except ValueError:
        log_n_raise(logger, "{} is an invalid capacity ! Please try one of the following:\n".format(size_str) +
                         "<number> KB, KiB, MB, MiB, GB, GiB, TB, TiB... ", level=WARNING)
    if size == capacity.Capacity(0):
        return 0
    if roundup:
        if (size / byte) / 512.0 != int((size / byte) / 512.0):
            size = ((int((size / byte) / 512) + 1) * 512) * byte
    return size
Esempio n. 14
0
def change_powershell_config(key, value):
    import fileinput
    config = read_config(conf_file)
    if not config:
        log_n_raise(logger, "Problem reading config file")
    log(logger, "Changing {} = {}".format(key, value), level=INFO)
    for line in fileinput.input(conf_file, inplace=True):
        if "=" not in line:
            print line,
            continue
        line_key, line_val = line.split("=")
        if line_key.strip() == key:
            print '    {} = "{}"'.format(key, value)
        else:
            print line,
    fileinput.close()
Esempio n. 15
0
def config_get(silent=False, skip_validation=False):
    if not path.exists(conf_dir):
        mkdir(conf_dir)
        generate_config()
    config = read_config(conf_file)
    if silent or not config:
        return config
    log(logger, "Current Config:", level=INFO, raw=True)
    for key, val in config.items():
        message = "    {}: {}".format(key, val)
        log(logger, message, level=INFO, raw=True)
    if not skip_validation:
        validate_config(config)
    if not path.exists(infinihost_bin):
        log_n_raise(
            logger,
            'smb.cli depends on "Host Power Tools" and can NOT find it!')
    return config
Esempio n. 16
0
def fs_detach(fsname, sdk):
    from smb.cli.share import get_all_shares_data, join_fs_and_share
    from smb.cli.share import share_delete
    all_filesystems = _get_all_fs(sdk)
    if fsname not in [fs['fsname'] for fs in all_filesystems]:
        log_n_raise(logger, "{} Does NOT exist. Typo?".format(fsname))
    volume = _validate_vol(sdk.get_ibox(), fsname)
    volume_name = volume.get_name()
    fs = Fs(volume, sdk)
    shares = get_all_shares_data()
    full_share_list = join_fs_and_share(all_filesystems, shares)
    for s in full_share_list:
        if s.get_fs()['fsname'] == fs.get_name():
            share_delete(s.get_name())
    ps_cmd._run_remove_partition_access_path(fs.get_winid(),
                                             fs.get_mountpoint())
    ps_cmd._run_move_cluster_volume_offline(volume_name)
    lib.cluster_remove_ms_volume_and_wait(volume_name)
    unmap_volume(volume_name, fs.get_mountpoint(), sdk)
Esempio n. 17
0
def create_volume_on_infinibox(volume_name, pool_name, size, sdk):
    ibox = sdk.get_ibox()
    pool = _validate_pool(pool_name, ibox, size)
    try:
        log(logger,
            "Creating Volume {} at {}".format(volume_name, pool_name),
            level=INFO)
        volume = ibox.volumes.create(name=volume_name,
                                     pool=pool,
                                     size=size,
                                     provtype='THIN')
        volume.set_metadata('volume.provisionedby',
                            'smb.cli-{}'.format(__version__))
        return volume
    except:
        error = sys.exc_info()[1]
        log_n_raise(
            logger, "Volume {} couldn't be created. {!r}".format(
                volume_name, str(error.message)))
Esempio n. 18
0
def _run_attach_vol_to_cluster_script(fs):
    # TODO: move to run
    from smb import PROJECTROOT
    from os import path
    attach_vol_to_cluster_script = path.realpath(
        path.join(PROJECTROOT, 'src', 'smb', 'cli', 'powershell',
                  'add_vol_to_cluster.ps1'))
    try:
        cmd = execute_assert_success([
            'powershell', '.',
            '"' + attach_vol_to_cluster_script.replace('\\', '/') + '"' +
            " -DiskNumber {}".format(fs.get_winid())
        ])
    except:
        error = sys.exc_info()[1]
        log_n_raise(logger,
                    "{} failed with error: {}".format(
                        attach_vol_to_cluster_script, error),
                    disable_print=True)
Esempio n. 19
0
def validate_config(config):
    import re
    default_val = re.compile('<.+>$')
    keys = [
        'FSRoleName', 'PoolName', 'Cluster', 'MountRoot', 'TempDriveLetter',
        'IboxAddress'
    ]
    for key in keys:
        if key not in config:
            log_n_raise(
                logger,
                "Not all parameters are in the config file. Config file {} is Invalid"
                .format(conf_file))
    for key, val in config.iteritems():
        if re.search(default_val, val):
            log_n_raise(
                logger,
                "Some configuration values are missing.\ne.g. {} = {}".format(
                    key, val))
Esempio n. 20
0
def fs_attach(volume_name, sdk, force=False):
    ibox = sdk.get_ibox()
    _validate_max_amount_of_volumes(sdk)
    _validate_vol_name(volume_name)
    volume = _validate_vol(ibox, volume_name)
    if force and lib.is_volume_mapped_to_cluster(volume, sdk):
        pass
    else:
        map_vol_to_cluster_infinibox(volume, sdk)
    lib.exit_if_vol_not_mapped(volume)
    fs = Fs(volume, sdk)
    _mountpoint_exist(fs.get_mountpoint())
    try:
        ps_cmd._run_attach_vol_to_cluster_script(fs)
    except:
        log_n_raise(logger,
                    "Couldn't add {} to SMB Cluster".format(volume_name))
    log(logger,
        "Volume {} Attached to Cluster Successfully.".format(volume_name),
        level=INFO,
        color="green")
Esempio n. 21
0
def validate_key_val(key, val):
    import re
    MAX_ROLE_NAME = 15
    MAX_POOL_NAME = 32
    key_lower = key.lower()
    regular_chars = re.compile('[a-zA-Z0-9\-\_]+$')
    dns_name = re.compile('([a-zA-Z0-9\-\_]+\.)+([a-zA-Z0-9\-\_]+$)')
    ip_address = re.compile(
        '((25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9]?[0-9])'
    )
    ms_drive_letter = re.compile(r'^[a-zA-Z]{1}:{1}\\{1}$')
    if key_lower in ['fsrolename', 'poolname', 'cluster']:
        if not re.match(regular_chars, val):
            log_n_raise(
                logger,
                "Only non-spacial Characters are Supported for {}".format(key))
    if key_lower in ['fsrolename', 'cluster']:
        if len(val) > MAX_ROLE_NAME:
            log_n_raise(
                logger,
                "{} Value is to long. Max allowed Characters are {}".format(
                    key, MAX_ROLE_NAME))
        # add verify that the cluster and cluster role is the same
    if key_lower == 'poolname' and len(val) > MAX_POOL_NAME:
        log_n_raise(
            logger,
            "{} Value is to long. Max allowed Characters are {}".format(
                key, MAX_POOL_NAME))
    if key_lower in ['mountroot', 'tempdriveletter']:
        if not re.match(ms_drive_letter, val):
            log_n_raise(
                logger,
                "{} Value is Invalid. value should be Microsoft drive letter. e.g. D:\ "
                .format(val))
        val = val.upper()
    if key_lower == 'iboxaddress':
        if re.match('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$', val):
            if not re.match(ip_address, val):
                log_n_raise(logger, "{} is Invalid IP address".format(val))
        else:
            if not re.match(dns_name, val):
                log_n_raise(logger,
                            "{} is Invalid InfiniBox DNS address".format(val))
    return key, val
Esempio n. 22
0
def is_cluster_online():
    config = config_get(silent=True)
    cmd = execute_assert_success(['powershell', '-c', 'Get-ClusterGroup', '-name', config['FSRoleName'], '|', 'Select-Object',
                            '-ExpandProperty', 'state'])
    if cmd.get_stdout().strip() != 'Online':
        log_n_raise(logger, "Cluster group {} NOT in Online state !! state is: {}".format(config['FSRoleName'], cmd.get_stdout().strip()))