Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
c496d10c1a | |||
3993cc96a5 | |||
a4b37b34a9 | |||
2f55024f0b | |||
213644a51a | |||
281d839801 | |||
4fd157a785 | |||
968b3a0f92 | |||
f5ba608ed1 |
2
.cz.yaml
2
.cz.yaml
@ -4,5 +4,5 @@ commitizen:
|
||||
prerelease_offset: 1
|
||||
tag_format: $version
|
||||
update_changelog_on_bump: false
|
||||
version: 1.0.0-b4
|
||||
version: 1.0.0-b5
|
||||
version_scheme: semver
|
||||
|
@ -151,7 +151,7 @@ Docker Container:
|
||||
script:
|
||||
- if [ "$CI_COMMIT_BRANCH" == "development" ] ; then RELEASE_CHANGELOG=$(cz bump --changelog --changelog-to-stdout --prerelease beta); else RELEASE_CHANGELOG=$(cz bump --changelog --changelog-to-stdout); fi
|
||||
- RELEASE_VERSION_NEW=$(cz version --project)
|
||||
- RELEASE_TAG=$RELEASE_VERSION_NEW
|
||||
- export RELEASE_TAG=$RELEASE_VERSION_NEW
|
||||
- echo "[DEBUG] RELEASE_VERSION_CURRENT[$RELEASE_VERSION_CURRENT]"
|
||||
- echo "[DEBUG] RELEASE_CHANGELOG[$RELEASE_CHANGELOG]"
|
||||
- echo "[DEBUG] RELEASE_VERSION_NEW[$RELEASE_VERSION_NEW]"
|
||||
|
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,3 +1,14 @@
|
||||
## 1.0.0-b5 (2024-07-31)
|
||||
|
||||
### Feat
|
||||
|
||||
- **api**: Add device config groups to devices
|
||||
- **api**: Ability to fetch configgroups from api along with config
|
||||
|
||||
### Fix
|
||||
|
||||
- **api**: Ensure device groups is read only
|
||||
|
||||
## 1.0.0-b4 (2024-07-29)
|
||||
|
||||
### Feat
|
||||
|
86
app/api/serializers/config.py
Normal file
86
app/api/serializers/config.py
Normal file
@ -0,0 +1,86 @@
|
||||
from rest_framework import serializers
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
from config_management.models.groups import ConfigGroups
|
||||
|
||||
|
||||
|
||||
class ParentGroupSerializer(serializers.ModelSerializer):
|
||||
|
||||
url = serializers.SerializerMethodField('get_url')
|
||||
|
||||
|
||||
class Meta:
|
||||
model = ConfigGroups
|
||||
fields = [
|
||||
'id',
|
||||
'name',
|
||||
'url',
|
||||
]
|
||||
read_only_fields = [
|
||||
'id',
|
||||
'name',
|
||||
'url',
|
||||
]
|
||||
|
||||
|
||||
def get_url(self, obj):
|
||||
|
||||
request = self.context.get('request')
|
||||
|
||||
return request.build_absolute_uri(reverse("API:_api_config_group", args=[obj.pk]))
|
||||
|
||||
|
||||
|
||||
class ConfigGroupsSerializerBase(serializers.ModelSerializer):
|
||||
|
||||
parent = ParentGroupSerializer(read_only=True)
|
||||
url = serializers.SerializerMethodField('get_url')
|
||||
|
||||
|
||||
class Meta:
|
||||
model = ConfigGroups
|
||||
fields = [
|
||||
'id',
|
||||
'parent',
|
||||
'name',
|
||||
'config',
|
||||
'url',
|
||||
]
|
||||
read_only_fields = [
|
||||
'id',
|
||||
'name',
|
||||
'config',
|
||||
'url',
|
||||
]
|
||||
|
||||
|
||||
def get_url(self, obj):
|
||||
|
||||
request = self.context.get('request')
|
||||
|
||||
return request.build_absolute_uri(reverse("API:_api_config_group", args=[obj.pk]))
|
||||
|
||||
|
||||
|
||||
class ConfigGroupsSerializer(ConfigGroupsSerializerBase):
|
||||
|
||||
|
||||
class Meta:
|
||||
model = ConfigGroups
|
||||
depth = 1
|
||||
fields = [
|
||||
'id',
|
||||
'parent',
|
||||
'name',
|
||||
'config',
|
||||
'url',
|
||||
]
|
||||
read_only_fields = [
|
||||
'id',
|
||||
'parent',
|
||||
'name',
|
||||
'config',
|
||||
'url',
|
||||
]
|
||||
|
@ -1,9 +1,38 @@
|
||||
from django.urls import reverse
|
||||
|
||||
from itam.models.device import Device
|
||||
from rest_framework import serializers
|
||||
|
||||
from api.serializers.config import ParentGroupSerializer
|
||||
|
||||
from config_management.models.groups import ConfigGroupHosts
|
||||
|
||||
from itam.models.device import Device
|
||||
|
||||
|
||||
|
||||
class DeviceConfigGroupsSerializer(serializers.ModelSerializer):
|
||||
|
||||
name = serializers.CharField(source='group.name', read_only=True)
|
||||
|
||||
url = serializers.HyperlinkedIdentityField(
|
||||
view_name="API:_api_config_group", format="html"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
|
||||
model = ConfigGroupHosts
|
||||
|
||||
fields = [
|
||||
'id',
|
||||
'name',
|
||||
'url',
|
||||
|
||||
]
|
||||
read_only_fields = [
|
||||
'id',
|
||||
'name',
|
||||
'url',
|
||||
]
|
||||
|
||||
|
||||
class DeviceSerializer(serializers.ModelSerializer):
|
||||
@ -14,6 +43,8 @@ class DeviceSerializer(serializers.ModelSerializer):
|
||||
|
||||
config = serializers.SerializerMethodField('get_device_config')
|
||||
|
||||
groups = DeviceConfigGroupsSerializer(source='configgrouphosts_set', many=True, read_only=True)
|
||||
|
||||
def get_device_config(self, device):
|
||||
|
||||
request = self.context.get('request')
|
||||
@ -22,11 +53,29 @@ class DeviceSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Device
|
||||
fields = '__all__'
|
||||
|
||||
read_only_fields = [
|
||||
'inventorydate',
|
||||
depth = 1
|
||||
fields = [
|
||||
'id',
|
||||
'is_global',
|
||||
'slug',
|
||||
'name',
|
||||
'config',
|
||||
'serial_number',
|
||||
'uuid',
|
||||
'inventorydate',
|
||||
'created',
|
||||
'modified',
|
||||
'groups',
|
||||
'organization',
|
||||
'url',
|
||||
]
|
||||
|
||||
read_only_fields = [
|
||||
'id',
|
||||
'config',
|
||||
'inventorydate',
|
||||
'created',
|
||||
'modified',
|
||||
'groups',
|
||||
'url',
|
||||
]
|
||||
|
||||
|
@ -3,7 +3,7 @@ from django.urls import path
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from rest_framework.urlpatterns import format_suffix_patterns
|
||||
|
||||
from .views import access, index
|
||||
from .views import access, config, index
|
||||
|
||||
from .views.itam import software, config as itam_config
|
||||
from .views.itam.device import DeviceViewSet
|
||||
@ -24,6 +24,9 @@ router.register('software', software.SoftwareViewSet, basename='software')
|
||||
urlpatterns = [
|
||||
path("config/<slug:slug>/", itam_config.View.as_view(), name="_api_device_config"),
|
||||
|
||||
path("configuration/", config.ConfigGroupsList.as_view(), name='_api_config_groups'),
|
||||
path("configuration/<int:pk>", config.ConfigGroupsDetail.as_view(), name='_api_config_group'),
|
||||
|
||||
path("device/inventory", inventory.Collect.as_view(), name="_api_device_inventory"),
|
||||
|
||||
path("organization/", access.OrganizationList.as_view(), name='_api_orgs'),
|
||||
|
54
app/api/views/config.py
Normal file
54
app/api/views/config.py
Normal file
@ -0,0 +1,54 @@
|
||||
from drf_spectacular.utils import extend_schema, extend_schema_view
|
||||
|
||||
from rest_framework import generics
|
||||
|
||||
from api.serializers.config import ConfigGroupsSerializer
|
||||
from api.views.mixin import OrganizationPermissionAPI
|
||||
|
||||
from config_management.models.groups import ConfigGroups
|
||||
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
get=extend_schema(
|
||||
summary = "Fetch Config groups",
|
||||
description="Returns a list of Config Groups."
|
||||
),
|
||||
)
|
||||
class ConfigGroupsList(generics.ListAPIView):
|
||||
|
||||
permission_classes = [
|
||||
OrganizationPermissionAPI
|
||||
]
|
||||
|
||||
queryset = ConfigGroups.objects.all()
|
||||
lookup_field = 'pk'
|
||||
serializer_class = ConfigGroupsSerializer
|
||||
|
||||
|
||||
def get_view_name(self):
|
||||
return "Config Groups"
|
||||
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
get=extend_schema(
|
||||
summary = "Get A Config Group",
|
||||
# responses = {}
|
||||
),
|
||||
)
|
||||
class ConfigGroupsDetail(generics.RetrieveAPIView):
|
||||
|
||||
permission_classes = [
|
||||
OrganizationPermissionAPI
|
||||
]
|
||||
|
||||
queryset = ConfigGroups.objects.all()
|
||||
lookup_field = 'pk'
|
||||
serializer_class = ConfigGroupsSerializer
|
||||
|
||||
|
||||
def get_view_name(self):
|
||||
return "Config Group"
|
||||
|
||||
|
@ -27,6 +27,7 @@ class Index(viewsets.ViewSet):
|
||||
{
|
||||
# "teams": reverse("_api_teams", request=request),
|
||||
"devices": reverse("API:device-list", request=request),
|
||||
"config_groups": reverse("API:_api_config_groups", request=request),
|
||||
"organizations": reverse("API:_api_orgs", request=request),
|
||||
"software": reverse("API:software-list", request=request),
|
||||
}
|
||||
|
@ -0,0 +1,224 @@
|
||||
import pytest
|
||||
import unittest
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from access.models import Organization, Team, TeamUsers, Permission
|
||||
|
||||
from app.tests.abstract.models import TenancyModel
|
||||
|
||||
from config_management.models.groups import ConfigGroups
|
||||
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class ConfigGroupsAPI(
|
||||
TestCase,
|
||||
):
|
||||
|
||||
model = ConfigGroups
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
"""Setup Test
|
||||
|
||||
1. Create an organization for user and item
|
||||
2. Create an item
|
||||
|
||||
"""
|
||||
|
||||
self.organization = Organization.objects.create(name='test_org')
|
||||
|
||||
|
||||
self.item = self.model.objects.create(
|
||||
organization = self.organization,
|
||||
name = 'one',
|
||||
config = dict({"key": "one", "existing": "dont_over_write"})
|
||||
)
|
||||
|
||||
self.second_item = self.model.objects.create(
|
||||
organization = self.organization,
|
||||
name = 'one_two',
|
||||
config = dict({"key": "two"}),
|
||||
parent = self.item
|
||||
)
|
||||
|
||||
self.url_view_kwargs = {'pk': self.second_item.id}
|
||||
|
||||
view_permissions = Permission.objects.get(
|
||||
codename = 'view_' + self.model._meta.model_name,
|
||||
content_type = ContentType.objects.get(
|
||||
app_label = self.model._meta.app_label,
|
||||
model = self.model._meta.model_name,
|
||||
)
|
||||
)
|
||||
|
||||
view_team = Team.objects.create(
|
||||
team_name = 'view_team',
|
||||
organization = self.organization,
|
||||
)
|
||||
|
||||
view_team.permissions.set([view_permissions])
|
||||
|
||||
self.view_user = User.objects.create_user(username="test_user_view", password="password")
|
||||
teamuser = TeamUsers.objects.create(
|
||||
team = view_team,
|
||||
user = self.view_user
|
||||
)
|
||||
|
||||
client = Client()
|
||||
url = reverse('API:_api_config_group', kwargs=self.url_view_kwargs)
|
||||
|
||||
|
||||
client.force_login(self.view_user)
|
||||
response = client.get(url)
|
||||
|
||||
self.api_data = response.data
|
||||
|
||||
|
||||
def test_api_field_exists_id(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
id field must exist
|
||||
"""
|
||||
|
||||
assert 'id' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_id(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
id field must be int
|
||||
"""
|
||||
|
||||
assert type(self.api_data['id']) is int
|
||||
|
||||
|
||||
def test_api_field_exists_parent(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
parent field must exist
|
||||
"""
|
||||
|
||||
assert 'parent' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_parent(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
parent field must be dict
|
||||
"""
|
||||
|
||||
assert type(self.api_data['parent']) is dict
|
||||
|
||||
|
||||
def test_api_field_exists_name(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
name field must exist
|
||||
"""
|
||||
|
||||
assert 'name' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_name(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
name field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['name']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_config(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
config field must exist
|
||||
"""
|
||||
|
||||
assert 'config' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_config(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
config field must be dict
|
||||
"""
|
||||
|
||||
assert type(self.api_data['config']) is dict
|
||||
|
||||
|
||||
def test_api_field_exists_url(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
url field must exist
|
||||
"""
|
||||
|
||||
assert 'url' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_url(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
url field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['url']) is str
|
||||
|
||||
|
||||
|
||||
def test_api_field_exists_parent_id(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
parent.id field must exist
|
||||
"""
|
||||
|
||||
assert 'id' in self.api_data['parent']
|
||||
|
||||
|
||||
def test_api_field_type_parent_id(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
parent.id field must be int
|
||||
"""
|
||||
|
||||
assert type(self.api_data['parent']['id']) is int
|
||||
|
||||
|
||||
def test_api_field_exists_parent_name(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
parent.name field must exist
|
||||
"""
|
||||
|
||||
assert 'name' in self.api_data['parent']
|
||||
|
||||
|
||||
def test_api_field_type_parent_name(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
parent.name field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['parent']['name']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_parent_url(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
parent.url field must exist
|
||||
"""
|
||||
|
||||
assert 'url' in self.api_data['parent']
|
||||
|
||||
|
||||
def test_api_field_type_parent_url(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
parent.url field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['parent']['url']) is str
|
522
app/itam/tests/unit/device/test_device_api.py
Normal file
522
app/itam/tests/unit/device/test_device_api.py
Normal file
@ -0,0 +1,522 @@
|
||||
import pytest
|
||||
import unittest
|
||||
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from rest_framework.relations import Hyperlink
|
||||
|
||||
from access.models import Organization, Team, TeamUsers, Permission
|
||||
|
||||
from api.tests.abstract.api_permissions import APIPermissions
|
||||
|
||||
from config_management.models.groups import ConfigGroups, ConfigGroupHosts
|
||||
|
||||
from itam.models.device import Device
|
||||
|
||||
|
||||
class DeviceAPI(TestCase):
|
||||
|
||||
|
||||
model = Device
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
"""Setup Test
|
||||
|
||||
1. Create an organization for user and item
|
||||
. create an organization that is different to item
|
||||
2. Create a device
|
||||
3. create teams with each permission: view, add, change, delete
|
||||
4. create a user per team
|
||||
"""
|
||||
|
||||
organization = Organization.objects.create(name='test_org')
|
||||
|
||||
self.organization = organization
|
||||
|
||||
different_organization = Organization.objects.create(name='test_different_organization')
|
||||
|
||||
|
||||
self.item = self.model.objects.create(
|
||||
organization=organization,
|
||||
name = 'deviceone',
|
||||
uuid = 'val',
|
||||
serial_number = 'another val'
|
||||
)
|
||||
|
||||
config_group = ConfigGroups.objects.create(
|
||||
organization = self.organization,
|
||||
name = 'one',
|
||||
config = dict({"key": "one", "existing": "dont_over_write"})
|
||||
)
|
||||
|
||||
config_group_second_item = ConfigGroups.objects.create(
|
||||
organization = self.organization,
|
||||
name = 'one_two',
|
||||
config = dict({"key": "two"}),
|
||||
parent = config_group
|
||||
)
|
||||
|
||||
config_group_hosts = ConfigGroupHosts.objects.create(
|
||||
organization = organization,
|
||||
host = self.item,
|
||||
group = config_group,
|
||||
)
|
||||
|
||||
|
||||
config_group_hosts_two = ConfigGroupHosts.objects.create(
|
||||
organization = organization,
|
||||
host = self.item,
|
||||
group = config_group_second_item,
|
||||
)
|
||||
|
||||
|
||||
# self.url_kwargs = {'pk': self.item.id}
|
||||
|
||||
self.url_view_kwargs = {'pk': self.item.id}
|
||||
|
||||
# self.add_data = {'name': 'device', 'organization': self.organization.id}
|
||||
|
||||
|
||||
view_permissions = Permission.objects.get(
|
||||
codename = 'view_' + self.model._meta.model_name,
|
||||
content_type = ContentType.objects.get(
|
||||
app_label = self.model._meta.app_label,
|
||||
model = self.model._meta.model_name,
|
||||
)
|
||||
)
|
||||
|
||||
view_team = Team.objects.create(
|
||||
team_name = 'view_team',
|
||||
organization = organization,
|
||||
)
|
||||
|
||||
view_team.permissions.set([view_permissions])
|
||||
|
||||
|
||||
|
||||
# add_permissions = Permission.objects.get(
|
||||
# codename = 'add_' + self.model._meta.model_name,
|
||||
# content_type = ContentType.objects.get(
|
||||
# app_label = self.model._meta.app_label,
|
||||
# model = self.model._meta.model_name,
|
||||
# )
|
||||
# )
|
||||
|
||||
# add_team = Team.objects.create(
|
||||
# team_name = 'add_team',
|
||||
# organization = organization,
|
||||
# )
|
||||
|
||||
# add_team.permissions.set([add_permissions])
|
||||
|
||||
|
||||
|
||||
# change_permissions = Permission.objects.get(
|
||||
# codename = 'change_' + self.model._meta.model_name,
|
||||
# content_type = ContentType.objects.get(
|
||||
# app_label = self.model._meta.app_label,
|
||||
# model = self.model._meta.model_name,
|
||||
# )
|
||||
# )
|
||||
|
||||
# change_team = Team.objects.create(
|
||||
# team_name = 'change_team',
|
||||
# organization = organization,
|
||||
# )
|
||||
|
||||
# change_team.permissions.set([change_permissions])
|
||||
|
||||
|
||||
|
||||
# delete_permissions = Permission.objects.get(
|
||||
# codename = 'delete_' + self.model._meta.model_name,
|
||||
# content_type = ContentType.objects.get(
|
||||
# app_label = self.model._meta.app_label,
|
||||
# model = self.model._meta.model_name,
|
||||
# )
|
||||
# )
|
||||
|
||||
# delete_team = Team.objects.create(
|
||||
# team_name = 'delete_team',
|
||||
# organization = organization,
|
||||
# )
|
||||
|
||||
# delete_team.permissions.set([delete_permissions])
|
||||
|
||||
|
||||
# self.no_permissions_user = User.objects.create_user(username="test_no_permissions", password="password")
|
||||
|
||||
|
||||
self.view_user = User.objects.create_user(username="test_user_view", password="password")
|
||||
teamuser = TeamUsers.objects.create(
|
||||
team = view_team,
|
||||
user = self.view_user
|
||||
)
|
||||
|
||||
# self.add_user = User.objects.create_user(username="test_user_add", password="password")
|
||||
# teamuser = TeamUsers.objects.create(
|
||||
# team = add_team,
|
||||
# user = self.add_user
|
||||
# )
|
||||
|
||||
# self.change_user = User.objects.create_user(username="test_user_change", password="password")
|
||||
# teamuser = TeamUsers.objects.create(
|
||||
# team = change_team,
|
||||
# user = self.change_user
|
||||
# )
|
||||
|
||||
# self.delete_user = User.objects.create_user(username="test_user_delete", password="password")
|
||||
# teamuser = TeamUsers.objects.create(
|
||||
# team = delete_team,
|
||||
# user = self.delete_user
|
||||
# )
|
||||
|
||||
|
||||
# self.different_organization_user = User.objects.create_user(username="test_different_organization_user", password="password")
|
||||
|
||||
|
||||
# different_organization_team = Team.objects.create(
|
||||
# team_name = 'different_organization_team',
|
||||
# organization = different_organization,
|
||||
# )
|
||||
|
||||
# different_organization_team.permissions.set([
|
||||
# view_permissions,
|
||||
# add_permissions,
|
||||
# change_permissions,
|
||||
# delete_permissions,
|
||||
# ])
|
||||
|
||||
# TeamUsers.objects.create(
|
||||
# team = different_organization_team,
|
||||
# user = self.different_organization_user
|
||||
# )
|
||||
|
||||
|
||||
client = Client()
|
||||
url = reverse('API:device-detail', kwargs=self.url_view_kwargs)
|
||||
|
||||
|
||||
client.force_login(self.view_user)
|
||||
response = client.get(url)
|
||||
|
||||
self.api_data = response.data
|
||||
|
||||
|
||||
def test_api_field_exists_id(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
id field must exist
|
||||
"""
|
||||
|
||||
assert 'id' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_id(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
id field must be int
|
||||
"""
|
||||
|
||||
assert type(self.api_data['id']) is int
|
||||
|
||||
|
||||
def test_api_field_exists_is_global(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
is_global field must exist
|
||||
"""
|
||||
|
||||
assert 'is_global' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_is_global(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
is_global field must be boolean
|
||||
"""
|
||||
|
||||
assert type(self.api_data['is_global']) is bool
|
||||
|
||||
|
||||
def test_api_field_exists_name(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
name field must exist
|
||||
"""
|
||||
|
||||
assert 'name' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_name(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
name field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['name']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_config(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
config field must exist
|
||||
"""
|
||||
|
||||
assert 'config' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_config(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
config field must be dict
|
||||
"""
|
||||
|
||||
assert type(self.api_data['config']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_serial_number(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
serial_number field must exist
|
||||
"""
|
||||
|
||||
assert 'serial_number' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_serial_number(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
serial_number field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['serial_number']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_uuid(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
uuid field must exist
|
||||
"""
|
||||
|
||||
assert 'uuid' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_uuid(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
uuid field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['uuid']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_inventorydate(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
inventorydate field must exist
|
||||
"""
|
||||
|
||||
assert 'inventorydate' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_inventorydate(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
inventorydate field must be str
|
||||
"""
|
||||
|
||||
assert (
|
||||
type(self.api_data['inventorydate']) is str
|
||||
or
|
||||
self.api_data['inventorydate'] is None
|
||||
)
|
||||
|
||||
|
||||
def test_api_field_exists_created(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
created field must exist
|
||||
"""
|
||||
|
||||
assert 'created' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_created(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
created field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['created']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_modified(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
modified field must exist
|
||||
"""
|
||||
|
||||
assert 'modified' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_modified(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
modified field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['modified']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_groups(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
groups field must exist
|
||||
"""
|
||||
|
||||
assert 'groups' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_groups(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
groups field must be list
|
||||
"""
|
||||
|
||||
assert type(self.api_data['groups']) is list
|
||||
|
||||
|
||||
def test_api_field_exists_organization(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
organization field must exist
|
||||
"""
|
||||
|
||||
assert 'organization' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_organization(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
organization field must be dict
|
||||
"""
|
||||
|
||||
assert type(self.api_data['organization']) is dict
|
||||
|
||||
|
||||
def test_api_field_exists_url(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
url field must exist
|
||||
"""
|
||||
|
||||
assert 'url' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_url(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
url field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['url']) is Hyperlink
|
||||
|
||||
|
||||
|
||||
|
||||
def test_api_field_exists_organization_id(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
organization.id field must exist
|
||||
"""
|
||||
|
||||
assert 'id' in self.api_data['organization']
|
||||
|
||||
|
||||
def test_api_field_type_organization_id(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
organization.id field must be int
|
||||
"""
|
||||
|
||||
assert type(self.api_data['organization']['id']) is int
|
||||
|
||||
|
||||
def test_api_field_exists_organization_name(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
organization.name field must exist
|
||||
"""
|
||||
|
||||
assert 'name' in self.api_data['organization']
|
||||
|
||||
|
||||
def test_api_field_type_organization_name(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
organization.name field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['organization']['name']) is str
|
||||
|
||||
|
||||
|
||||
|
||||
def test_api_field_exists_groups_id(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
groups.id field must exist
|
||||
"""
|
||||
|
||||
assert 'id' in self.api_data['groups'][0]
|
||||
|
||||
|
||||
def test_api_field_type_groups_id(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
groups.id field must be int
|
||||
"""
|
||||
|
||||
assert type(self.api_data['groups'][0]['id']) is int
|
||||
|
||||
|
||||
def test_api_field_exists_groups_name(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
groups.name field must exist
|
||||
"""
|
||||
|
||||
assert 'name' in self.api_data['groups'][0]
|
||||
|
||||
|
||||
def test_api_field_type_groups_name(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
groups.name field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['groups'][0]['name']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_groups_url(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
groups.url field must exist
|
||||
"""
|
||||
|
||||
assert 'url' in self.api_data['groups'][0]
|
||||
|
||||
|
||||
def test_api_field_type_groups_url(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
groups.url field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['groups'][0]['url']) is Hyperlink
|
@ -16,3 +16,8 @@ This documentation is targeted towards those whom administer the applications de
|
||||
- [Backup](./backup.md)
|
||||
|
||||
- [Installation](./installation.md)
|
||||
|
||||
|
||||
## Ansible Automation Platform / AWX
|
||||
|
||||
We have built an [Ansible Collection](../../ansible/collections/centurion/index.md) for Centurion ERP that you could consider the bridge between the config within Centurion and the end device. This collection can be directly added to AAP / AWX as a project which enables accessing the features the collection has to offer. Please refer to the [collections documentation](../../ansible/collections/centurion/index.md) for further information.
|
||||
|
@ -27,6 +27,8 @@ Whilst there are many Enterprise Rescource Planning (ERP) applications, Centurio
|
||||
|
||||
Centurion ERP contains the following modules:
|
||||
|
||||
- [Companion Ansible Collection](../ansible/collections/centurion/index.md)
|
||||
|
||||
- [Configuration Management](./user/config_management/index.md)
|
||||
|
||||
- [IT Asset Management (ITAM)](./user/itam/index.md)
|
||||
|
Reference in New Issue
Block a user