Beispiel #1
0
 def logged_in(self):
     target_iqn = self.parent.parent.name
     gateways = self.parent.parent.get_child('gateways')
     local_gw = this_host()
     is_local_target = len(
         [child
          for child in gateways.children if child.name == local_gw]) > 0
     if is_local_target:
         client_info = GWClient.get_client_info(target_iqn, self.client_iqn)
         self.alias = client_info['alias']
         self.ip_address = ','.join(client_info['ip_address'])
         return client_info['state']
     else:
         self.alias = ''
         self.ip_address = ''
         return ''
Beispiel #2
0
def valid_client(**kwargs):
    """
    validate a client create or update request, based on mode.
    :param kwargs: 'mode' is the key field used to determine process flow
    :return: 'ok' or an error description (str)
    """

    valid_modes = ['create', 'delete', 'auth', 'disk']
    parms_passed = set(kwargs.keys())

    if 'mode' in kwargs:
        if kwargs['mode'] not in valid_modes:
            return ("Invalid client validation mode request - "
                    "asked for {}, available {}".format(
                        kwargs['mode'], valid_modes))
    else:
        return "Invalid call to valid_client - mode is needed"

    # at this point we have a mode to work with

    mode = kwargs['mode']
    client_iqn = kwargs['client_iqn']
    target_iqn = kwargs['target_iqn']
    config = get_config()
    if not config:
        return "Unable to query the local API for the current config"
    target_config = config['targets'][target_iqn]

    if mode == 'create':
        # iqn must be valid
        try:
            normalize_wwn(['iqn'], client_iqn)
        except RTSLibError:
            return ("Invalid IQN name for iSCSI")

        # iqn must not already exist
        if client_iqn in target_config['clients']:
            return ("A client with the name '{}' is "
                    "already defined".format(client_iqn))

        # Creates can only be done with a minimum number of gw's in place
        num_gws = len([
            gw_name for gw_name in config['gateways']
            if isinstance(config['gateways'][gw_name], dict)
        ])
        if num_gws < settings.config.minimum_gateways:
            return ("Clients can not be defined until a HA configuration "
                    "has been defined "
                    "(>{} gateways)".format(settings.config.minimum_gateways))

        # at this point pre-req's look good
        return 'ok'

    elif mode == 'delete':

        # client must exist in the configuration
        if client_iqn not in target_config['clients']:
            return ("{} is not defined yet - nothing to "
                    "delete".format(client_iqn))

        this_client = target_config['clients'].get(client_iqn)
        if this_client.get('group_name', None):
            return ("Unable to delete '{}' - it belongs to "
                    "group {}".format(client_iqn,
                                      this_client.get('group_name')))

        # client to delete must not be logged in - we're just checking locally,
        # since *all* nodes are set up the same, and a client login request
        # would normally login to each gateway
        client_info = GWClient.get_client_info(target_iqn, client_iqn)
        if client_info['state'] == 'LOGGED_IN':
            return ("Client '{}' is logged in to {}- unable to delete until"
                    " it's logged out".format(client_iqn, target_iqn))

        # at this point, the client looks ok for a DELETE operation
        return 'ok'

    elif mode == 'auth':
        # client iqn must exist
        if client_iqn not in target_config['clients']:
            return ("Client '{}' does not exist".format(client_iqn))

        username = kwargs['username']
        password = kwargs['password']
        mutual_username = kwargs['mutual_username']
        mutual_password = kwargs['mutual_password']

        error_msg = valid_credentials(username, password, mutual_username,
                                      mutual_password)
        if error_msg:
            return error_msg

        return 'ok'

    elif mode == 'disk':

        this_client = target_config['clients'].get(client_iqn)
        if this_client.get('group_name', None):
            return ("Unable to manage disks for '{}' - it belongs to "
                    "group {}".format(client_iqn,
                                      this_client.get('group_name')))

        if 'image_list' not in parms_passed:
            return ("Disk changes require 'image_list' to be set, containing"
                    " a comma separated str of rbd images (pool/image)")

        rqst_disks = set(kwargs['image_list'].split(','))
        mapped_disks = set(target_config['clients'][client_iqn]['luns'].keys())
        current_disks = set(config['disks'].keys())

        if len(rqst_disks) > len(mapped_disks):
            # this is an add operation

            # ensure the image list is 'complete' not just a single disk
            if not mapped_disks.issubset(rqst_disks):
                return ("Invalid image list - it must contain existing "
                        "disks AND any additions")

            # ensure new disk(s) exist - must yield a result since rqst>mapped
            new_disks = rqst_disks.difference(mapped_disks)
            if not new_disks.issubset(current_disks):
                # disks provided are not currently defined
                return ("Invalid image list - it defines new disks that do "
                        "not current exist")

            return 'ok'

        else:

            # this is a disk removal operation
            if kwargs['image_list']:
                if not rqst_disks.issubset(mapped_disks):
                    return ("Invalid image list ({})".format(rqst_disks))

            return 'ok'

    return 'Unknown error in valid_client function'
Beispiel #3
0
 def logged_in(self):
     target_iqn = self.parent.parent.name
     client_info = GWClient.get_client_info(target_iqn, self.client_iqn)
     self.alias = client_info['alias']
     self.ip_address = ','.join(client_info['ip_address'])
     return client_info['state']