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)
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
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
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
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