Skip to content

adding SDK changes for ACLP APIs #528

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions linode_api4/groups/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
from .tag import *
from .volume import *
from .vpc import *
from .monitor import *

Check notice

Code scanning / CodeQL

'import *' may pollute namespace Note

Import pollutes the enclosing namespace, as the imported module
linode_api4.groups.monitor
does not define '__all__'.
185 changes: 185 additions & 0 deletions linode_api4/groups/monitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
from linode_api4.errors import UnexpectedResponseError
from linode_api4.groups import Group
from linode_api4.objects import (
CreateToken,
DashboardByService,
ServiceDetails,
Dashboard,
MonitorServiceSupported,
MetricDefinition,
DashboardsByID,
)

__all__ = [
"MonitorGroup",
]
class MonitorGroup(Group):
"""
Encapsulates Monitor-related methods of the :any:`LinodeClient`. This
should not be instantiated on its own, but should instead be used through
an instance of :any:`LinodeClient`::

client = LinodeClient(token)
instances = client.monitor.dashboards() # use the LKEGroup

This group contains all features beneath the `/monitor` group in the API v4.
"""

def dashboards(self, *filters):
"""
Returns a list of dashboards on your account.

.. note:: This endpoint is in beta. This will only function if base_url is set to `https://api.linode.com/v4beta`.

API Documentation: https://techdocs.akamai.com/linode-api/reference/get-dashboards-all

:param filters: Any number of filters to apply to this query.
See :doc:`Filtering Collections</linode_api4/objects/filtering>`
for more details on filtering.

:returns: A list of Dashboards.
:rtype: PaginatedList of Dashboard
"""
return self.client._get_and_filter(Dashboard, *filters)

def dashboard_by_ID(self, dashboard_id: int, *filters):
"""
Returns a dashboards on your account based on the ID passed.

.. note:: This endpoint is in beta. This will only function if base_url is set to `https://api.linode.com/v4beta`.

API Documentation: https://techdocs.akamai.com/linode-api/reference/get-dashboards-by-id

:param filters: Any number of filters to apply to this query.
See :doc:`Filtering Collections</linode_api4/objects/filtering>`
for more details on filtering.

:returns: A Dashboards.
:rtype: PaginatedList of the Dashboard
"""
result = self.client.get(f"/monitor/dashboards/{dashboard_id}")

if not "id" in result:
raise UnexpectedResponseError(
"Unexpected response when getting Dashboard!", json=result
)
return DashboardsByID(self.client, result["id"], result)
Comment on lines +45 to +66
Copy link
Contributor

@yec-akamai yec-akamai Apr 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have to explicitly implement the get by id method in the group. If you read through the Base class for object, you can find each object has inherited some basic functions, i.e. get, set, delete, etc. Can you please update your PR to match the codebase standard?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functions in the base class can only be used when the API parses ID based on the header called 'X-Filter'. The ACLP APIs are not written in a way to recognise any additional headers like this, hence added a new method for ID



def dashboards_by_service(self, service_type: str, *filters):
"""
Returns a dashboards on your account based on the service passed.

.. note:: This endpoint is in beta. This will only function if base_url is set to `https://api.linode.com/v4beta`.

API Documentation: https://techdocs.akamai.com/linode-api/reference/get-dashboards

:param filters: Any number of filters to apply to this query.
See :doc:`Filtering Collections</linode_api4/objects/filtering>`
for more details on filtering.

:returns: A Dashboards filtered by Service Type.
:rtype: PaginatedList of the Dashboards
"""

return self.client._get_and_filter(
DashboardByService,
*filters,
endpoint=f"/monitor/services/{service_type}/dashboards",
)


def supported_services(self, *filters):
"""
Returns a list of services supported by ACLP.

.. note:: This endpoint is in beta. This will only function if base_url is set to `https://api.linode.com/v4beta`.

API Documentation: https://techdocs.akamai.com/linode-api/reference/get-monitor-services

:param filters: Any number of filters to apply to this query.
See :doc:`Filtering Collections</linode_api4/objects/filtering>`
for more details on filtering.

:returns: A list of Supported Services
:rtype: PaginatedList of the Dashboards
"""

return self.client._get_and_filter(MonitorServiceSupported, *filters)

def details_by_service(self, service_type: str,*filters):
"""
Returns a details about a particular service.

.. note:: This endpoint is in beta. This will only function if base_url is set to `https://api.linode.com/v4beta`.

API Documentation: https://techdocs.akamai.com/linode-api/reference/get-monitor-services-for-service-type

:param filters: Any number of filters to apply to this query.
See :doc:`Filtering Collections</linode_api4/objects/filtering>`
for more details on filtering.

:returns: Details about a Supported Services
:rtype: PaginatedList of the Service
"""
return self.client._get_and_filter(
ServiceDetails,
*filters,
endpoint=f"/monitor/services/{service_type}",
)

def metric_definitions(self, service_type: str,*filters):
"""
Returns metrics for a specific service type.

.. note:: This endpoint is in beta. This will only function if base_url is set to `https://api.linode.com/v4beta`.

API Documentation: https://techdocs.akamai.com/linode-api/reference/get-monitor-information

:param filters: Any number of filters to apply to this query.
See :doc:`Filtering Collections</linode_api4/objects/filtering>`
for more details on filtering.

:returns: Returns a List of metrics for a service
:rtype: PaginatedList of metrics
"""
return self.client._get_and_filter(
MetricDefinition,
*filters,
endpoint=f"/monitor/services/{service_type}/metric-definitions",
)

def create_token(self, service_type: str, entity_ids: list, *filters):
"""
Returns a JWE Token for a specific service type.

.. note:: This endpoint is in beta. This will only function if base_url is set to `https://api.linode.com/v4beta`.

API Documentation: https://techdocs.akamai.com/linode-api/reference/post-get-token
:param filters: Any number of filters to apply to this query.
See :doc:`Filtering Collections</linode_api4/objects/filtering>`
for more details on filtering.

:returns: Returns a token for a service
:rtype: str
"""

params = {"entity_ids": entity_ids}

result = self.client.post(f"/monitor/services/{service_type}/token", data=params)

if "token" not in result:
raise UnexpectedResponseError(
"Unexpected response when creating token!", json=result
)
return CreateToken(self.client, result["token"], result)










3 changes: 3 additions & 0 deletions linode_api4/linode_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
TagGroup,
VolumeGroup,
VPCGroup,
MonitorGroup,
)
from linode_api4.objects import Image, and_

Expand Down Expand Up @@ -201,6 +202,8 @@ def __init__(
#: Access methods related to VM placement - See :any:`PlacementAPIGroup` for more information.
self.placement = PlacementAPIGroup(self)

self.monitor = MonitorGroup(self)

@property
def _user_agent(self):
return "{}python-linode_api4/{} {}".format(
Expand Down
1 change: 1 addition & 0 deletions linode_api4/objects/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
from .vpc import *
from .beta import *
from .placement import *
from .monitor import *

Check notice

Code scanning / CodeQL

'import *' may pollute namespace Note

Import pollutes the enclosing namespace, as the imported module
linode_api4.objects.monitor
does not define '__all__'.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated the group and object to include 'all'

107 changes: 107 additions & 0 deletions linode_api4/objects/monitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
from linode_api4.objects import (
Base,
Property,
)

__all__ = ['Dashboard', 'DashboardsByID', 'DashboardByService', 'MonitorServiceSupported', 'ServiceDetails', 'MetricDefinition', 'CreateToken']
class Dashboard(Base):
"""
List dashboards: https://techdocs.akamai.com/linode-api/get-dashboards-all
"""

api_endpoint = "/monitor/dashboards/"
properties = {
"id": Property(identifier=True),
"created": Property(is_datetime=True),
"label": Property(),
"service_type": Property(),
"type": Property(),
"widgets": Property(mutable=True),
"updated": Property(is_datetime=True),

}

class DashboardsByID(Base):
"""
Get a dashboard: https://techdocs.akamai.com/linode-api/reference/get-dashboards-by-id
"""


properties = {
"id": Property(identifier=True),
"created": Property(is_datetime=True),
"label": Property(),
"service_type": Property(),
"type": Property(),
"widgets": Property(mutable=True),
"updated": Property(is_datetime=True),

}
Comment on lines +7 to +39
Copy link
Contributor

@lgarber-akamai lgarber-akamai Apr 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could these two be merged using an api_endpoint like /monitor/dashboards/{id}?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The /monitor/dashboards and /monitor/dashboards/{id} are implemented separately in the codebase. It does not expect the 'X-filter' header which I believe is mandatory for grouping it.


class DashboardByService(Base):
"""
Get a dashboard: https://techdocs.akamai.com/linode-api/reference/get-dashboards
"""

properties = {
"id": Property(identifier=True),
"created": Property(is_datetime=True),
"label": Property(),
"service_type": Property(),
"type": Property(),
"widgets": Property(mutable=True),
"updated": Property(is_datetime=True),

}


class MonitorServiceSupported(Base):

api_endpoint = "/monitor/services/"
id_attribute = "service_type"
properties = {
"service_type": Property(),
"label": Property(mutable=True),

}

class ServiceDetails(Base):
"""
API Documentation: https://techdocs.akamai.com/linode-api/reference/get-monitor-services-for-service-type
"""
id_attribute = "service_type"
properties = {
"label": Property(),
"service_type": Property(),
}



class MetricDefinition(Base):
"""
API Documentation: https://techdocs.akamai.com/linode-api/reference/get-monitor-information
"""

id_attribute = "metric"
properties = {
"available_aggregate_functions": Property(),
"dimensions": Property(mutable=True),
"label": Property(),
"is_alertable": Property(),
"metric": Property(),
"metric_type": Property(),
"scrape_interval": Property(),
"unit": Property(),
}

class CreateToken(Base):
"""
API Documentation: https://techdocs.akamai.com/linode-api/reference/post-get-token
"""

properties = {
"token": Property(mutable=True)
}



37 changes: 37 additions & 0 deletions test/fixtures/monitor_dashboards.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"data": [
{
"created": "2024-10-10T05:01:58",
"id": 1,
"label": "Resource Usage",
"service_type": "dbaas",
"type": "standard",
"updated": "2024-10-10T05:01:58",
"widgets": [
{
"aggregate_function": "sum",
"chart_type": "area",
"color": "default",
"label": "CPU Usage",
"metric": "cpu_usage",
"size": 12,
"unit": "%",
"y_label": "cpu_usage"
},
{
"aggregate_function": "sum",
"chart_type": "area",
"color": "default",
"label": "Disk I/O Write",
"metric": "write_iops",
"size": 6,
"unit": "IOPS",
"y_label": "write_iops"
}
]
}
],
"page": 1,
"pages": 1,
"results": 1
}
30 changes: 30 additions & 0 deletions test/fixtures/monitor_dashboards_1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"created": "2024-10-10T05:01:58",
"id": 1,
"label": "Resource Usage",
"service_type": "dbaas",
"type": "standard",
"updated": "2024-10-10T05:01:58",
"widgets": [
{
"aggregate_function": "sum",
"chart_type": "area",
"color": "default",
"label": "CPU Usage",
"metric": "cpu_usage",
"size": 12,
"unit": "%",
"y_label": "cpu_usage"
},
{
"aggregate_function": "sum",
"chart_type": "area",
"color": "default",
"label": "Available Memory",
"metric": "available_memory",
"size": 6,
"unit": "GB",
"y_label": "available_memory"
}
]
}
Loading