def _from_csv(cls, system, data, csv_type, log): """ Import data from CSV file into System Objects """ for key in data.keys(): if key in cls.reg_keys and key != 'id': if data[key]: newdata = smart_bool(data[key]) else: newdata = None current_data = getattr(system, key, None) if unicode(newdata) != unicode(current_data): setattr(system, key, newdata) system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=key, old=u'%s' % current_data, new=u'%s' % newdata) # import arch if 'arch' in data: arch_objs = [] if data['arch']: arches = data['arch'].split(',') for arch in arches: try: arch_obj = Arch.by_name(arch) except ValueError: raise ValueError("%s: Invalid arch %s" % (system.fqdn, arch)) arch_objs.append(arch_obj) if system.arch != arch_objs: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'arch', old=u'%s' % system.arch, new=u'%s' % arch_objs) system.arch = arch_objs # import cc if 'cc' in data: cc_objs = [] if data['cc']: cc_objs = data['cc'].split(',') if system.cc != cc_objs: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'cc', old=u'%s' % system.cc, new=u'%s' % cc_objs) system.cc = cc_objs # import labController if 'lab_controller' in data: if data['lab_controller']: try: lab_controller = LabController.by_name( data['lab_controller']) except InvalidRequestError: raise ValueError("%s: Invalid lab controller %s" % (system.fqdn, data['lab_controller'])) else: lab_controller = None if system.lab_controller != lab_controller: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'lab_controller', old=u'%s' % system.lab_controller, new=u'%s' % lab_controller) system.lab_controller = lab_controller # import owner if 'owner' in data: if data['owner']: owner = User.by_user_name(data['owner']) if not owner: raise ValueError("%s: Invalid User %s" % (system.fqdn, data['owner'])) if owner.removed: raise ValueError('%s: user %s is deleted' % (system.fqdn, owner.user_name)) else: owner = None if system.owner != owner: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'owner', old=u'%s' % system.owner, new=u'%s' % owner) system.owner = owner # import status if 'status' in data and data['status']: try: systemstatus = SystemStatus.from_string(data['status']) except ValueError: raise ValueError("%s: Invalid Status %s" % (system.fqdn, data['status'])) if system.status != systemstatus: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'status', old=u'%s' % system.status, new=u'%s' % systemstatus) system.status = systemstatus # import type if 'type' in data: if not data['type']: raise ValueError("%s: Invalid Type None" % system.fqdn) try: systemtype = SystemType.from_string(data['type']) except ValueError: raise ValueError("%s: Invalid Type %s" % (system.fqdn, data['type'])) if system.type != systemtype: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'type', old=u'%s' % system.type, new=u'%s' % systemtype) system.type = systemtype # import secret if 'secret' in data: # 'private' used to be a field on system (called 'secret' in the UI # and CSV). The field is replaced by the 'view' permission in the # access policy so CSV export no longer produces 'secret' in its # output. However we still accept it on import for compatibility. # It is mapped to the 'view everybody' rule in the access policy. if not data['secret']: raise ValueError("%s: Invalid secret None" % system.fqdn) secret = smart_bool(data['secret']) view_everybody = system.custom_access_policy.grants_everybody( SystemPermission.view) if secret and view_everybody: # remove 'view everybody' rule for rule in system.custom_access_policy.rules: if rule.permission == SystemPermission.view and rule.everybody: system.record_activity(user=identity.current.user, service=u'HTTP', field=u'Access Policy Rule', action=u'Removed', old=repr(rule)) session.delete(rule) if not secret and not view_everybody: # add rule granting 'view everybody' new_rule = system.custom_access_policy.add_rule( everybody=True, permission=SystemPermission.view) system.record_activity(user=identity.current.user, service=u'HTTP', field=u'Access Policy Rule', action=u'Added', new=repr(new_rule))
def update_system(fqdn): system = _get_system_by_FQDN(fqdn) if not system.can_edit(identity.current.user): raise Forbidden403('Cannot edit system') data = read_json_request(request) # helper for recording activity below def record_activity(field, old, new, action=u'Changed'): system.record_activity(user=identity.current.user, service=u'HTTP', action=action, field=field, old=old, new=new) with convert_internal_errors(): # XXX what a nightmare... need to use a validation/conversion library, # and maybe simplify/relocate the activity recording stuff somehow changed = False renamed = False if 'fqdn' in data: new_fqdn = data['fqdn'].lower() if new_fqdn != system.fqdn: if System.query.filter(System.fqdn == new_fqdn).count(): raise Conflict409('System %s already exists' % new_fqdn) record_activity(u'FQDN', system.fqdn, new_fqdn) system.fqdn = new_fqdn changed = True renamed = True if 'owner' in data and data['owner'].get( 'user_name') != system.owner.user_name: if not system.can_change_owner(identity.current.user): raise Forbidden403('Cannot change owner') new_owner = User.by_user_name(data['owner'].get('user_name')) if new_owner is None: raise BadRequest400('No such user %s' % data['owner'].get('user_name')) record_activity(u'Owner', system.owner, new_owner) system.owner = new_owner changed = True if 'status' in data: new_status = SystemStatus.from_string(data['status']) if new_status != system.status: record_activity(u'Status', system.status, new_status) system.status = new_status if not new_status.bad and system.status_reason: # clear the status reason for "good" statuses record_activity(u'Status Reason', system.status_reason, None) system.status_reason = None changed = True if 'status_reason' in data: new_reason = data['status_reason'] or None if new_reason and not system.status.bad: raise ValueError('Cannot set status reason when status is %s' % system.status) if new_reason != system.status_reason: record_activity(u'Status Reason', system.status_reason, new_reason) system.status_reason = new_reason changed = True if 'type' in data: new_type = SystemType.from_string(data['type']) if new_type != system.type: record_activity(u'Type', system.type, new_type) system.type = new_type changed = True if 'arches' in data: new_arches = [Arch.by_name(a) for a in (data['arches'] or [])] added_arches = set(new_arches).difference(system.arch) removed_arches = set(system.arch).difference(new_arches) if added_arches or removed_arches: for added_arch in added_arches: record_activity(u'Arch', None, added_arch, u'Added') for removed_arch in removed_arches: record_activity(u'Arch', removed_arch, None, u'Removed') system.arch[:] = new_arches changed = True if 'lab_controller_id' in data: if data['lab_controller_id']: new_lc = LabController.by_id(data['lab_controller_id']) else: new_lc = None if new_lc != system.lab_controller: if system.open_reservation is not None: raise Conflict409( 'Unable to change lab controller while system ' 'is in use (return the system first)') record_activity(u'Lab Controller', system.lab_controller, new_lc) system.lab_controller = new_lc changed = True # If we're given any power-related keys, need to ensure system.power exists if not system.power and set(['power_type', 'power_address', 'power_user', 'power_password', 'power_id', 'power_quiescent_period'])\ .intersection(data.keys()): system.power = Power() if 'power_type' in data: new_power_type = PowerType.by_name(data['power_type']) if new_power_type != system.power.power_type: if not system.power.power_type: old_power_type = '' else: old_power_type = system.power.power_type.name record_activity(u'power_type', old_power_type, new_power_type.name) system.power.power_type = new_power_type changed = True if 'power_address' in data: new_power_address = data['power_address'] if not new_power_address: raise ValueError('Power address is required') if new_power_address != system.power.power_address: record_activity(u'power_address', system.power.power_address, data['power_address']) system.power.power_address = new_power_address changed = True if 'power_user' in data: new_power_user = data['power_user'] or u'' if new_power_user != (system.power.power_user or u''): record_activity(u'power_user', u'********', u'********') system.power.power_user = new_power_user changed = True if 'power_password' in data: new_power_password = data['power_password'] or u'' if new_power_password != (system.power.power_passwd or u''): record_activity(u'power_passwd', u'********', u'********') system.power.power_passwd = new_power_password changed = True if 'power_id' in data: new_power_id = data['power_id'] or u'' if new_power_id != (system.power.power_id or u''): record_activity(u'power_id', system.power.power_id, new_power_id) system.power.power_id = new_power_id changed = True if 'power_quiescent_period' in data: new_qp = int(data['power_quiescent_period']) if new_qp != system.power.power_quiescent_period: record_activity(u'power_quiescent_period', system.power.power_quiescent_period, new_qp) system.power.power_quiescent_period = new_qp changed = True if 'release_action' in data: new_release_action = ReleaseAction.from_string( data['release_action']) if new_release_action != (system.release_action or ReleaseAction.power_off): record_activity( u'release_action', (system.release_action or ReleaseAction.power_off), new_release_action) system.release_action = new_release_action changed = True if 'reprovision_distro_tree' in data: if (not data['reprovision_distro_tree'] or 'id' not in data['reprovision_distro_tree']): new_rpdt = None else: new_rpdt = DistroTree.by_id( data['reprovision_distro_tree']['id']) if new_rpdt != system.reprovision_distro_tree: record_activity(u'reprovision_distro_tree', unicode(system.reprovision_distro_tree), unicode(new_rpdt)) system.reprovision_distro_tree = new_rpdt changed = True if 'location' in data: new_location = data['location'] or None if new_location != system.location: record_activity(u'Location', system.location, new_location) system.location = new_location changed = True if 'lender' in data: new_lender = data['lender'] or None if new_lender != system.lender: record_activity(u'Lender', system.lender, new_lender) system.lender = new_lender changed = True if 'kernel_type' in data: new_kernel_type = KernelType.by_name(data['kernel_type']) if new_kernel_type != system.kernel_type: record_activity(u'Kernel Type', system.kernel_type, new_kernel_type) system.kernel_type = new_kernel_type changed = True if 'hypervisor' in data: if data['hypervisor']: new_hypervisor = Hypervisor.by_name(data['hypervisor']) else: new_hypervisor = None if new_hypervisor != system.hypervisor: record_activity(u'Hypervisor', system.hypervisor, new_hypervisor) system.hypervisor = new_hypervisor changed = True if 'vendor' in data: new_vendor = data['vendor'] or None if new_vendor != system.vendor: record_activity(u'Vendor', system.vendor, new_vendor) system.vendor = new_vendor changed = True if 'model' in data: new_model = data['model'] or None if new_model != system.model: record_activity(u'Model', system.model, new_model) system.model = new_model changed = True if 'serial_number' in data: new_serial_number = data['serial_number'] or None if new_serial_number != system.serial: record_activity(u'Serial Number', system.serial, new_serial_number) system.serial = new_serial_number changed = True if 'mac_address' in data: new_mac_address = data['mac_address'] or None if new_mac_address != system.mac_address: record_activity(u'MAC Address', system.mac_address, new_mac_address) system.mac_address = new_mac_address changed = True if 'memory' in data: new_memory = int(data['memory']) if data['memory'] else None if new_memory != system.memory: record_activity(u'Memory', system.memory, new_memory) system.memory = new_memory changed = True if 'numa_nodes' in data: new_numa_nodes = int( data['numa_nodes']) if data['numa_nodes'] else None if not system.numa: system.numa = Numa() if new_numa_nodes != system.numa.nodes: record_activity(u'NUMA/Nodes', system.numa.nodes, new_numa_nodes) system.numa.nodes = new_numa_nodes changed = True if changed: # XXX clear checksum!? system.date_modified = datetime.datetime.utcnow() response = jsonify(system.__json__()) if renamed: response.headers.add('Location', url('/view/%s' % system.fqdn)) return response
def _from_csv(cls,system,data,csv_type,log): """ Import data from CSV file into System Objects """ for key in data.keys(): if key in cls.reg_keys and key != 'id': if data[key]: newdata = smart_bool(data[key]) else: newdata = None current_data = getattr(system, key, None) if unicode(newdata) != unicode(current_data): setattr(system,key,newdata) system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=key, old=u'%s' % current_data, new=u'%s' % newdata) # import arch if 'arch' in data: arch_objs = [] if data['arch']: arches = data['arch'].split(',') for arch in arches: try: arch_obj = Arch.by_name(arch) except ValueError: raise ValueError("%s: Invalid arch %s" % (system.fqdn, arch)) arch_objs.append(arch_obj) if system.arch != arch_objs: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'arch', old=u'%s' % system.arch, new=u'%s' % arch_objs) system.arch = arch_objs # import cc if 'cc' in data: cc_objs = [] if data['cc']: cc_objs = data['cc'].split(',') if system.cc != cc_objs: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'cc', old=u'%s' % system.cc, new=u'%s' % cc_objs) system.cc = cc_objs # import labController if 'lab_controller' in data: if data['lab_controller']: try: lab_controller = LabController.by_name(data['lab_controller']) except InvalidRequestError: raise ValueError("%s: Invalid lab controller %s" % (system.fqdn, data['lab_controller'])) else: lab_controller = None if system.lab_controller != lab_controller: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'lab_controller', old=u'%s' % system.lab_controller, new=u'%s' % lab_controller) system.lab_controller = lab_controller # import owner if 'owner' in data: if data['owner']: owner = User.by_user_name(data['owner']) if not owner: raise ValueError("%s: Invalid User %s" % (system.fqdn, data['owner'])) else: owner = None if system.owner != owner: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'owner', old=u'%s' % system.owner, new=u'%s' % owner) system.owner = owner # import status if 'status' in data and data['status']: try: systemstatus = SystemStatus.from_string(data['status']) except ValueError: raise ValueError("%s: Invalid Status %s" % (system.fqdn, data['status'])) if system.status != systemstatus: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'status', old=u'%s' % system.status, new=u'%s' % systemstatus) system.status = systemstatus # import type if 'type' in data: if not data['type']: raise ValueError("%s: Invalid Type None" % system.fqdn) try: systemtype = SystemType.from_string(data['type']) except ValueError: raise ValueError("%s: Invalid Type %s" % (system.fqdn, data['type'])) if system.type != systemtype: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'type', old=u'%s' % system.type, new=u'%s' % systemtype) system.type = systemtype # import secret if 'secret' in data: # 'private' used to be a field on system (called 'secret' in the UI # and CSV). The field is replaced by the 'view' permission in the # access policy so CSV export no longer produces 'secret' in its # output. However we still accept it on import for compatibility. # It is mapped to the 'view everybody' rule in the access policy. if not data['secret']: raise ValueError("%s: Invalid secret None" % system.fqdn) secret = smart_bool(data['secret']) view_everybody = system.custom_access_policy.grants_everybody( SystemPermission.view) if secret and view_everybody: # remove 'view everybody' rule for rule in system.custom_access_policy.rules: if rule.permission == SystemPermission.view and rule.everybody: system.record_activity(user=identity.current.user, service=u'HTTP', field=u'Access Policy Rule', action=u'Removed', old=repr(rule)) session.delete(rule) if not secret and not view_everybody: # add rule granting 'view everybody' new_rule = system.custom_access_policy.add_rule(everybody=True, permission=SystemPermission.view) system.record_activity(user=identity.current.user, service=u'HTTP', field=u'Access Policy Rule', action=u'Added', new=repr(new_rule))
def update_system(fqdn): system = _get_system_by_FQDN(fqdn) if not system.can_edit(identity.current.user): raise Forbidden403('Cannot edit system') data = read_json_request(request) # helper for recording activity below def record_activity(field, old, new, action=u'Changed'): system.record_activity(user=identity.current.user, service=u'HTTP', action=action, field=field, old=old, new=new) with convert_internal_errors(): # XXX what a nightmare... need to use a validation/conversion library, # and maybe simplify/relocate the activity recording stuff somehow changed = False renamed = False if 'fqdn' in data: new_fqdn = data['fqdn'].lower() if new_fqdn != system.fqdn: if System.query.filter(System.fqdn == new_fqdn).count(): raise Conflict409('System %s already exists' % new_fqdn) record_activity(u'FQDN', system.fqdn, new_fqdn) system.fqdn = new_fqdn changed = True renamed = True if 'owner' in data and data['owner'].get('user_name') != system.owner.user_name: if not system.can_change_owner(identity.current.user): raise Forbidden403('Cannot change owner') new_owner = User.by_user_name(data['owner'].get('user_name')) if new_owner is None: raise BadRequest400('No such user %s' % data['owner'].get('user_name')) record_activity(u'Owner', system.owner, new_owner) system.owner = new_owner changed = True if 'status' in data: new_status = SystemStatus.from_string(data['status']) if new_status != system.status: record_activity(u'Status', system.status, new_status) system.status = new_status if not new_status.bad and system.status_reason: # clear the status reason for "good" statuses record_activity(u'Status Reason', system.status_reason, None) system.status_reason = None changed = True if 'status_reason' in data: new_reason = data['status_reason'] or None if new_reason and not system.status.bad: raise ValueError('Cannot set status reason when status is %s' % system.status) if new_reason != system.status_reason: record_activity(u'Status Reason', system.status_reason, new_reason) system.status_reason = new_reason changed = True if 'type' in data: new_type = SystemType.from_string(data['type']) if new_type != system.type: record_activity(u'Type', system.type, new_type) system.type = new_type changed = True if 'arches' in data: new_arches = [Arch.by_name(a) for a in (data['arches'] or [])] added_arches = set(new_arches).difference(system.arch) removed_arches = set(system.arch).difference(new_arches) if added_arches or removed_arches: for added_arch in added_arches: record_activity(u'Arch', None, added_arch, u'Added') for removed_arch in removed_arches: record_activity(u'Arch', removed_arch, None, u'Removed') system.arch[:] = new_arches changed = True if 'lab_controller_id' in data: if data['lab_controller_id']: new_lc = LabController.by_id(data['lab_controller_id']) else: new_lc = None if new_lc != system.lab_controller: if system.open_reservation is not None: raise Conflict409('Unable to change lab controller while system ' 'is in use (return the system first)') record_activity(u'Lab Controller', system.lab_controller, new_lc) system.lab_controller = new_lc changed = True # If we're given any power-related keys, need to ensure system.power exists if not system.power and set(['power_type', 'power_address', 'power_user', 'power_password', 'power_id', 'power_quiescent_period'])\ .intersection(data.keys()): system.power = Power() if 'power_type' in data: new_power_type = PowerType.by_name(data['power_type']) if new_power_type != system.power.power_type: if not system.power.power_type: old_power_type = '' else: old_power_type = system.power.power_type.name record_activity(u'power_type', old_power_type, new_power_type.name) system.power.power_type = new_power_type changed = True if 'power_address' in data: new_power_address = data['power_address'] if not new_power_address: raise ValueError('Power address is required') if new_power_address != system.power.power_address: record_activity(u'power_address', system.power.power_address, data['power_address']) system.power.power_address = new_power_address changed = True if 'power_user' in data: new_power_user = data['power_user'] or u'' if new_power_user != (system.power.power_user or u''): record_activity(u'power_user', u'********', u'********') system.power.power_user = new_power_user changed = True if 'power_password' in data: new_power_password = data['power_password'] or u'' if new_power_password != (system.power.power_passwd or u''): record_activity(u'power_passwd', u'********', u'********') system.power.power_passwd = new_power_password changed = True if 'power_id' in data: new_power_id = data['power_id'] or u'' if new_power_id != (system.power.power_id or u''): record_activity(u'power_id', system.power.power_id, new_power_id) system.power.power_id = new_power_id changed = True if 'power_quiescent_period' in data: new_qp = int(data['power_quiescent_period']) if new_qp != system.power.power_quiescent_period: record_activity(u'power_quiescent_period', system.power.power_quiescent_period, new_qp) system.power.power_quiescent_period = new_qp changed = True if 'release_action' in data: new_release_action = ReleaseAction.from_string(data['release_action']) if new_release_action != (system.release_action or ReleaseAction.power_off): record_activity(u'release_action', (system.release_action or ReleaseAction.power_off), new_release_action) system.release_action = new_release_action changed = True if 'reprovision_distro_tree' in data: if (not data['reprovision_distro_tree'] or 'id' not in data['reprovision_distro_tree']): new_rpdt = None else: new_rpdt = DistroTree.by_id(data['reprovision_distro_tree']['id']) if new_rpdt != system.reprovision_distro_tree: record_activity(u'reprovision_distro_tree', unicode(system.reprovision_distro_tree), unicode(new_rpdt)) system.reprovision_distro_tree = new_rpdt changed = True if 'location' in data: new_location = data['location'] or None if new_location != system.location: record_activity(u'Location', system.location, new_location) system.location = new_location changed = True if 'lender' in data: new_lender = data['lender'] or None if new_lender != system.lender: record_activity(u'Lender', system.lender, new_lender) system.lender = new_lender changed = True if 'kernel_type' in data: new_kernel_type = KernelType.by_name(data['kernel_type']) if new_kernel_type != system.kernel_type: record_activity(u'Kernel Type', system.kernel_type, new_kernel_type) system.kernel_type = new_kernel_type changed = True if 'hypervisor' in data: if data['hypervisor']: new_hypervisor = Hypervisor.by_name(data['hypervisor']) else: new_hypervisor = None if new_hypervisor != system.hypervisor: record_activity(u'Hypervisor', system.hypervisor, new_hypervisor) system.hypervisor = new_hypervisor changed = True if 'vendor' in data: new_vendor = data['vendor'] or None if new_vendor != system.vendor: record_activity(u'Vendor', system.vendor, new_vendor) system.vendor = new_vendor changed = True if 'model' in data: new_model = data['model'] or None if new_model != system.model: record_activity(u'Model', system.model, new_model) system.model = new_model changed = True if 'serial_number' in data: new_serial_number = data['serial_number'] or None if new_serial_number != system.serial: record_activity(u'Serial Number', system.serial, new_serial_number) system.serial = new_serial_number changed = True if 'mac_address' in data: new_mac_address = data['mac_address'] or None if new_mac_address != system.mac_address: record_activity(u'MAC Address', system.mac_address, new_mac_address) system.mac_address = new_mac_address changed = True if 'memory' in data: new_memory = int(data['memory']) if data['memory'] else None if new_memory != system.memory: record_activity(u'Memory', system.memory, new_memory) system.memory = new_memory changed = True if 'numa_nodes' in data: new_numa_nodes = int(data['numa_nodes']) if data['numa_nodes'] else None if not system.numa: system.numa = Numa() if new_numa_nodes != system.numa.nodes: record_activity(u'NUMA/Nodes', system.numa.nodes, new_numa_nodes) system.numa.nodes = new_numa_nodes changed = True if changed: # XXX clear checksum!? system.date_modified = datetime.datetime.utcnow() response = jsonify(system.__json__()) if renamed: response.headers.add('Location', url('/view/%s' % system.fqdn)) return response