コード例 #1
0
def _manage_unmanage_subcloud(subcloud=None,
                              manage=False,
                              check_first=True,
                              fail_ok=False,
                              con_ssh=None,
                              auth_info=Tenant.get('admin_platform',
                                                   'RegionOne'),
                              source_openrc=False):
    """
    Manage/Unmanage given subcloud(s)
    Args:
        subcloud:
        manage:
        check_first:
        fail_ok:

    Returns:

    """
    operation = 'manage' if manage else 'unmanage'
    expt_state = '{}d'.format(operation)
    if not subcloud:
        subcloud = [ProjVar.get_var('PRIMARY_SUBCLOUD')]
    elif isinstance(subcloud, str):
        subcloud = [subcloud]

    subclouds_to_update = list(subcloud)
    if check_first:
        subclouds_in_state = get_subclouds(mgmt=expt_state,
                                           con_ssh=con_ssh,
                                           auth_info=auth_info)
        subclouds_to_update = list(
            set(subclouds_to_update) - set(subclouds_in_state))
        if not subclouds_to_update:
            LOG.info("{} already {}. Do nothing.".format(subcloud, expt_state))
            return -1, []

    LOG.info("Attempt to {}: {}".format(operation, subclouds_to_update))
    failed_subclouds = []
    for subcloud_ in subclouds_to_update:
        code, out = cli.dcmanager('subcloud ' + operation,
                                  subcloud_,
                                  ssh_client=con_ssh,
                                  fail_ok=True,
                                  auth_info=auth_info,
                                  source_openrc=source_openrc)

        if code > 0:
            failed_subclouds.append(subcloud_)

    if failed_subclouds:
        err = "Failed to {} {}".format(operation, failed_subclouds)
        if fail_ok:
            LOG.info(err)
            return 1, failed_subclouds
        raise exceptions.DCError(err)

    LOG.info(
        "Check management status for {} after dcmanager subcloud {}".format(
            subclouds_to_update, operation))
    mgmt_states = get_subclouds(field='management',
                                name=subclouds_to_update,
                                auth_info=auth_info,
                                con_ssh=con_ssh)
    failed_subclouds = [
        subclouds_to_update[i] for i in range(len(mgmt_states))
        if mgmt_states[i] != expt_state
    ]
    if failed_subclouds:
        raise exceptions.DCError("{} not {} after dcmanger subcloud {}".format(
            failed_subclouds, expt_state, operation))

    return 0, subclouds_to_update
コード例 #2
0
def add_subcloud(subcloud,
                 subcloud_controller_node,
                 system_controller_node,
                 bootstrap_values_path,
                 deploy_play_book_path,
                 deploy_values_path,
                 fail_ok=False,
                 auth_info=Tenant.get('admin_platform', 'RegionOne'),
                 source_openrc=None):
    """


    """
    operation = 'add'
    LOG.info("Attempt to {}: {}".format(operation, subcloud))

    if system_controller_node.ssh_conn is None:
        msg = 'No ssh connection to System Controller; Cannot add subcloud {} '.format(
            subcloud)
        LOG.warning(msg)
        if fail_ok:
            return 1, msg
        else:
            raise exceptions.DCError(msg)
    subcloud_add_config_pathes = [
        bootstrap_values_path, deploy_play_book_path, deploy_values_path
    ]

    if not subcloud_controller_node or not bootstrap_values_path or not deploy_play_book_path or not deploy_values_path:
        msg = "To add a subcloud all values must be specified"
        LOG.warning(msg)
        if fail_ok:
            return 1, msg
        else:
            raise exceptions.DCError(msg)

    for file_path in subcloud_add_config_pathes:
        if system_controller_node.ssh_conn.exec_cmd(
                "test -f {}".format(file_path))[0] != 0:
            msg = "Subcloud {} is missing config file {} ".format(
                subcloud, file_path)
            LOG.warning(msg)
            if fail_ok:
                return 1, msg
            else:
                raise exceptions.DCError(msg)

    args_dict = {
        '--bootstrap-address': subcloud_controller_node.host_ip,
        '--bootstrap-values': bootstrap_values_path,
        '--deploy-playbook': deploy_play_book_path,
        '--deploy-values': deploy_values_path,
        '--subcloud-password': HostLinuxUser.get_password()
    }

    opt_args = ''
    for key, val in args_dict.items():
        if val is not None:
            opt_args += '{} {} '.format(key, val)

    rc, output = cli.dcmanager('subcloud ' + operation,
                               opt_args,
                               ssh_client=system_controller_node.ssh_conn,
                               fail_ok=fail_ok,
                               auth_info=auth_info,
                               source_openrc=source_openrc)

    if rc != 0:
        msg = "Fail to add subcloud {}: {}".format(subcloud, output)
        LOG.warning(msg)
        if fail_ok:
            return 1, msg
        else:
            raise exceptions.DCError(msg)

    return rc, output
コード例 #3
0
def wait_for_sync_audit(subclouds,
                        con_ssh=None,
                        fail_ok=False,
                        filters_regex=None,
                        timeout=DCTimeout.SYNC):
    """
    Wait for Updating subcloud log msg in dcmanager.log for given subcloud(s)
    Args:
        subclouds (list|tuple|str):
        con_ssh:
        fail_ok:
        filters_regex: e.g., ['audit_action.*keypair', 'Clean audit.*ntp'], '\/compute'
        timeout:

    Returns (tuple):
        (True, <res_dict>)
        (False, <res_dict>)

    """
    if not con_ssh:
        con_ssh = ControllerClient.get_active_controller('RegionOne')

    if isinstance(subclouds, str):
        subclouds = [subclouds]

    LOG.info(
        "Waiting for sync audit in dcmanager.log for: {}".format(subclouds))
    if not filters_regex:
        filters_regex = ['platform', 'patching', 'identity']
    elif isinstance(filters_regex, str):
        filters_regex = [filters_regex]

    subclouds_dict = {subcloud: list(filters_regex) for subcloud in subclouds}
    res = {subcloud: False for subcloud in subclouds}
    subclouds_to_wait = list(subclouds)
    end_time = time.time() + timeout

    expt_list = []
    for subcloud in subclouds_dict:
        expt_list += [
            '{}.*{}'.format(subcloud, service)
            for service in subclouds_dict[subcloud]
        ]

    con_ssh.send('tail -n 0 -f {}'.format(SysLogPath.DC_ORCH))

    try:
        while time.time() < end_time:
            index = con_ssh.expect(expt_list, timeout=timeout, fail_ok=True)
            if index >= 0:
                subcloud_, service_ = expt_list[index].split('.*', maxsplit=1)
                subclouds_dict[subcloud_].remove(service_)
                expt_list.pop(index)
                if not subclouds_dict[subcloud_]:
                    subclouds_to_wait.remove(subcloud_)
                    subclouds_dict.pop(subcloud_)
                    res[subcloud_] = True
                if not subclouds_to_wait:
                    LOG.info("sync request logged for: {}".format(subclouds))
                    return True, res
            else:
                msg = 'sync audit for {} not shown in {} in {}s: {}'.format(
                    subclouds_to_wait, SysLogPath.DC_ORCH, timeout,
                    subclouds_dict)
                if fail_ok:
                    LOG.info(msg)
                    for subcloud in subclouds_to_wait:
                        res[subcloud] = False
                    return False, res
                else:
                    raise exceptions.DCError(msg)

    finally:
        con_ssh.send_control()
        con_ssh.expect()
コード例 #4
0
def wait_for_subcloud_status(subcloud,
                             avail=None,
                             sync=None,
                             mgmt=None,
                             deploy=None,
                             timeout=DCTimeout.SUBCLOUD_AUDIT,
                             check_interval=30,
                             auth_info=Tenant.get('admin_platform',
                                                  'RegionOne'),
                             con_ssh=None,
                             source_openrc=None,
                             fail_ok=False):
    """
    Wait for subcloud status
    Args:
        subcloud:
        avail:
        sync:
        mgmt:
        timeout:
        check_interval:
        auth_info:
        con_ssh:
        source_openrc:
        fail_ok:

    Returns:

    """

    if not subcloud:
        raise ValueError("Subcloud name must be specified")

    expt_status = {}
    if avail:
        expt_status['avail'] = avail
    if sync:
        expt_status['sync'] = sync
    if mgmt:
        expt_status['mgmt'] = mgmt
    if deploy:
        expt_status['deploy'] = deploy

    if not expt_status:
        raise ValueError(
            "At least one  expected status of the subcloud must be specified.")

    LOG.info("Wait for {} status: {}".format(subcloud, expt_status))
    end_time = time.time() + timeout + check_interval
    while time.time() < end_time:
        if get_subclouds(field='name',
                         name=subcloud,
                         con_ssh=con_ssh,
                         source_openrc=source_openrc,
                         auth_info=auth_info,
                         **expt_status):
            return 0, subcloud
        LOG.info("Not in expected states yet...")
        time.sleep(check_interval)

    msg = '{} status did not reach {} within {} seconds'.format(
        subcloud, expt_status, timeout)
    LOG.warning(msg)
    if fail_ok:
        return 1, msg
    else:
        raise exceptions.DCError(msg)
コード例 #5
0
def wait_for_subcloud_config(func,
                             *func_args,
                             subcloud=None,
                             config_name=None,
                             expected_value=None,
                             auth_name='admin_platform',
                             fail_ok=False,
                             timeout=DCTimeout.SYNC,
                             check_interval=30,
                             strict_order=True,
                             **func_kwargs):
    """
    Wait for subcloud configuration to reach expected value
    Args:
        subcloud (str|None):
        func: function defined to get current value, which has to has parameter con_ssh and auth_info
        *func_args: positional args for above func. Should NOT include auth_info or con_ssh.
        config_name (str): such as dns, keypair, etc
        expected_value (None|str|list):
        auth_name (str): auth dict name. e.g., admin_platform, admin, tenant1, TENANT2, etc
        fail_ok (bool):
        timeout (int):
        check_interval (int):
        strict_order (bool)
        **func_kwargs: kwargs for defined func. auth_info and con_ssh has to be provided here

    Returns (tuple):
        (0, <subcloud_config>)     # same as expected
        (1, <subcloud_config>)     # did not update within timeout
        (2, <subcloud_config>)     # updated to unexpected value

    """
    if not subcloud:
        subcloud = ProjVar.get_var('PRIMARY_SUBCLOUD')

    config_name = ' ' + config_name if config_name else ''

    if expected_value is None:
        central_ssh = ControllerClient.get_active_controller(name='RegionOne')
        expected_value = func(con_ssh=central_ssh,
                              auth_info=Tenant.get(auth_name,
                                                   dc_region='RegionOne'))
    elif isinstance(expected_value, str):
        expected_value = expected_value.split(sep=',')

    if not strict_order:
        expected_value = sorted(list(expected_value))

    LOG.info("Wait for {}{} to be {}".format(subcloud, config_name,
                                             expected_value))
    if not func_kwargs.get('con_ssh', None):
        func_kwargs['con_ssh'] = ControllerClient.get_active_controller(
            name=subcloud)
    if not func_kwargs.get('auth_info', None):
        func_kwargs['auth_info'] = Tenant.get(auth_name, dc_region=subcloud)

    origin_subcloud_val = func(*func_args, **func_kwargs)
    subcloud_val = copy.copy(origin_subcloud_val)
    if isinstance(subcloud_val, str):
        subcloud_val = subcloud_val.split(sep=',')

    if not strict_order:
        subcloud_val = sorted(list(subcloud_val))

    end_time = time.time() + timeout + check_interval
    while time.time() < end_time:
        if subcloud_val == expected_value:
            LOG.info("{}{} setting is same as central region".format(
                subcloud, config_name))
            return 0, subcloud_val

        elif subcloud_val != origin_subcloud_val:
            msg = '{}{} config changed to unexpected value. Expected: {}; Actual: {}'.\
                format(subcloud, config_name, expected_value, subcloud_val)

            if fail_ok:
                LOG.info(msg)
                return 2, subcloud_val
            else:
                raise exceptions.DCError(msg)

        time.sleep(check_interval)
        subcloud_val = func(*func_args, **func_kwargs)

    msg = '{}{} config did not reach: {} within {} seconds; actual: {}'.format(
        subcloud, config_name, expected_value, timeout, subcloud_val)
    if fail_ok:
        LOG.info(msg)
        return 1, subcloud_val
    else:
        raise exceptions.DCError(msg)