Skip to content
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

adde support for v2 api Settings #77

Merged
merged 5 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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 dynatrace/environment_v2/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,4 @@ def _create_from_raw_data(self, raw_element: Dict[str, Any]):

def to_json(self) -> Dict[str, Any]:
return {"name": self.name, "id": self.id}

97 changes: 97 additions & 0 deletions dynatrace/environment_v2/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
from datetime import datetime
from dynatrace.dynatrace_object import DynatraceObject
from typing import List, Optional, Union, Dict, Any

from dynatrace.http_client import HttpClient
from dynatrace.pagination import PaginatedList
import json
import logging
from http.client import HTTPConnection # py3
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think this is used anywhere?

Copy link
Author

Choose a reason for hiding this comment

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

removed unused imports



class SettingService:
ENDPOINT = "/api/v2/settings/objects"

def __init__(self, http_client: HttpClient):
self.__http_client = http_client

def list(self,schema_id: Optional[str] = None,
Copy link
Collaborator

Choose a reason for hiding this comment

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

We'll want to update these method names to 'list_objects' etc... The issue would be that this API also lets you list and view 'schemas' so we'd need to name them a bit more clearly to differentiate.

Copy link
Author

Choose a reason for hiding this comment

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

renamed methods

scope: Optional[str] = None,external_ids: Optional[str] = None,
fields: Optional[str] = None,
filter:Optional[str] = None, sort:Optional[str] = None, page_size:Optional[str] = None) -> PaginatedList["DynatraceObject"]:
"""Lists settings

:return: a list of settings with details
"""
params = {
"schemaIds": schema_id,
"scope": scope,
"fields": fields,
"externalIds": external_ids,
"filter": filter,
"sort": sort,
"pageSize": page_size,
}
return PaginatedList(Settings, self.__http_client, target_url=self.ENDPOINT, list_item="items", target_params=params)

def post(self,external_id,object_id,schema_id,schema_version,scope, value,validate_only):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Similar to above the name should clarify what we're interacting with as well as we want to name them after the action not the HTTP method.

e.g. create_object

Copy link
Author

Choose a reason for hiding this comment

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

renamed methods

"""Creates a new settings object

:param external_id: External identifier for the object being created
:param object_id: The ID of the settings object that should be replaced. Only applicable if an external identifier
:param object_id: the ID of the object
:param schema_id: The schema on which the object is based
:param schema_version: The version of the schema on which the object is based.
:param scope The scope that the object targets. For more details, please see Dynatrace Documentation.
:param value The value of the setting.
:return: a Settings object
"""
params = {
"validate_only": validate_only,
}
body =[ {
"externalId" : external_id,
"objectId": object_id,
"schemaId": schema_id,
"schemaVersion": schema_version,
"scope": scope,
"value" : value

}]

response = self.__http_client.make_request(self.ENDPOINT,params=body, method="POST",query_params=params).json()
return response


def get(self, object_id: str):
"""Gets parameters of specified settings object

:param object_id: the ID of the object
:return: a Settings object
"""
response = self.__http_client.make_request(f"{self.ENDPOINT}/{object_id}").json()
return Settings(raw_element=response)

def update(self, object_id: str, value):
"""Updates an existing settings object
:param object_id: the ID of the object

"""
return self.__http_client.make_request(path=f"{self.ENDPOINT}/{object_id}", params=value, method="PUT")

def delete(self, object_id: str):
"""Deletes the specified object

:param object_id: the ID of the object
:return: HTTP response
"""
return self.__http_client.make_request(path=f"{self.ENDPOINT}/{object_id}", method="DELETE")

class Settings(DynatraceObject):
value = None
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think this is needed/used anywhere.

Copy link
Author

Choose a reason for hiding this comment

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

removed value=none

def _create_from_raw_data(self, raw_element: Dict[str, Any]):
# Mandatory
self.objectId: str = raw_element["objectId"]
self.value: str = raw_element["value"]
def to_json(self):
Copy link
Collaborator

Choose a reason for hiding this comment

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

I understand the motivation for this but I don't think we'd include this as all it is is a 'getter' that returns the value attribute. If this is needed they can just access the 'value' attribute of the settings object. We don't have anything like this for other objects. to_json() could also confuse someone if they expected the whole json including the object id.

Copy link
Author

Choose a reason for hiding this comment

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

removed to_json

return self.value
3 changes: 3 additions & 0 deletions dynatrace/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
from dynatrace.environment_v2.problems import ProblemService
from dynatrace.environment_v2.service_level_objectives import SloService
from dynatrace.environment_v2.logs import LogService
from dynatrace.environment_v2.settings import SettingService

from dynatrace.http_client import HttpClient


Expand Down Expand Up @@ -118,6 +120,7 @@ def __init__(
self.oneagents_config_environment: OneAgentEnvironmentWideConfigService = OneAgentEnvironmentWideConfigService(self.__http_client)
self.oneagents_config_host: OneAgentOnAHostConfigService = OneAgentOnAHostConfigService(self.__http_client)
self.oneagents_config_hostgroup: OneAgentInAHostGroupService = OneAgentInAHostGroupService(self.__http_client)
self.settings : SettingService = SettingService(self.__http_client)
self.plugins: PluginService = PluginService(self.__http_client)
self.problems: ProblemService = ProblemService(self.__http_client)
self.slos: SloService = SloService(self.__http_client)
Expand Down
37 changes: 37 additions & 0 deletions test/environment_v2/test_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from datetime import datetime

import dynatrace.environment_v2.settings as st
from dynatrace import Dynatrace
from dynatrace.pagination import PaginatedList
payload = {"additionalInformation": [],
"contactDetails":[{"email": '[email protected]', "integrationType": "EMAIL"}],
"description": 'unittest',
"identifier":'unittest',
"links": [],
"name": 'unittest',
"responsibilities": {"development": False,
"infrastructure": False,
"lineOfBusiness": True,
"operations": False,
"security": False},
"supplementaryIdentifiers": [] }
def test_list(dt: Dynatrace):
settings = dt.settings.list(schema_id="builtin:ownership.teams")
assert isinstance(settings, PaginatedList)
assert len(list(settings)) == 1
assert all(isinstance(s, st.Settings) for s in settings)

def test_get(dt: Dynatrace):
setting = dt.settings.get(object_id="vu9U3hXa3q0AAAABABdidWlsdGluOm93bmVyc2hpcC50ZWFtcwAGdGVuYW50AAZ0ZW5hbnQAJGVjN2UyNTdhLWM5MTktM2YzMC05NWFiLTliMzNkMmQwZGRkY77vVN4V2t6t")
assert isinstance(setting, st.Settings)

def test_post(dt: Dynatrace):

response = dt.settings.post(external_id='unittest',object_id='unittest',schema_id="builtin:ownership.teams",schema_version="1.0.6",scope="environment", value=payload,validate_only=False)
assert response[0].get("code") == 200
assert response[0].get("code") is not None

def test_put(dt: Dynatrace):
payload["identifier"] = "unittestupdate"
response = dt.settings.update("unittest",payload)
print(response)
31 changes: 31 additions & 0 deletions test/mock_data/GET_api_v2_settings_objects_804a7afa1d2a354.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"items": [

{
"objectId": "vu9U3hXa3q0AAAABABdidWlsdGluOm93bmVyc2hpcC50ZWFtcwAGdGVuYW50AAZ0ZW5hbnQAJGVjN2UyNTdhLWM5MTktM2YzMC05NWFiLTliMzNkMmQwZGRkY77vVN4V2t6t",
"value": {
"name": "user",
"description": "user",
"identifier": "user",
"supplementaryIdentifiers": [],
"responsibilities": {
"development": false,
"security": false,
"operations": false,
"infrastructure": true,
"lineOfBusiness": false
},
"contactDetails": [
{
"integrationType": "EMAIL",
"email": "[email protected]"
}
],
"links": [],
"additionalInformation": []
}
}
],
"totalCount": 1,
"pageSize": 500
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"objectId": "vu9U3hXa3q0AAAABABdidWlsdGluOm93bmVyc2hpcC50ZWFtcwAGdGVuYW50AAZ0ZW5hbnQAJGVjN2UyNTdhLWM5MTktM2YzMC05NWFiLTliMzNkMmQwZGRkY77vVN4V2t6t",
"value": {
"name": "user",
"description": "user",
"identifier": "user",
"supplementaryIdentifiers": [],
"responsibilities": {
"development": false,
"security": false,
"operations": false,
"infrastructure": true,
"lineOfBusiness": false
},
"contactDetails": [
{
"integrationType": "EMAIL",
"email": "[email protected]"
}
],
"links": [],
"additionalInformation": []
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"code": 200,
"objectId": "vu9U3hXa3q0AAAABABdidWlsdGluOm93bmVyc2hpcC50ZWFtcwAGdGVuYW50AAZ0ZW5hbnQAJDVhNjk1MzViLWQ3NDYtMzVmYi05MDdjLTM2ODNkMmMyNWQzOb7vVN4V2t6t"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"code": 200,
"objectId": "vu9U3hXa3q0AAAABABdidWlsdGluOm93bmVyc2hpcC50ZWFtcwAGdGVuYW50AAZ0ZW5hbnQAJDVhNjk1MzViLWQ3NDYtMzVmYi05MDdjLTM2ODNkMmMyNWQzOb7vVN4V2t6t"
}
Loading