Skip to content

Commit

Permalink
sites with model, test, doco, and additions to classic_api.py
Browse files Browse the repository at this point in the history
  • Loading branch information
Honestpuck committed Oct 27, 2023
1 parent 447f2a2 commit ef02271
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 0 deletions.
11 changes: 11 additions & 0 deletions docs/reference/models_classic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,17 @@ Packages
ClassicPackage
ClassicPackageItem

Sites
-----

.. currentmodule:: jamf_pro_sdk.models.classic.sites

.. autosummary::
:toctree: _autosummary

ClassicSite
ClassicSiteItem

Group and Search Criteria
-------------------------

Expand Down
98 changes: 98 additions & 0 deletions src/jamf_pro_sdk/clients/classic_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,24 @@
ClassicAdvancedComputerSearch,
ClassicAdvancedComputerSearchesItem,
)

from ..models.classic.categories import ClassicCategoriesItem, ClassicCategory

from ..models.classic.computer_groups import (
ClassicComputerGroup,
ClassicComputerGroupMember,
ClassicComputerGroupMembershipUpdate,
)

from ..models.classic.computers import (
ClassicComputer,
ClassicComputersItem,
)

from ..models.classic.packages import ClassicPackage, ClassicPackageItem

from ..models.classic.sites import ClassicSite, ClassicSitesItem

if TYPE_CHECKING:
import requests

Expand All @@ -45,6 +51,7 @@
int, ClassicAdvancedComputerSearch, ClassicAdvancedComputerSearchesItem
]
PackageId = Union[int, ClassicPackage, ClassicPackageItem]
SiteId = Union[int, ClassicSite, ClassicSitesItem]


def parse_response_id(xml: str) -> int:
Expand Down Expand Up @@ -554,3 +561,94 @@ def delete_package_by_id(self, package: PackageId) -> None:
"""
package_id = ClassicApi._parse_id(package)
self.api_request(method="delete", resource_path=f"packages/id/{package_id}")


# /sites APIs


def create_site(self, data: Union[str, ClassicSite]) -> int:
"""Create a new site.
Only the ``name`` is required.
:param data: Can be an XML string or a
:class:`~jamf_pro_sdk.models.classic.sites.ClassicSite` object.
:type data: Union[str, ClassicSite]
:return: ID of the new site.
:rtype: int
"""
resp = self.api_request(method="post", resource_path="sites/id/0", data=data)
return parse_response_id(resp.text)


def list_all_sites(self) -> List[ClassicSitesItem]:
"""Returns a list of all sites.
:return: List of sites.
:rtype: List[~jamf_pro_sdk.models.classic.sites.ClassicSitesItem]
"""
resp = self.api_request(method="get", resource_path="sites")
return [ClassicSitesItem(**i) for i in resp.json()["sites"]]


def get_site_by_id(self, site: SiteId) -> ClassicSite:
"""Returns a single site record using the ID.
:param site: A site ID or supported Classic API model.
:type site: Union[int, ClassicSite, ClassicSitesItem]
:return: Site.
:rtype: ~jamf_pro_sdk.models.classic.sites.ClassicSite
"""
site_id = ClassicApi._parse_id(site)
resp = self.api_request(method="get", resource_path=f"sites/id/{site_id}")
return ClassicSite(**resp.json()["site"])


def update_site_by_id(
self, site: SiteId, data: Union[str, ClassicSite], return_updated: bool = False
):
"""Update a site using the ID.
:param site: A site ID or supported Classic API model.
:type site: Union[int, ClassicSite, ClassicSitesItem]
:param data: Can be an XML string or a
:class:`~jamf_pro_sdk.models.classic.sites.ClassicSite` object.
:type data: Union[str, ClassicSite]
"""
site_id = ClassicApi._parse_id(site)
self.api_request(method="put", resource_path=f"sites/id/{site_id}", data=data)
if return_updated:
return self.get_site_by_id(site_id)


def delete_site_by_id(self, site: SiteId) -> None:
"""Delete a site using the ID.
:param site: A site ID or supported Classic API model.
:type site: Union[int, ClassicSite, ClassicSitesItem]
"""
site_id = ClassicApi._parse_id(site)
self.api_request(method="delete", resource_path=f"sites/id/{site_id}")


def create_site(self, data: Union[str, ClassicSite]) -> int:
"""Create a new site.
:param data: Can be an XML string or a
:class:`~jamf_pro_sdk.models.classic.sites.ClassicSite` object.
:type data: Union[str, ClassicSite]
:return: ID of the new site.
:rtype: int
"""
resp = self.api_request(method="post", resource_path="sites/id/0", data=data)
return parse_response_id(resp.text)
31 changes: 31 additions & 0 deletions src/jamf_pro_sdk/models/classic/sites.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from typing import Optional

from pydantic import Extra

from .. import BaseModel
from . import ClassicApiModel

_XML_ARRAY_ITEM_NAMES = {}


class ClassicSiteItem(BaseModel, extra=Extra.allow):
"""Represents a site record returned by the
:meth:`~jamf_pro_sdk.clients.classic_api.ClassicApi.list_sites` operation.
"""

id: Optional[int]
name: Optional[str]


class ClassicSite(ClassicApiModel):
"""Represents a site record returned by the
:meth:`~jamf_pro_sdk.clients.classic_api.ClassicApi.get_site_by_id` operation.
Note that due to the simplicity of the model this information is available in the list.
"""

_xml_root_name = "site"
_xml_array_item_names = _XML_ARRAY_ITEM_NAMES
_xml_write_fields = {"name"}

id: Optional[int]
name: Optional[str]
24 changes: 24 additions & 0 deletions tests/models/test_models_classic_sites.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import json

from deepdiff import DeepDiff
from src.jamf_pro_sdk.models.classic.sites import ClassicSite

SITE_JSON = {"site": {"id": 1, "name": "Test Site"}}


def test_site_model_parsings():
"""Verify select attributes across the Site model."""
site = ClassicSite(**SITE_JSON["site"])

assert site is not None # mypy
assert site.name == "Test Site"
assert site.id == 1


def test_site_model_json_output_matches_input():
site = ClassicSite(**SITE_JSON["site"])
serialized_output = json.loads(site.json(exclude_none=True))

diff = DeepDiff(SITE_JSON["site"], serialized_output, ignore_order=True)

assert not diff

0 comments on commit ef02271

Please sign in to comment.