Ejemplo n.º 1
0
def add_resource_roles(resource_label=None,
                       resource_id=None,
                       roles=None,
                       additional_data=None):
    """
    And roles to an existing resource
    """
    message = None
    if roles is None:
        roles = []

    session = persistent_mgr.create_database_session()
    if resource_id is not None:
        pass
    elif resource_label is not None:
        resource = persistent_mgr.get_device_by_label(session, resource_label)
        if resource is not None:
            resource_id = resource.resource_id
    else:
        message = "Error: add_role called without specifying to remove either a label or id"
        return -1, message

    roles_to_add = []
    for role in roles:
        roles_to_add.append(ResourceRole(resource_id, role, additional_data))

    hooks = _load_inventory_device_plugins()
    hook_name = 'unknown'  # keeps pylint happy

    # pre_save hooks
    try:
        for hook_name, hook_plugin in hooks.items():
            hook_plugin.add_role_pre_save(resource, roles_to_add)
    except Exception as e:
        logging.exception(e)
        message = _("Before role was added. Error in plugin (%s): %s") % (
            hook_name, e)

    persistent_mgr.add_device_roles(session, roles_to_add)

    # post_save hooks
    try:
        for hook_name, hook_plugin in hooks.items():
            hook_plugin.add_role_post_save(resource, roles_to_add)
    except Exception as e:
        logging.exception(e)
        message = _("After role was added. Error in plugin (%s): %s") % (
            hook_name, e)

    session.close()
    if message is None:
        message = _("added role successfully.")
    return (0, message)
Ejemplo n.º 2
0
def get_resource_id_by_label(resource_label):
    """
    Find the resource id for the given label
    Returns:
        resource_id or None
    """
    resource_id = None
    session = persistent_mgr.create_database_session()
    resource = persistent_mgr.get_device_by_label(session, resource_label)
    if resource:
        resource_id = resource.resource_id
    session.close()
    return resource_id
Ejemplo n.º 3
0
def remote_access(label):
    """Establish ssh shell access to remote endpoint

    Args:
        label:  label of the device to establish shell with

    Returns:
        rc: return code
        message: message associated with return code returned
    """
    _method_ = 'remote_access.remote_access'
    session = persistent_mgr.create_database_session()
    device = persistent_mgr.get_device_by_label(session, label)
    if device:
        address = device.address
        userid = device.userid
        password = None
        if device.password:
            password = persistent_mgr.decrypt_data(device.password)
        ssh_key_string = None
        key = device.key
        if key:
            ssh_key_string = StringIO(key.value)
            if key.password:
                password = persistent_mgr.decrypt_data(key.password)
        logging.info(
            "%s::Retrieved device details. Opening remote shell to the device (%s).",
            _method_, label)
        try:
            print(_(
                "Establishing remote SSH connection to device (%s).") % label)
            _create_remote_connection(label, address, userid, password, ssh_key_string)
        except Exception as e:
            message = _("Remote access to device (%s) failed due to error :%s") % (
                label, e)
            logging.warning(
                "%s::Failed to connect to device (%s) failed due to error :%s", _method_, label, e)
            return 1, message
    else:
        message = _(
            "Device (%s) not found.") % label
        logging.warning(
            "%s::Device (%s) not found.", _method_, label)
        return 1, message
    logging.info(
        "%s::Remote access to device (%s) successful", _method_, label)
    message = _("Remote access to device (%s) successful") % label
    session.close()
    return 0, message
Ejemplo n.º 4
0
def change_resource_properties(label=None,
                               deviceid=None,
                               new_label=None,
                               userid=None,
                               password=None,
                               address=None,
                               rackid=None,
                               rack_location=None,
                               ssh_key=None):
    """ Change the device properties in the data store

    Args:
        label: the existing label of the device (this or device id should be provided)
        deviceid: the device id of the device to change
        new_label:  new label to set for the device
        userid: the userid to set as userid managing the device.
        password: password of the userid or the ssh key
        address: the ip address or the hostname to set for the device
        rackid:  rack id to set for the device
        rack_location: location in the rack of the element
        ssh_key: string containing the new ssh private key

    Returns:
        rc:  return code
        message: completion message indicating reason for non zero rc (translated)
    """
    _method_ = 'resource_mgr.change_resource_properties'
    message = None

    session = persistent_mgr.create_database_session()

    # no properties changed
    properties = [
        new_label, userid, password, address, rackid, rack_location, ssh_key
    ]
    if all(prop is None for prop in properties):
        return 0, ""

    # gain access to the device object for the targeted item.
    if deviceid is not None:
        device = persistent_mgr.get_device_by_id(session, deviceid)
        device_des = deviceid
    else:
        device = persistent_mgr.get_device_by_label(session, label)
        device_des = label
    if not device:
        logging.error(
            "%s::Failed to change device properties device (%s) is not found.",
            _method_, device_des)
        message = _(
            "Failed to change device properties, device (%s) is not found."
        ) % (device_des)
        return 101, message

    old_device_info = device.to_dict_obj()

    address_changed = False
    # check if we now need to handle an IP address change in the change properties
    ip_address = ""
    hostname = ""

    if address is not None:
        if is_valid_address(address):
            ip_address = address
            hostname = socket.gethostbyaddr(address)[0]
        else:
            hostname = socket.getfqdn(address)
            ip_address = socket.gethostbyname(hostname)

        if ip_address != device.address:
            # check if id is of good form and not already in use as long as its
            # different from the one we have
            rc, message = validate_address(ip_address)
            if rc != 0:
                logging.error("%s::Failed to validate supplied address: %s",
                              _method_, ip_address)
                return rc, message
            else:
                # now handle the IP address change
                address_changed = True
                logging.info("%s: IP address changed.", _method_)
                device.address = ip_address
                device.hostname = hostname
    else:
        # we may need the address for authorization changes, make sure its set
        ip_address = device.address

    # if we made it here we, have an ip address to use and maybe using a
    # changed address.
    old_auth = None
    new_auth = None

    if address_changed or userid is not None or password is not None or ssh_key is not None:
        # validate that the existing credentials work with the new IP
        # address or the new credentials are valid

        # Figure out if we are:
        # 1. Replacing the userid and password with another userid and pasword
        # 2. Replacing the ssh_key with another ssh_key (may or may not have a password)
        # 3. Replacing the userid and password with an ssh_key
        # 4. Replacing the ssh_key with a userid nad password
        # 5. Not changing anything just the ip address
        # Figure out and set old_auth and new_auth to either userpass or key

        if device.key is not None:
            old_auth = "key"
        else:
            old_auth = "userpass"

        if ssh_key is not None:
            new_auth = "key"
        elif userid is not None or password is not None:
            new_auth = "userpass"
        else:
            new_auth = None

        device_type = device.resource_type
        if userid:
            temp_userid = userid
        else:
            temp_userid = device.userid

        temp_password = None
        temp_ssh_key = None
        if password:
            temp_password = password
        else:
            if device.password is not None:
                if new_auth is None:  # only lookup old password if auth hasn't changed
                    temp_password = persistent_mgr.decrypt_data(
                        device.password)
        if ssh_key:
            temp_ssh_key = ssh_key
        else:
            if device.key:
                key = device.key
                temp_ssh_key = key.value
                if key.password:
                    if new_auth is None:  # only lookup old password if auth hasn't changed
                        temp_password = persistent_mgr.decrypt_data(
                            key.password)
        if new_auth == "key":
            rc, message = _change_device_key(device, ip_address, temp_userid,
                                             temp_ssh_key, temp_password)
        elif new_auth == "userpass":
            rc, message = _change_device_userpass(device, ip_address,
                                                  temp_userid, temp_password)
        else:
            rc, message = _validate(ip_address, temp_userid, temp_password,
                                    device_type, temp_ssh_key)
        if rc != 0:
            # return error if unable to validate with currently set info
            return rc, message
        else:
            device.status = constants.access_status.SUCCESS.value
            device.statusTime = datetime.utcnow()

    if new_label is not None and new_label != device.label:
        # have new label and the new label differs from the existing label for
        # the target device
        rc, message = validate_label(new_label)
        if rc != 0:
            # another device already exists with the label
            logging.error(
                "%s::failed to change device properties, a device with the new label (%s)"
                " already exists.", _method_, new_label)
            message = _(
                "Failed to change device properties, a device with the new label"
                " (%(label)s) already exists.") % {
                    'label': new_label
                }
            return 104, message

        device.label = new_label
    if rackid is not None:
        device.rack_id = rackid
    if rack_location is not None:
        device.eia_location = rack_location

    # pre_save hooks
    hooks = _load_inventory_device_plugins()
    hook_name = 'unknown'  # keeps pylint happy

    try:
        for hook_name, hook_plugin in hooks.items():
            hook_plugin.change_device_pre_save(device, old_device_info)
    except Exception as e:
        logging.exception(e)
        message = _("Error in plugin (%s). Unable to change device: Reason: %s"
                    ) % (hook_name, e)
        return 102, message

    # commit the change.
    logging.info("%s: commit device changes now. device info: %s", _method_,
                 device)
    persistent_mgr.update_device(session)

    if old_auth == "key" and new_auth == "userpass":
        # Need to delete ssh key from database
        key_info = device.key
        persistent_mgr.delete_keys(session, [key_info])

    # post_save hooks
    try:
        for hook_name, hook_plugin in hooks.items():
            hook_plugin.change_device_post_save(device, old_device_info)
    except Exception as e:
        logging.exception(e)
        message = push_message(
            message,
            _("After device properties were changed, "
              "Error in plugin (%s): %s") % (hook_name, e))

    # return success
    logging.info("EXIT %s device properties changed", _method_)
    message = push_message(message, _("Changed device successfully."))
    session.close()
    return 0, message
Ejemplo n.º 5
0
def change_resource_password(label=None,
                             deviceid=None,
                             old_password=None,
                             new_password=None):

    method_ = 'resource_mgr.change_resource_password'
    message = None
    session = persistent_mgr.create_database_session()

    # gain access to the device object for the targeted item.
    if deviceid is not None:
        device = persistent_mgr.get_device_by_id(session, deviceid)
        device_des = deviceid
    elif label is not None:
        label = label.strip()
        device = persistent_mgr.get_device_by_label(session, label)
        device_des = label
    else:
        logging.error("Deviceid and label are None.")
        message = _("Deviceid and label are None")
        return 101, message
    if not device:
        logging.error(
            "%s::Failed to change device password device (%s) is not found.",
            method_, device_des)
        message = _(
            "Failed to change device password, device (%s) is not found.") % (
                device_des)
        return 101, message
    device_type = device.resource_type

    plugins = _load_device_plugins()

    if device_type:
        plugin = plugins[device_type]
        try:
            plugin.connect(device.address, device.userid, old_password)
            plugin.change_device_password(new_password)
            plugin.disconnect()
            # Now change the password in the database
            device.password = persistent_mgr.encrypt_data(new_password)
            # Commit the change
            logging.info("%s: commit device changes now. device info: %s",
                         method_, device)
            persistent_mgr.update_device(session)
        except KeyError:
            logging.error("%s::plugin(%s) not found", method_, device_type)
            message = _(
                "Failed to change device password, plugin (%s) is not found."
            ) % (device_type)
            return 101, message
        except Exception as e:
            logging.exception(e)
            logging.warning(
                "%s:plugin. Exception running change_device_password: %s",
                method_, e)
            message = _(
                "Failed to change device password, Exception occurred for plugin (%s)."
            ) % (device_type)
            return 101, message

    if not message:
        message = _("Changed device password successfully.")
    session.close()
    return 0, message