示例#1
0
    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))
示例#2
0
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
示例#3
0
    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))
示例#4
0
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