예제 #1
0
def _check_and_update_services(storage_ceph_ext):
    svcs = api_helper.getListFromServices(storage_ceph_ext)

    # If glance/nova is already a service on other rbd backend, remove it from there
    check_svcs = [constants.SB_SVC_GLANCE, constants.SB_SVC_NOVA]
    for s in check_svcs:
        if s in svcs:
            sb_list = pecan.request.dbapi.storage_backend_get_list()

            if sb_list:
                for sb in sb_list:
                    if (sb.uuid != storage_ceph_ext.get("uuid", None)
                            and sb.backend in [
                                constants.SB_TYPE_CEPH,
                                constants.SB_TYPE_CEPH_EXTERNAL
                            ] and s in sb.get('services')):
                        services = api_helper.getListFromServices(sb)
                        services.remove(s)
                        cap = sb.capabilities
                        for k in HIERA_DATA[s]:
                            cap.pop(k, None)
                        values = {
                            'services': ','.join(services),
                            'capabilities': cap,
                        }
                        pecan.request.dbapi.storage_backend_update(
                            sb.uuid, values)
예제 #2
0
def _get_options_string(storage_lvm):
    opt_str = ""
    caps = storage_lvm.get('capabilities', {})
    services = api_helper.getListFromServices(storage_lvm)

    # get the backend parameters
    backend_dict = caps.get("backend", {})
    be_str = ""
    for key in backend_dict:
        be_str += "\t%s: %s\n" % (key, backend_dict[key])

    # Only show the backend values if any are present
    if len(be_str) > 0:
        opt_str = "Backend:\n%s" % be_str

    # Get any supported service parameters
    for svc in constants.SB_LVM_SVCS_SUPPORTED:
        svc_dict = caps.get(svc, None)
        if svc_dict and svc in services:
            svc_str = ""
            for key in svc_dict:
                svc_str += "\t%s: %s\n" % (key, svc_dict.get(key, None))

            if len(svc_str) > 0:
                opt_str += "%s:\n%s" % (svc.title(), svc_str)

    if len(opt_str) > 0:
        opt_str = "Applying the following options:\n\n" + opt_str
    return opt_str
예제 #3
0
def _check_backend_lvm(req, storage_lvm, confirmed=False):
    # check for the backend parameters
    capabilities = storage_lvm.get('capabilities', {})

    # Discover the latest hiera_data for the supported service
    _discover_and_validate_backend_hiera_data(capabilities)

    for k in HIERA_DATA['backend']:
        if not capabilities.get(k, None):
            raise wsme.exc.ClientSideError("Missing required backend "
                                           "parameter: %s" % k)

    # go through the service list and validate
    req_services = api_helper.getListFromServices(storage_lvm)

    # Cinder is mandatory for lvm backend
    if constants.SB_SVC_CINDER not in req_services:
        raise wsme.exc.ClientSideError(
            "Service %s is mandatory for "
            "the %s backend." %
            (constants.SB_SVC_CINDER, constants.SB_TYPE_LVM))

    for svc in req_services:
        if svc not in constants.SB_LVM_SVCS_SUPPORTED:
            raise wsme.exc.ClientSideError(
                "Service %s is not supported for the"
                " %s backend" % (svc, constants.SB_TYPE_LVM))

        # Service is valid. Discover the latest hiera_data for the supported service
        discover_func = eval('_discover_and_validate_' + svc + '_hiera_data')
        discover_func(capabilities)

        # Service is valid. Check the params
        for k in HIERA_DATA[svc]:
            if not capabilities.get(k, None):
                raise wsme.exc.ClientSideError("Missing required %s service "
                                               "parameter: %s" % (svc, k))
    # Update based on any discovered values
    storage_lvm['capabilities'] = capabilities

    # TODO (rchurch): Put this back in some form for delivery OR move to specific
    # backend checks to limit operations based on the backend
    #
    # if req == constants.SB_API_OP_MODIFY or req == constants.SB_API_OP_DELETE:
    #     raise wsme.exc.ClientSideError("API Operation %s is not supported for "
    #                                    "the %s backend" %
    #                                    (req, constants.SB_TYPE_LVM))

    # Check for confirmation
    if not confirmed:
        _options_str = _get_options_string(storage_lvm)
        raise wsme.exc.ClientSideError(
            _("%s\nWARNING : THIS OPERATION IS NOT REVERSIBLE AND CANNOT BE CANCELLED. \n"
              "\nBy confirming this operation, the LVM backend will be created.\n\n"
              "Please refer to the system admin guide for minimum spec for LVM\n"
              "storage. Set the 'confirmed' field to execute this operation\n"
              "for the %s backend.") % (_options_str, constants.SB_TYPE_LVM))
예제 #4
0
def _apply_backend_changes(op, sb_obj):
    if op == constants.SB_API_OP_CREATE:
        services = api_helper.getListFromServices(sb_obj.as_dict())
        if constants.SB_SVC_CINDER in services:

            # Services are specified: Update backend + service actions
            api_helper.enable_backend(
                sb_obj, pecan.request.rpcapi.update_lvm_cinder_config)

    elif op == constants.SB_API_OP_MODIFY:
        if sb_obj.state == constants.SB_STATE_CONFIG_ERR:
            api_helper.enable_backend(
                sb_obj, pecan.request.rpcapi.update_lvm_cinder_config)

    elif op == constants.SB_API_OP_DELETE:
        pass
예제 #5
0
def _apply_backend_changes(op, sb_obj):
    if op == constants.SB_API_OP_CREATE:
        # This is a DB only change => Set the state to configured
        pecan.request.dbapi.storage_ceph_rook_update(
            sb_obj.uuid, {'state': constants.SB_STATE_CONFIGURED})

        services = api_helper.getListFromServices(sb_obj.as_dict())
        pecan.request.rpcapi.update_ceph_rook_config(pecan.request.context,
                                                     sb_obj.get('uuid'),
                                                     services)

    elif op == constants.SB_API_OP_MODIFY:
        pass

    elif op == constants.SB_API_OP_DELETE:
        pass
예제 #6
0
def _check_backend_file(req, storage_file, confirmed=False):
    # check for the backend parameters
    capabilities = storage_file.get('capabilities', {})

    # Discover the latest hiera_data for the supported service
    _discover_and_validate_backend_hiera_data(capabilities)

    for k in HIERA_DATA['backend']:
        if not capabilities.get(k, None):
            raise wsme.exc.ClientSideError("Missing required backend "
                                           "parameter: %s" % k)

    # go through the service list and validate
    req_services = api_helper.getListFromServices(storage_file)
    for svc in req_services:
        if svc not in constants.SB_FILE_SVCS_SUPPORTED:
            raise wsme.exc.ClientSideError(
                "Service %s is not supported for the"
                " %s backend" % (svc, constants.SB_TYPE_FILE))

        # Service is valid. Discover the latest hiera_data for the supported service
        discover_func = eval('_discover_and_validate_' + svc + '_hiera_data')
        discover_func(capabilities)

        # Service is valid. Check the params
        for k in HIERA_DATA[svc]:
            if not capabilities.get(k, None):
                raise wsme.exc.ClientSideError("Missing required %s service "
                                               "parameter: %s" % (svc, k))

    # Update based on any discovered values
    storage_file['capabilities'] = capabilities

    # TODO (rchurch): Put this back
    # if req == constants.SB_API_OP_MODIFY or req == constants.SB_API_OP_DELETE:
    #     raise wsme.exc.ClientSideError("API Operation %s is not supported for "
    #                                    "the %s backend" %
    #                                    (req, constants.SB_TYPE_FILE))

    # Check for confirmation
    if not confirmed:
        _options_str = _get_options_string(storage_file)
        raise wsme.exc.ClientSideError(
            _("%s\nWARNING : THIS OPERATION IS NOT REVERSIBLE AND CANNOT BE "
              "CANCELLED. \n\nPlease set the 'confirmed' field to execute "
              "this operation for the %s backend.") %
            (_options_str, constants.SB_TYPE_FILE))
def _check_backend_external(req, storage_external, confirmed=False):
    # check if it is running on secondary region
    system = pecan.request.dbapi.isystem_get_one()
    if system and system.capabilities.get('region_config') is not True:
        raise wsme.exc.ClientSideError("External backend can only be added on "
                                       "secondary region.")

    # check for the backend parameters
    capabilities = storage_external.get('capabilities', {})

    # Discover the latest hiera_data for the supported service
    _discover_and_validate_backend_hiera_data(capabilities)

    for k in HIERA_DATA['backend']:
        if not capabilities.get(k, None):
            raise wsme.exc.ClientSideError("Missing required backend "
                                           "parameter: %s" % k)

    # go through the service list and validate
    req_services = api_helper.getListFromServices(storage_external)
    for svc in req_services:
        if svc not in constants.SB_EXTERNAL_SVCS_SUPPORTED:
            raise wsme.exc.ClientSideError(
                "Service %s is not supported for the"
                " %s backend" % (svc, constants.SB_TYPE_EXTERNAL))

        # Service is valid. Discover the latest hiera_data for the supported service
        discover_func = eval('_discover_and_validate_' + svc + '_hiera_data')
        discover_func(capabilities)

        # Service is valid. Check the params
        for k in HIERA_DATA[svc]:
            if not capabilities.get(k, None):
                raise wsme.exc.ClientSideError("Missing required %s service "
                                               "parameter: %s" % (svc, k))

    # Update based on any discovered values
    storage_external['capabilities'] = capabilities

    # Check for confirmation
    if not confirmed:
        _options_str = _get_options_string(storage_external)
        raise wsme.exc.ClientSideError(
            _("%s\nWARNING : THIS OPERATION IS NOT REVERSIBLE AND CANNOT BE "
              "CANCELLED. \n\nPlease set the 'confirmed' field to execute "
              "this operation for the %s backend.") %
            (_options_str, constants.SB_TYPE_EXTERNAL))
예제 #8
0
def _check_backend_ceph_rook(req, storage_ceph_rook, confirmed=False):
    # check for the backend parameters
    capabilities = storage_ceph_rook.get('capabilities', {})

    # Discover the latest hiera_data for the supported service
    _discover_and_validate_backend_hiera_data(capabilities)

    for k in HIERA_DATA['backend']:
        if not capabilities.get(k, None):
            raise wsme.exc.ClientSideError("Missing required backend "
                                           "parameter: %s" % k)

    # go through the service list and validate
    req_services = api_helper.getListFromServices(storage_ceph_rook)
    for svc in req_services:
        if svc not in constants.SB_CEPH_ROOK_SVCS_SUPPORTED:
            raise wsme.exc.ClientSideError(
                "Service %s is not supported for the"
                " %s backend" % (svc, constants.SB_TYPE_FILE))

        # Service is valid. Discover the latest hiera_data for the supported service
        discover_func = eval('_discover_and_validate_' + svc + '_hiera_data')
        discover_func(capabilities)

        # Service is valid. Check the params
        for k in HIERA_DATA[svc]:
            if not capabilities.get(k, None):
                raise wsme.exc.ClientSideError("Missing required %s service "
                                               "parameter: %s" % (svc, k))

    # Update based on any discovered values
    storage_ceph_rook['capabilities'] = capabilities
    storage_ceph_rook['state'] = constants.SB_STATE_CONFIGURED
    storage_ceph_rook['task'] = constants.SB_TASK_NONE

    # Check for confirmation
    if not confirmed:
        _options_str = _get_options_string(storage_ceph_rook)
        raise wsme.exc.ClientSideError(
            _("%s\nWARNING : THIS OPERATION IS NOT REVERSIBLE AND CANNOT BE "
              "CANCELLED. \n\nPlease set the 'confirmed' field to execute "
              "this operation for the %s backend.") %
            (_options_str, constants.SB_TYPE_CEPH_ROOK))
예제 #9
0
def _apply_ceph_external_backend_changes(op, sb_obj, orig_sb_obj=None):
    if ((op == constants.SB_API_OP_CREATE) or
           (op == constants.SB_API_OP_MODIFY and
            sb_obj.get('ceph_conf') != orig_sb_obj.get('ceph_conf'))):

        values = {'task': constants.SB_TASK_APPLY_CONFIG_FILE}
        pecan.request.dbapi.storage_ceph_external_update(sb_obj.get('uuid'), values)

        try:
            pecan.request.rpcapi.distribute_ceph_external_config(
                pecan.request.context, sb_obj.get('ceph_conf'))
        except Exception as e:
            LOG.exception(e)
            msg = _("Failed to distribute ceph config file.")
            raise wsme.exc.ClientSideError(msg)

        services = api_helper.getListFromServices(sb_obj)

        pecan.request.rpcapi.update_ceph_external_config(
                                                pecan.request.context,
                                                sb_obj.get('uuid'),
                                                services)
    elif op == constants.SB_API_OP_DELETE:
        msg = _("Delete a Ceph external backend is not supported currently.")
        raise wsme.exc.ClientSideError(msg)
    else:
        # Compare ceph pools
        caps = sb_obj.get('capabilities', {})
        orig_caps = orig_sb_obj.get('capabilities', {})
        services = []
        for svc in constants.SB_CEPH_EXTERNAL_SVCS_SUPPORTED:
            for k in HIERA_DATA[svc]:
                if caps.get(k, None) != orig_caps.get(k, None):
                    services.append(svc)

        pecan.request.rpcapi.update_ceph_external_config(
                                                pecan.request.context,
                                                sb_obj.get('uuid'),
                                                services)
def _apply_backend_changes(op, sb_obj):
    if op in [constants.SB_API_OP_CREATE, constants.SB_API_OP_MODIFY]:
        services = api_helper.getListFromServices(sb_obj.as_dict())
        if constants.SB_SVC_CINDER in services:
            # Services are specified: Update backend + service actions
            api_helper.enable_backend(
                sb_obj, pecan.request.rpcapi.update_external_cinder_config)

        else:
            # If no service is specified or glance or swift is the only service
            # this is a DB only change => Set the state to configured
            pecan.request.dbapi.storage_external_update(
                sb_obj.uuid, {'state': constants.SB_STATE_CONFIGURED})

        # update shared_services
        s_s = utils.get_shared_services()
        shared_services = [] if s_s is None else ast.literal_eval(s_s)

        if services is not None:
            for s in services:
                if (s == constants.SB_SVC_CINDER and
                        constants.SERVICE_TYPE_VOLUME not in shared_services):
                    shared_services.append(constants.SERVICE_TYPE_VOLUME)

                if (s == constants.SB_SVC_GLANCE and
                        constants.SERVICE_TYPE_IMAGE not in shared_services):
                    shared_services.append(constants.SERVICE_TYPE_IMAGE)

        system = pecan.request.dbapi.isystem_get_one()

        system.capabilities['shared_services'] = str(shared_services)
        pecan.request.dbapi.isystem_update(
            system.uuid, {'capabilities': system.capabilities})

    elif op == constants.SB_API_OP_DELETE:
        pass
예제 #11
0
def _check_backend_ceph_external(storage_ceph_ext):
    """Prechecks for adding an external Ceph backend."""

    # go through the service list and validate
    svcs = api_helper.getListFromServices(storage_ceph_ext)

    for svc in svcs:
        if svc not in constants.SB_CEPH_EXTERNAL_SVCS_SUPPORTED:
            raise wsme.exc.ClientSideError(
                "Service %s is not supported for the"
                " %s backend" % (svc, constants.SB_TYPE_CEPH_EXTERNAL))

    # check for the backend parameters
    capabilities = storage_ceph_ext.get('capabilities', {})

    # Discover the latest hiera_data for the supported service
    _discover_and_validate_backend_hiera_data(capabilities)

    for svc in svcs:
        for k in HIERA_DATA[svc]:
            if not capabilities.get(k, None):
                raise wsme.exc.ClientSideError("Missing required %s service "
                                               "parameter: %s" % (svc, k))

    for svc in constants.SB_CEPH_EXTERNAL_SVCS_SUPPORTED:
        for k in HIERA_DATA[svc]:
            if capabilities.get(k, None) and svc not in svcs:
                raise wsme.exc.ClientSideError(
                    "Missing required service %s for "
                    "parameter: %s" % (svc, k))

    valid_pars = [i for sublist in HIERA_DATA.values() for i in sublist]
    if len(set(capabilities.keys()) - set(valid_pars)) > 0:
        raise wsme.exc.ClientSideError(
            "Parameter %s is not valid " %
            list(set(capabilities.keys()) - set(valid_pars)))

    # Check the Ceph configuration file
    ceph_conf_file = storage_ceph_ext.get('ceph_conf')
    if ceph_conf_file:
        if (ceph_conf_file == constants.SB_TYPE_CEPH_CONF_FILENAME):
            msg = _("The %s name is reserved for the internally managed Ceph "
                    "cluster.\nPlease use a different name and try again." %
                    constants.SB_TYPE_CEPH_CONF_FILENAME)
            raise wsme.exc.ClientSideError(msg)
    else:
        # Raise error if the Ceph configuration file is not provided.
        msg = _("A Ceph configuration file must be provided for provisioning "
                "an external Ceph cluster.")
        raise wsme.exc.ClientSideError(msg)

    # If a conf file is specified, make sure the backend's name is not already
    # used / one of the default names for other backends.
    if ceph_conf_file:
        backend_name = storage_ceph_ext.get('name')
        backend_list = pecan.request.dbapi.storage_backend_get_list()
        for backend in backend_list:
            if backend.uuid != storage_ceph_ext.get("uuid", None):
                if backend_name in constants.SB_DEFAULT_NAMES.values():
                    msg = _(
                        "The \"%s\" name is reserved for internally managed "
                        "backends." % backend_name)
                    raise wsme.exc.ClientSideError(msg)
                if backend.name == backend_name:
                    msg = _(
                        "The \"%s\" name is already used for another backend."
                        % backend_name)
                    raise wsme.exc.ClientSideError(msg)