def to_internal_value(self, data): req = self.context['request'] # Value of 0 represents live, and is the default version = get_version(req) data['version'] = self.context.get('version') or version location = data.pop('location') data['site'] = location['site'] if location['tag'] == 'rack-mount': data['rack'] = location['rack'] # data['rack_position'] = location['position'] ??? data['rack_position'] = location['rack_position'] elif location['tag'] == 'chassis-mount': data['blade_chassis'] = location['asset'] data['slot'] = location['slot'] data['rack'] = location['rack'] data['rack_position'] = None elif location['tag'] == 'offline': data['rack'] = None data['rack_position'] = None else: raise serializers.ValidationError( "Invalid location given for this asset." ) return super(AssetSerializer, self).to_internal_value(data)
def validate_asset_number(self, value): if value is None and get_version(self.context['request']) == 0: max_an = Asset.objects.all().aggregate(Max('asset_number')) asset_number = (max_an['asset_number__max'] or 100000) + 1 return asset_number return value
def get_queryset(self): queryset = Asset.objects.filter(commissioned=None) user = self.request.query_params.get('username', None) time_from = self.request.query_params.get('timestamp_from', None) time_to = self.request.query_params.get('timestamp_to', None) decommissioned_by = self.request.query_params.get( 'decommissioned_by', None) site = get_site(self.request) version = get_version(self.request) if site: queryset = queryset.filter(site__id=site) if user: queryset = queryset.filter(owner__username=user) if time_from and time_to: dt_from = dateparse.parse_datetime(time_from) dt_to = dateparse.parse_datetime(time_to) queryset = queryset.filter( decommissioned_timestamp__range=(dt_from, dt_to)) if decommissioned_by: queryset = queryset.filter( Q(decommissioned_by__username__icontains=decommissioned_by) | Q(decommissioned_by__first_name__icontains=decommissioned_by) | Q(decommissioned_by__last_name__icontains=decommissioned_by)) queryset = queryset.filter(version__parent_id__in=(0, version)) return queryset
def get_queryset(self): combined = Asset.objects.filter( commissioned=Asset.Decommissioned.COMMISSIONED) version = ChangePlan.objects.get(id=get_version(self.request)) versioned = versioned_queryset(combined, version, Asset.IDENTITY_FIELDS) return versioned
def perform_create(self, serializer): super(CreateAndLogMixin, self).perform_create(serializer) if(get_version(self.request)) != 0: return entry = ActionLog.objects.create( **create_dict(self, ActionLog.Action.CREATE, serializer.data['id']) ) entry.save()
def perform_destroy(self, instance): entry = ActionLog.objects.create( **create_dict(self, ActionLog.Action.DESTROY, instance.id), ) if(get_version(self.request)) == 0: entry.save() try: super(DeleteAndLogMixin, self).perform_destroy(instance) except serializers.ValidationError as e: entry.delete() raise e
def get_queryset(self): version = ChangePlan.objects.get(id=get_version(self.request)) queryset = Asset.objects.all() datacenter_id = self.request.query_params.get('site_id', None) if datacenter_id is not None: queryset = queryset.filter(site_id=datacenter_id) rack_id = self.request.query_params.get('rack_id', None) if rack_id is not None: rack = Rack.objects.filter(id=rack_id).first() if rack is not None: queryset = queryset.filter(rack__rack=rack.rack) if 'asset_id' in self.request.query_params: queryset = queryset.exclude( id=self.request.query_params['asset_id']) queryset = versioned_queryset(queryset, version, Asset.IDENTITY_FIELDS) return queryset
def perform_update(self, serializer): diffs = [] old = model_to_dict(serializer.instance) super(UpdateAndLogMixin, self).perform_update(serializer) if(get_version(self.request)) != 0: return new = model_to_dict(serializer.Meta.model.objects.get(id=old['id'])) for key in new: if key == 'comment': continue if key in old and new[key] != old[key]: diffs.append((key, old[key], new[key])) entries = [] for diff in diffs: entries.append(ActionLog.objects.create( **create_dict(self, ActionLog.Action.UPDATE, old['id']), field_changed=diff[0], old_value=str(diff[1]), new_value=str(diff[2]) )) for entry in entries: entry.save()
def filter_queryset(self, request, queryset, view): version = get_version(request) return versioned_queryset( queryset, ChangePlan.objects.get(id=version), view.serializer_class.Meta.model.IDENTITY_FIELDS)
def get(self, request, *args, **kwargs): data = NetworkPortResource( get_version(request), request.user).export(version_id=get_version(request)) return Response(data, HTTP_200_OK)
def get(self, request, *args, **kwargs): data = AssetResource(get_version(request), request.user) \ .export(queryset=self.filter_queryset(self.get_queryset())) return Response(data, HTTP_200_OK)
def post(self, request, *args, **kwargs): try: if not request.user.is_superuser: if not request.user.permission.asset_perm: raise serializers.ValidationError( "You don't have permission.") data = request.data force = bool(request.query_params['force']) file = data.get('file') dataset = Dataset().load(str(file.read(), 'utf-8-sig'), format="csv") if not dataset.headers == [ 'src_hostname', 'src_port', 'src_mac', 'dest_hostname', 'dest_port' ]: return Response( { "status": "error", "errors": [{ "errors": "Improperly Formatted CSV" }] }, HTTP_200_OK) result = NetworkPortResource(get_version(request), request.user, True).import_data(dataset, dry_run=not force) errors = get_errors( result, lambda row, error: "{} -> {}: {}".format( row.errors[0].row['src_hostname'], row.errors[0].row[ 'dest_hostname'], str(error.error.detail[0] if hasattr(error.error, "detail") and isinstance( error.error.detail, list) else error.error))) if len(errors) > 0: return Response({ "status": "error", "errors": errors }, HTTP_200_OK) elif not force: resource = NetworkPortResource(get_version(request), request.user, False) result = resource.import_data(dataset) errors = get_errors( result, lambda row, error: "{} -> {}: {}".format( row.errors[0].row['src_hostname'], row.errors[0].row[ 'dest_hostname'], str(error.error.detail[0] if hasattr(error.error, "detail") and isinstance( error.error.detail, list) else error.error))) if len(errors) > 0: return Response({ "status": "error", "errors": errors }, HTTP_200_OK) try: changeplan = ChangePlan.objects.get(owner=request.user, name="_BULK_IMPORT_" + str(id(resource))) except ChangePlan.DoesNotExist: return Response({"status": "skip"}, status=HTTP_200_OK) live = ChangePlan.objects.get(id=0) messages = [] network_diff = get_network(changeplan, live) for diff in network_diff: if diff['live']: messages += [ "#{} – {}: {}".format(diff['live'].asset.hostname, diff['live'].label.name, message) for message in diff['messages'] ] else: messages += [ "#{} – {}: {}".format(diff['live'].asset.hostname, diff['new'].label.name, message) for message in diff['messages'] ] response = { 'status': "diff", 'network': messages, } for model in (Powered, NetworkPort, Asset, PDU, Rack): if model == Asset: model.objects.filter( version=changeplan, itmodel__type=ITModel.Type.BLADE).delete() model.objects.filter(version=changeplan).delete() changeplan.delete() return Response(response, status=HTTP_200_OK) else: return Response({}, status=HTTP_200_OK) except Exception as e: print(e) return Response( { "status": "error", "errors": [{ "errors": "Unexpected Error! Is your CSV data valid?" }] }, HTTP_200_OK)
def post(self, request, *args, **kwargs): try: if not request.user.is_superuser: if not request.user.permission.asset_perm: raise serializers.ValidationError( "You don't have permission.") data = request.data force = bool(request.query_params['force']) file = data.get('file') dataset = Dataset().load(str(file.read(), 'utf-8-sig'), format="csv") if not set(dataset.headers) == { 'asset_number', 'hostname', 'datacenter', 'offline_site', 'rack', 'rack_position', 'chassis_number', 'chassis_slot', 'vendor', 'model_number', 'owner', 'comment', 'power_port_connection_1', 'power_port_connection_2', 'custom_display_color', 'custom_cpu', 'custom_memory', 'custom_storage' }: return Response( { "status": "error", "errors": [{ "errors": "Improperly Formatted CSV" }] }, HTTP_200_OK) result = AssetResource(get_version(request), request.user, True).import_data(dataset, dry_run=not force) errors = get_errors( result, lambda row, error: "{} {}: {}".format( row.errors[0].row['asset_number'], row.errors[0].row[ 'hostname'], str(error.error.detail[0] if hasattr(error.error, "detail") and isinstance( error.error.detail, list) else error.error))) if len(errors) > 0: return Response({ "status": "error", "errors": errors }, HTTP_200_OK) elif not force: resource = AssetResource(get_version(request), request.user, False) result = resource.import_data(dataset) errors = get_errors( result, lambda row, error: "{} {}: {}".format( row.errors[0].row['asset_number'], row.errors[0].row[ 'hostname'], str(error.error.detail[0] if hasattr(error.error, "detail") and isinstance( error.error.detail, list) else error.error))) if len(errors) > 0: return Response({ "status": "error", "errors": errors }, HTTP_200_OK) try: changeplan = ChangePlan.objects.get(owner=request.user, name="_BULK_IMPORT_" + str(id(resource))) except ChangePlan.DoesNotExist: return Response( { "status": "diff", "asset": ["No Changes"], "power": [] }, status=HTTP_200_OK) live = ChangePlan.objects.get(id=0) asset_messages = [] power_messages = [] asset_diff = get_asset(changeplan, live) power_diff = get_power(changeplan, live) for diff in asset_diff: if diff['live']: asset_messages += [ "#{}: {}".format(diff['live'].asset_number, message) for message in diff['messages'] ] else: asset_messages += [ '{}: {}'.format(diff['new'].hostname, message) for message in diff['messages'] ] for diff in power_diff: if diff['live']: power_messages += [ "#{}: {}".format(diff['live'].asset.asset_number, message) for message in diff['messages'] ] else: power_messages += [ "#{}: {}".format( diff['new'].asset.asset_number or diff['new'].asset, message) for message in diff['messages'] ] response = { 'status': "diff", 'asset': asset_messages, 'power': power_messages, } for model in (Powered, NetworkPort, Asset, PDU, Rack): if model == Asset: model.objects.filter( version=changeplan, itmodel__type=ITModel.Type.BLADE).delete() model.objects.filter(version=changeplan).delete() changeplan.delete() return Response(response, status=HTTP_200_OK) else: return Response({}, status=HTTP_200_OK) except Exception as e: print(e) return Response( { "status": "error", "errors": [{ "errors": "Unexpected Error! Is your CSV data valid?" }] }, HTTP_200_OK)