Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/asyncplatform/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ def configuration_manager(self) -> Any:
"""Get the Configuration Manager service instance."""
return self.client.configuration_manager

@property
def integration_models(self) -> Any:
"""Get the Integration Models service instance."""
return self.client.integration_models

@property
def integrations(self) -> Any:
"""Get the Integrations service instance."""
return self.client.integrations

@logging.trace
async def get_groups(self) -> dict[str, dict[str, Any]]:
"""Retrieve and cache all authorization groups from the platform.
Expand Down
97 changes: 97 additions & 0 deletions src/asyncplatform/resources/integration_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Copyright (c) 2025 Itential, Inc
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

"""Integration model resource for managing Itential Platform integration models.

This module provides the Resource class for high-level integration model
management operations including importing OpenAPI specs with delete-before-replace
semantics and deleting models by version identifier.
"""

from __future__ import annotations

from typing import TYPE_CHECKING
from typing import Any

from asyncplatform import logging
from asyncplatform.resources import ResourceBase

if TYPE_CHECKING:
from collections.abc import Mapping


class Resource(ResourceBase):
"""Resource class for managing integration models.

Provides high-level lifecycle operations for integration models, wrapping
the integration_models service with import and delete convenience methods.

Attributes:
integration_models: Property that returns the Integration Models
service instance
"""

name: str = "integration_models"

@logging.trace
async def importer(self, spec: Mapping[str, Any]) -> dict[str, Any]:
"""Import an integration model, replacing any existing version.

Derives the version identifier from the spec's info block, deletes any
existing model with the same version identifier, then creates the new
model. Follows delete-before-replace to avoid version conflicts on
re-import.

Args:
spec: A valid OpenAPI 3.x specification. Must include info.title
and info.version fields

Returns:
A dictionary containing the created integration model data

Raises:
AsyncPlatformError: If the spec exceeds 15 MB or any API request fails
"""
title: str = spec["info"]["title"]
version: str = spec["info"]["version"]
version_id = f"{title}:{version}"

existing = await self.integration_models.find_integration_models(
name=version_id
)
if existing:
await self.integration_models.delete_integration_model(version_id)
logging.info(f"Deleted existing integration model: {version_id}")

result = await self.integration_models.create_integration_model(spec)

logging.info(f"Successfully imported integration model: {version_id}")

return result

@logging.trace
async def delete(self, version_id: str) -> dict[str, Any]:
"""Delete an integration model by version identifier.

Searches for a model by version identifier and deletes it if found.
Returns an empty dictionary if no matching model exists.

Args:
version_id: The version identifier of the model to delete, in the
form title:version (e.g. "My API:1.0.0")

Returns:
A dictionary containing the deletion result, or an empty dictionary
if no model with the specified version identifier was found

Raises:
AsyncPlatformError: If the delete operation fails
"""
existing = await self.integration_models.find_integration_models(
name=version_id
)
if not existing:
return {}

return await self.integration_models.delete_integration_model(version_id)
108 changes: 108 additions & 0 deletions src/asyncplatform/resources/integrations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Copyright (c) 2025 Itential, Inc
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

"""Integration resource for managing Itential Platform integration instances.

This module provides the Resource class for high-level integration instance
management operations including creating instances and deleting instances by name.
"""

from __future__ import annotations

from typing import TYPE_CHECKING
from typing import Any

from asyncplatform import logging
from asyncplatform.resources import ResourceBase

if TYPE_CHECKING:
from collections.abc import Mapping


class Resource(ResourceBase):
"""Resource class for managing integration instances.

Provides high-level lifecycle operations for integration instances, wrapping
the integrations service with import and delete convenience methods.

Attributes:
integrations: Property that returns the Integrations service instance
"""

name: str = "integrations"

@logging.trace
async def importer(
self,
*,
name: str,
type: str,
properties: Mapping[str, Any],
virtual: bool | None = None,
model: str | None = None,
overwrite: bool = False,
) -> dict[str, Any]:
"""Create an integration instance, optionally replacing an existing one.

Creates an integration instance with the given configuration. By default,
raises an error if an instance with the same name already exists. Set
overwrite=True to delete the existing instance before creating the new one.

Args:
name: Name for the integration instance
type: The integration adapter type
properties: Configuration properties for the integration
virtual: Whether to create a virtual integration
model: Optional integration model name to associate with the instance
overwrite: If True, deletes an existing instance with the same name
before creating. If False (default), raises an error if the
instance already exists

Returns:
A dictionary containing the created integration instance data

Raises:
AsyncPlatformError: If overwrite is False and an instance with the
same name already exists, or if any API request fails
"""
if overwrite:
existing = await self.integrations.find_integrations(name=name)
if existing:
await self.integrations.delete_integration(name)
logging.info(f"Deleted existing integration instance: {name}")

result = await self.integrations.create_integration(
name=name,
type=type,
properties=properties,
virtual=virtual,
model=model,
)

logging.info(f"Successfully created integration instance: {name}")

return result

@logging.trace
async def delete(self, name: str) -> dict[str, Any]:
"""Delete an integration instance by name.

Searches for an integration instance by name and deletes it if found.
Returns an empty dictionary if no matching instance exists.

Args:
name: The name of the integration instance to delete

Returns:
A dictionary containing the deletion result, or an empty dictionary
if no instance with the specified name was found

Raises:
AsyncPlatformError: If the delete operation fails
"""
existing = await self.integrations.find_integrations(name=name)
if not existing:
return {}

return await self.integrations.delete_integration(name)
Loading
Loading