Skip to content

Commit

Permalink
Merge pull request #391 from nofusscomputing/software-os-installation…
Browse files Browse the repository at this point in the history
…s-endpoints
  • Loading branch information
jon-nfc authored Nov 22, 2024
2 parents b160b36 + a2752bf commit 916bc9c
Show file tree
Hide file tree
Showing 15 changed files with 1,915 additions and 49 deletions.
2 changes: 2 additions & 0 deletions app/api/urls_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,11 @@
router.register('itam/device/(?P<device_id>[0-9]+)/notes', notes_v2.ViewSet, basename='_api_v2_device_notes')
router.register('itam/inventory', inventory.ViewSet, basename='_api_v2_inventory')
router.register('itam/operating_system', operating_system_v2.ViewSet, basename='_api_v2_operating_system')
router.register('itam/operating_system/(?P<operating_system_id>[0-9]+)/installs', device_operating_system.ViewSet, basename='_api_v2_operating_system_installs')
router.register('itam/operating_system/(?P<operating_system_id>[0-9]+)/notes', notes_v2.ViewSet, basename='_api_v2_operating_system_notes')
router.register('itam/operating_system/(?P<operating_system_id>[0-9]+)/version', operating_system_version_v2.ViewSet, basename='_api_v2_operating_system_version')
router.register('itam/software', software_v2.ViewSet, basename='_api_v2_software')
router.register('itam/software/(?P<software_id>[0-9]+)/installs', device_software_v2.ViewSet, basename='_api_v2_software_installs')
router.register('itam/software/(?P<software_id>[0-9]+)/notes', notes_v2.ViewSet, basename='_api_v2_software_notes')
router.register('itam/software/(?P<software_id>[0-9]+)/version', software_version_v2.ViewSet, basename='_api_v2_software_version')

Expand Down
47 changes: 47 additions & 0 deletions app/api/v2/tests/unit/abstract/test_view_set_unit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

from django.test import TestCase



class ViewSetAttributesUnit:
""" Unit Tests For View Set attributes.
These tests ensure that View sets contian the required attributesthat are
used by the API .
"""


def test_attribute_exists_page_layout(self):
"""Attrribute Test, Exists
Ensure attribute `page_layout` exists
"""

pass


def test_attribute_type_page_layout(self):
"""Attrribute Test, Type
Ensure attribute `page_layout` is of type `list`
"""

pass


def test_attribute_not_callable_page_layout(self):
"""Attrribute Test, Not Callable
Attribute must be a property
Ensure attribute `page_layout` is not callable.
"""

pass

# other tests required
# - filterset_fields
# - metadata_class
# - search_fields
# - documentation
# - model_documentation or is in `model.documentation`
3 changes: 2 additions & 1 deletion app/itam/models/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ def get_url_kwargs(self) -> dict:

return {
'device_id': self.device.id,
'pk': self.software.id
'pk': self.id
}


Expand Down Expand Up @@ -714,6 +714,7 @@ class Meta:
]

table_fields: list = [
'device',
'operating_system_version',
'version',
'installdate',
Expand Down
68 changes: 61 additions & 7 deletions app/itam/serializers/device_operating_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@

from api.serializers import common

from core import exceptions as centurion_exception
from core.fields.badge import Badge, BadgeField

from itam.models.device import Device, DeviceOperatingSystem
from itam.serializers.device import DeviceBaseSerializer
from itam.serializers.operating_system_version import OperatingSystemVersionBaseSerializer
from itam.serializers.operating_system_version import OperatingSystem, OperatingSystemVersionBaseSerializer



Expand Down Expand Up @@ -59,9 +60,22 @@ class DeviceOperatingSystemModelSerializer(

def get_url(self, obj) -> dict:

return {
'_self': obj.get_url( request = self._context['view'].request )
}
if self._context.get('view', None):

if self.context['view'].kwargs.get('device_id'):

return {
'_self': obj.get_url( request = self._context['view'].request )
}

elif self.context['view'].kwargs.get('operating_system_id'):

return {
'_self': reverse("v2:_api_v2_operating_system_installs-detail", request = self._context['view'].request, kwargs = {
'operating_system_id': obj.operating_system_version.operating_system.pk,
'pk': obj.pk
} )
}



Expand Down Expand Up @@ -93,11 +107,51 @@ class Meta:

def validate(self, data):

device = Device.objects.get(id=self._context['view'].kwargs['device_id'])
if self._context['view'].kwargs.get('device_id', None):

device = Device.objects.get(id = (self._context['view'].kwargs['device_id']))

data['device'] = device

# data['organization'] = device.organization


if (
not data.get('device', None)
and not getattr(self.instance, 'device', None)
):

raise centurion_exception.ValidationError(
detail = {
'device': 'this field is required'
},
code = 'required'
)


# if self._context['view'].kwargs.get('operating_system_id', None):

# operating_system = OperatingSystem.objects.get(id = int(self._context['view'].kwargs['operating_system_id']))

# data['operating_system'] = operating_system


data['organization'] = data['device'].organization



if (
not data.get('operating_system_version', None)
and not getattr(self.instance, 'operating_system_version', None)
):

data['device_id'] = device.id
raise centurion_exception.ValidationError(
detail = {
'operating_system': 'this field is required'
},
code = 'required'
)

data['organization'] = device.organization

validate = super().validate(data)

Expand Down
79 changes: 61 additions & 18 deletions app/itam/serializers/device_software.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@

from api.serializers import common

from core import exceptions as centurion_exception
from core.fields.badge import Badge, BadgeField

from itam.models.device import Device, DeviceSoftware
from itam.serializers.device import DeviceBaseSerializer
from itam.serializers.software import SoftwareBaseSerializer
from itam.serializers.software import Software, SoftwareBaseSerializer
from itam.serializers.software_category import SoftwareCategoryBaseSerializer
from itam.serializers.software_version import SoftwareVersionBaseSerializer

Expand Down Expand Up @@ -59,15 +60,33 @@ class DeviceSoftwareModelSerializer(

def get_url(self, obj) -> dict:

return {
'_self': obj.get_url( request = self._context['view'].request )
}
if 'view' in self._context:

if 'software_id' in self._context['view'].kwargs:

return {
'_self': reverse("v2:_api_v2_software_installs-detail", request = self._context['view'].request, kwargs = {
'software_id': obj.software.pk,
'pk': obj.pk
} )
}

elif 'device_id' in self._context['view'].kwargs:

return {
'_self': obj.get_url( request = self._context['view'].request )
}



action_badge = BadgeField(label='Action')

category = SoftwareCategoryBaseSerializer(many=False, read_only=True, source='software.category')

device = serializers.PrimaryKeyRelatedField(write_only = True, required = False, queryset=Device.objects.all() )

software = serializers.PrimaryKeyRelatedField(write_only = True, required = False, queryset=Software.objects.all() )


class Meta:

Expand Down Expand Up @@ -100,32 +119,56 @@ class Meta:
'_urls',
]

def __init__(self, instance=None, data=empty, **kwargs):

super().__init__(instance=instance, data=data, **kwargs)
def validate(self, data):

if isinstance(self.instance, DeviceSoftware):

self.fields.fields['device'].read_only = True

self.fields.fields['software'].read_only = True
if 'view' in self._context:

if 'device_id' in self._context['view'].kwargs:

device = Device.objects.get(id=self._context['view'].kwargs['device_id'])

def is_valid(self, *, raise_exception=False):
data['device'] = device
data['organization'] = device.organization

is_valid = super().is_valid(raise_exception=raise_exception)
if 'software_id' in self._context['view'].kwargs:

if 'view' in self._context:
software = Software.objects.get(id=int(self._context['view'].kwargs['software_id']))

if 'device_id' in self._context['view'].kwargs:
data['software'] = software

device = Device.objects.get(id=self._context['view'].kwargs['device_id'])
if 'device' in data:

data['organization'] = data['device'].organization


if(
not data.get('device')
and not getattr(self.instance, 'device', None)
):

raise centurion_exception.ValidationError(
detail = {
'device': 'This field is required'
},
code = 'required'
)


if(
not data.get('software')
and not getattr(self.instance, 'software', None)
):

self.validated_data['device'] = device
self.validated_data['organization'] = device.organization
raise centurion_exception.ValidationError(
detail = {
'software': 'This field is required',
},
code = 'required'
)

return is_valid
return data



Expand Down
1 change: 1 addition & 0 deletions app/itam/serializers/operating_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def get_url(self, item) -> dict:
'model_id': item.pk
}
),
'installations': reverse("v2:_api_v2_operating_system_installs-list", request=self._context['view'].request, kwargs={'operating_system_id': item.pk}),
'notes': reverse("v2:_api_v2_operating_system_notes-list", request=self._context['view'].request, kwargs={'operating_system_id': item.pk}),
'tickets': reverse(
"v2:_api_v2_item_tickets-list",
Expand Down
1 change: 1 addition & 0 deletions app/itam/serializers/software.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def get_url(self, item) -> dict:
'model_id': item.pk
}
),
'installations': reverse("v2:_api_v2_software_installs-list", request=self._context['view'].request, kwargs={'software_id': item.pk}),
'notes': reverse("v2:_api_v2_software_notes-list", request=self._context['view'].request, kwargs={'software_id': item.pk}),
'publisher': reverse("v2:_api_v2_manufacturer-list", request=self._context['view'].request),
'services': 'ToDo',
Expand Down
Loading

0 comments on commit 916bc9c

Please sign in to comment.