Exemplo n.º 1
0
    def decorated(*args, **kwargs):

        # First check that the source of the request is actually valid
        local_gw = ['127.0.0.1']
        gw_names = [
            gw for gw in config.config['gateways']
            if isinstance(config.config['gateways'][gw], dict)
        ]
        gw_ips = [get_ip(gw_name) for gw_name in gw_names] + \
                 local_gw + settings.config.trusted_ip_list

        if request.remote_addr not in gw_ips:
            return jsonify(message="API access not available to "
                           "{}".format(request.remote_addr)), 403

        # check credentials supplied in the http request are valid
        auth = request.authorization
        if not auth:
            return jsonify(message="Missing credentials"), 401

        if (auth.username != settings.config.api_user
                or auth.password != settings.config.api_password):
            return jsonify(message="username/password mismatch with the "
                           "configuration file"), 401

        return f(*args, **kwargs)
Exemplo n.º 2
0
def is_cleanup_host(config):
    """
    decide which gateway host should be responsible for any non-specific
    updates to the config object
    :param config: configuration dict from the rados pool
    :return: boolean indicating whether the addition cleanup should be
    performed by the running host
    """
    cleanup = False

    if 'ip_list' in config.config["gateways"]:

        gw_1 = config.config["gateways"]["ip_list"][0]

        usable_ip = get_ip(gw_1)
        if usable_ip != '0.0.0.0':
            if usable_ip in ipv4_addresses():
                cleanup = True

    return cleanup
Exemplo n.º 3
0
def is_cleanup_host(config):
    """
    decide which gateway host should be responsible for any non-specific updates to the
    config object
    :param config: configuration dict from the rados pool
    :return: boolean indicating whether the addition cleanup should be performed
             by the running host
    """
    cleanup = False

    if 'ip_list' in config.config["gateways"]:

        gw_1 = config.config["gateways"]["ip_list"][0]

        usable_ip = get_ip(gw_1)
        if usable_ip != '0.0.0.0':
            if usable_ip in ipv4_addresses():
                cleanup = True

    return cleanup
Exemplo n.º 4
0
def valid_gateway(gw_name, gw_ip, config):
    """
    validate the request for a new gateway
    :param gw_name: (str) host (shortname) of the gateway
    :param gw_ip: (str) ipv4 address on the gw that will be used for iSCSI
    :param config: (dict) current config
    :return: (str) "ok" or error description
    """

    http_mode = 'https' if settings.config.api_secure else "http"

    # if the gateway request already exists in the config, computer says "no"
    if gw_name in config['gateways']:
        return "Gateway name {} already defined".format(gw_name)

    if gw_ip in config['gateways'].get('ip_list', []):
        return "IP address already defined to the configuration"

    # validate the gateway name is resolvable
    if get_ip(gw_name) == '0.0.0.0':
        return ("Gateway '{}' is not resolvable to an ipv4"
                " address".format(gw_name))

    # validate the ip_address is valid ipv4
    if get_ip(gw_ip) == '0.0.0.0':
        return ("IP address provided is not usable (name doesn't"
                " resolve, or not a valid ipv4 address)")

    # At this point the request seems reasonable, so lets check a bit deeper

    gw_api = '{}://{}:{}/api'.format(http_mode,
                                     gw_name,
                                     settings.config.api_port)

    # check the intended host actually has the requested IP available
    api = APIRequest(gw_api + '/sysinfo/ipv4_addresses')
    api.get()

    if api.response.status_code != 200:
        return ("ipv4_addresses query to {} failed - check "
                "rbd-target-api log. Is the API server "
                "running and in the right mode (http/https)?".format(gw_name))

    try:
        target_ips = api.response.json()['data']
    except:
        return "Malformed REST API response"

    if gw_ip not in target_ips:
        return ("IP address of {} is not available on {}. Valid "
                "IPs are :{}".format(gw_ip,
                                     gw_name,
                                     ','.join(target_ips)))

    # check that config file on the new gateway matches the local machine
    api = APIRequest(gw_api + '/sysinfo/checkconf')
    api.get()
    if api.response.status_code != 200:
        return ("checkconf API call to {} failed with "
                "code".format(gw_name,
                              api.response.status_code))

    # compare the hash of the new gateways conf file with the local one
    local_hash = gen_file_hash('/etc/ceph/iscsi-gateway.cfg')
    try:
        remote_hash = str(api.response.json()['data'])
    except:
        remote_hash = None

    if local_hash != remote_hash:
        return ("/etc/ceph/iscsi-gateway.cfg on {} does "
                "not match the local version. Correct and "
                "retry request".format(gw_name))

    # Check for package version dependencies
    api = APIRequest(gw_api + '/sysinfo/checkversions')
    api.get()
    if api.response.status_code != 200:
        try:
            errors = api.response.json()['data']
        except:
            return "Malformed REST API response"

        return ("{} failed package validation checks - "
                "{}".format(gw_name,
                            ','.join(errors)))

    # At this point the gateway seems valid
    return "ok"