Esempio n. 1
0
def define_gateway():
    """
    define the iSCSI target and tpgs
    :return: (object) gateway object
    """

    gw_ip_list = config.config['gateways'].get('ip_list', None)
    gw_iqn = config.config['gateways'].get('iqn', None)

    # Gateway Definition : Handle the creation of the Target/TPG(s) and Portals
    # Although we create the tpgs, we flick the enable_portal flag off so the
    # enabled tpg will not have an outside IP address. This prevents clients
    # from logging in too early, failing and giving up because the nodeACL
    # hasn't been defined yet (yes Windows I'm looking at you!)

    # first check if there are tpgs already in LIO (True) - this would indicate
    # a restart or reload call has been made. If the tpg count is 0, this is a
    # boot time request

    gateway = GWTarget(logger,
                       gw_iqn,
                       gw_ip_list,
                       enable_portal=portals_active())
    if gateway.error:
        halt("Error initializing iSCSI target: {}".format(gateway.error_msg))

    gateway.manage('target')
    if gateway.error:
        halt("Error creating the iSCSI target (target, TPGs, Portals): "
             "{}".format(gateway.error_msg))

    return gateway
Esempio n. 2
0
def target(target_iqn=None):
    """
    Handle the definition of the iscsi target name
    The target is added to the configuration object, seeding the configuration
    for ALL gateways
    :param target_iqn: IQN of the target each gateway will use
    **RESTRICTED**
    """
    if request.method == 'PUT':

        gateway_ip_list = []

        target = GWTarget(logger, str(target_iqn), gateway_ip_list)

        if target.error:
            logger.error("Unable to create an instance of the GWTarget class")
            return jsonify(message="GWTarget problem - "
                           "{}".format(target.error_msg)), 500

        target.manage('init')
        if target.error:
            logger.error("Failure during gateway 'init' processing")
            return jsonify(
                message="iscsi target 'init' process failed "
                "for {} - {}".format(target_iqn, target.error_msg)), 500

        return jsonify(message="Target defined successfully"), 200

    else:
        # return unrecognised request
        return jsonify(message="Invalid method ({}) to target "
                       "API".format(request.method)), 405
Esempio n. 3
0
def ansible_main():
    # Configures the gateway on the host. All images defined are added to
    # the default tpg for later allocation to clients
    fields = {
        "gateway_iqn": {
            "required": True,
            "type": "str"
        },
        "gateway_ip_list": {
            "required": True
        },  # "type": "list"},
        "mode": {
            "required": True,
            "choices": ['target', 'map']
        }
    }

    module = AnsibleModule(
        argument_spec=fields,  # noqa: F405
        supports_check_mode=False)

    cfg = Config(logger)
    if cfg.config['version'] > 3:
        module.fail_json(msg="Unsupported iscsigws.yml/iscsi-gws.yml setting "
                         "detected. Remove depreciated iSCSI target, LUN, "
                         "client, and gateway settings from "
                         "iscsigws.yml/iscsi-gws.yml. See "
                         "iscsigws.yml.sample for list of supported "
                         "settings")

    gateway_iqn = module.params['gateway_iqn']
    gateway_ip_list = module.params['gateway_ip_list'].split(',')
    mode = module.params['mode']

    if not valid_ip(gateway_ip_list):
        module.fail_json(msg="Invalid gateway IP address(es) provided - port "
                         "22 check failed ({})".format(gateway_ip_list))

    logger.info("START - GATEWAY configuration started - mode {}".format(mode))

    gateway = GWTarget(logger, gateway_iqn, gateway_ip_list)
    if gateway.error:
        logger.critical("(ansible_main) Gateway init failed - "
                        "{}".format(gateway.error_msg))
        module.fail_json(msg="iSCSI gateway initialisation failed "
                         "({})".format(gateway.error_msg))

    gateway.manage(mode)

    if gateway.error:
        logger.critical("(main) Gateway creation or load failed, "
                        "unable to continue")
        module.fail_json(msg="iSCSI gateway creation/load failure "
                         "({})".format(gateway.error_msg))

    logger.info("END - GATEWAY configuration complete")
    module.exit_json(changed=gateway.changes_made,
                     meta={"msg": "Gateway setup complete"})
Esempio n. 4
0
def ansible_main():
    # Configures the gateway on the host. All images defined are added to
    # the default tpg for later allocation to clients
    fields = {"gateway_iqn": {"required": True, "type": "str"},
              "gateway_ip_list": {"required": True},    # "type": "list"},
              "mode": {
                  "required": True,
                  "choices": ['target', 'map']
                  }
              }

    module = AnsibleModule(argument_spec=fields,
                           supports_check_mode=False)

    gateway_iqn = module.params['gateway_iqn']
    gateway_ip_list = module.params['gateway_ip_list'].split(',')
    mode = module.params['mode']

    if not valid_ip(gateway_ip_list):
        module.fail_json(msg="Invalid gateway IP address(es) provided - port "
                             "22 check failed ({})".format(gateway_ip_list))

    logger.info("START - GATEWAY configuration started - mode {}".format(mode))

    gateway = GWTarget(logger, gateway_iqn, gateway_ip_list)
    if gateway.error:
        logger.critical("(ansible_main) Gateway init failed - "
                        "{}".format(gateway.error_msg))
        module.fail_json(msg="iSCSI gateway initialisation failed "
                             "({})".format(gateway.error_msg))

    gateway.manage(mode)

    if gateway.error:
        logger.critical("(main) Gateway creation or load failed, "
                        "unable to continue")
        module.fail_json(msg="iSCSI gateway creation/load failure "
                             "({})".format(gateway.error_msg))


    logger.info("END - GATEWAY configuration complete")
    module.exit_json(changed=gateway.changes_made,
                     meta={"msg": "Gateway setup complete"})
Esempio n. 5
0
def ansible_main():
    # Configures the gateway on the host. All images defined are added to
    # the default tpg for later allocation to clients
    fields = {"gateway_iqn": {"required": True, "type": "str"},
              "gateway_ip_list": {"required": True},    # "type": "list"},
              "mode": {
                  "required": True,
                  "choices": ['target', 'map']
                  }
              }

    module = AnsibleModule(argument_spec=fields,
                           supports_check_mode=False)

    gateway_iqn = module.params['gateway_iqn']
    gateway_ip_list = module.params['gateway_ip_list'].split(',')
    mode = module.params['mode']

    if not valid_ip(gateway_ip_list):
        module.fail_json(msg="Invalid gateway IP address(es) provided - port 22 check failed ({})".format(gateway_ip_list))

    logger.info("START - GATEWAY configuration started in mode {}".format(mode))

    gateway = GWTarget(logger, gateway_iqn, gateway_ip_list)
    if gateway.error:
        logger.critical("(ansible_main) Gateway init failed - {}".format(gateway.error_msg))
        module.fail_json(msg="iSCSI gateway initialisation failed ({})".format(gateway.error_msg))

    gateway.manage(mode)

    if gateway.error:
        logger.critical("(main) Gateway creation or load failed, unable to continue")
        module.fail_json(msg="iSCSI gateway creation/load failure ({})".format(gateway.error_msg))


    logger.info("END - GATEWAY configuration complete")
    module.exit_json(changed=gateway.changes_made, meta={"msg": "Gateway setup complete"})
Esempio n. 6
0
    def activate(self):
        disk = self.config.config['disks'].get(self.config_key, None)
        if not disk:
            raise CephiSCSIError("Image {} not found.".format(self.image))

        wwn = disk.get('wwn', None)
        if not wwn:
            raise CephiSCSIError("LUN {} missing wwn".format(self.image))

        # re-add backend storage object
        so = self.lio_stg_object()
        if not so:
            self.add_dev_to_lio(wwn)
            if self.error:
                raise CephiSCSIError("LUN activate failure - {}".format(
                    self.error_msg))

        # re-add LUN to target
        local_gw = this_host()
        targets_items = [
            item for item in self.config.config['targets'].items()
            if self.config_key in item[1]['disks']
            and local_gw in item[1]['portals']
        ]
        for target_iqn, target in targets_items:
            ip_list = target['ip_list']

            # Add the mapping for the lun to ensure the block device is
            # present on all TPG's
            gateway = GWTarget(self.logger, target_iqn, ip_list)

            gateway.manage('map')
            if gateway.error:
                raise CephiSCSIError("LUN mapping failed - {}".format(
                    gateway.error_msg))

            # re-map LUN to hosts
            client_err = ''
            for client_iqn in target['clients']:
                client_metadata = target['clients'][client_iqn]
                if client_metadata.get('group_name', ''):
                    continue

                image_list = list(client_metadata['luns'].keys())
                if self.config_key not in image_list:
                    continue

                client_chap = CHAP(client_metadata['auth']['chap'])
                chap_str = client_chap.chap_str
                if client_chap.error:
                    raise CephiSCSIError("Password decode issue : "
                                         "{}".format(client_chap.error_msg))

                client_chap_mutual = CHAP(
                    client_metadata['auth']['chap_mutual'])
                chap_mutual_str = client_chap_mutual.chap_str
                if client_chap_mutual.error:
                    raise CephiSCSIError("Password decode issue : "
                                         "{}".format(
                                             client_chap_mutual.error_msg))

                client = GWClient(self.logger, client_iqn, image_list,
                                  chap_str, chap_mutual_str, target_iqn)
                client.manage('present')
                if client.error:
                    client_err = "LUN mapping failed {} - {}".format(
                        client_iqn, client.error_msg)

            # re-map LUN to host groups
            for group_name in target['groups']:
                host_group = target['groups'][group_name]
                members = host_group.get('members')
                disks = host_group.get('disks').keys()
                if self.config_key not in disks:
                    continue

                group = Group(self.logger, target_iqn, group_name, members,
                              disks)
                group.apply()
                if group.error:
                    client_err = "LUN mapping failed {} - {}".format(
                        group_name, group.error_msg)

            if client_err:
                raise CephiSCSIError(client_err)
Esempio n. 7
0
def manage_disk(image_id):
    """
    Manage a disk definition on the local gateway
    Internal Use ONLY
    Disks can be created and added to each gateway, or deleted through this
    call
    :param image_id: (str) of the form pool.image_name
    **RESTRICTED**
    """

    if request.method == 'GET':

        if image_id in config.config['disks']:
            return jsonify(config.config["disks"][image_id]), 200

        else:
            return jsonify(message="rbd image {} not "
                           "found".format(image_id)), 404

    elif request.method == 'PUT':
        # A put is for either a create or a resize
        # put('http://127.0.0.1:5000/api/disk/rbd.ansible3',data={'pool': 'rbd','size': '3G','owner':'ceph-1'})

        rqst_fields = set(request.form.keys())
        if rqst_fields.issuperset(("pool", "size", "owner", "mode")):

            image_name = str(image_id.split('.', 1)[1])
            lun = LUN(logger, str(request.form['pool']), image_name,
                      str(request.form['size']), str(request.form['owner']))
            if lun.error:
                logger.error("Unable to create a LUN instance"
                             " : {}".format(lun.error_msg))
                return jsonify(message="Unable to establish LUN instance"), 500

            lun.allocate()
            if lun.error:
                logger.error("LUN alloc problem - {}".format(lun.error_msg))
                return jsonify(message="LUN allocation failure"), 500

            if request.form['mode'] == 'create':
                # new disk is allocated, so refresh the local config object
                config.refresh()

                iqn = config.config['gateways']['iqn']
                ip_list = config.config['gateways']['ip_list']

                # Add the mapping for the lun to ensure the block device is
                # present on all TPG's
                gateway = GWTarget(logger, iqn, ip_list)

                gateway.manage('map')
                if gateway.error:
                    logger.error("LUN mapping failed : "
                                 "".format(gateway.error_msg))
                    return jsonify(message="LUN map failed"), 500

                return jsonify(message="LUN created"), 200

            elif request.form['mode'] == 'resize':

                return jsonify(message="LUN resized"), 200

        else:

            # this is an invalid request
            return jsonify(message="Invalid Request - need to provide"
                           "pool, size and owner"), 400

    else:
        # DELETE request
        # let's assume that the request has been validated by the caller

        # if valid_request(request.remote_addr):
        purge_host = request.form['purge_host']

        pool, image = image_id.split('.', 1)

        lun = LUN(logger, pool, image, '0G', purge_host)

        if lun.error:
            # problem defining the LUN instance
            logger.error("Error initialising the LUN : "
                         "{}".format(lun.error_msg))
            return jsonify(message="Error establishing LUN instance"), 500

        lun.remove_lun()
        if lun.error:
            if 'allocated to' in lun.error_msg:
                # attempted to remove rbd that is still allocated to a client
                status_code = 400
            else:
                status_code = 500

            logger.error("LUN remove failed : {}".format(lun.error_msg))
            return jsonify(message="Failed to remove the LUN"), status_code

        config.refresh()

        return jsonify(message="LUN removed"), 200
Esempio n. 8
0
def manage_gateway(gateway_name=None):
    """
    Manage the local iSCSI gateway definition
    Internal Use ONLY
    Gateways may be be added(PUT), queried (GET) or deleted (DELETE) from
    the configuration
    :param gateway_name: (str) gateway name, normally the DNS name
    **RESTRICTED**
    """

    if request.method == 'GET':

        if gateway_name in config.config['gateways']:

            return jsonify(config.config['gateways'][gateway_name]), 200
        else:
            return jsonify(message="Gateway doesn't exist in the "
                           "configuration"), 404

    elif request.method == 'PUT':
        # the parameters need to be cast to str for compatibility
        # with the comparison logic in common.config.add_item
        logger.debug("Attempting create of gateway {}".format(gateway_name))

        gateway_ips = str(request.form['gateway_ip_list'])
        target_iqn = str(request.form['target_iqn'])
        target_mode = str(request.form.get('mode', 'target'))

        gateway_ip_list = gateway_ips.split(',')

        gateway = GWTarget(logger, target_iqn, gateway_ip_list)

        if gateway.error:
            logger.error("Unable to create an instance of the GWTarget class")
            return jsonify(message="Failed to create the gateway"), 500

        gateway.manage(target_mode)
        if gateway.error:
            logger.error("manage({}) logic failed for {}".format(
                target_mode, gateway_name))
            return jsonify(message="Failed to create the gateway"), 500

        logger.info("created the gateway")

        if target_mode == 'target':
            # refresh only for target definitions, since that's when the config
            # will actually change
            logger.info("refreshing the configuration after the gateway "
                        "creation")
            config.refresh()

        return jsonify(message="Gateway defined/mapped"), 200

    else:
        # DELETE gateway request
        gateway = GWTarget(logger, config.config['gateways']['iqn'], '')
        if gateway.error:
            return jsonify(message="Failed to connect to the gateway"), 500

        gateway.manage('clearconfig')
        if gateway.error:
            logger.error("clearconfig failed for {} : "
                         "{}".format(gateway_name, gateway.error_msg))
            return jsonify(message="Unable to remove {} from the "
                           "configuration".format(gateway_name)), 400

        else:

            config.refresh()

            return jsonify(message="Gateway removed successfully"), 200