diff --git a/dynatrace/environment_v2/schemas.py b/dynatrace/environment_v2/schemas.py index b126d78..fd254c5 100644 --- a/dynatrace/environment_v2/schemas.py +++ b/dynatrace/environment_v2/schemas.py @@ -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} + diff --git a/dynatrace/environment_v2/settings.py b/dynatrace/environment_v2/settings.py new file mode 100644 index 0000000..bdd78e4 --- /dev/null +++ b/dynatrace/environment_v2/settings.py @@ -0,0 +1,91 @@ +from typing import Optional, Dict, Any + +from dynatrace.dynatrace_object import DynatraceObject +from dynatrace.http_client import HttpClient +from dynatrace.pagination import PaginatedList + + +class SettingService: + ENDPOINT = "/api/v2/settings/objects" + + def __init__(self, http_client: HttpClient): + self.__http_client = http_client + + def list_objects(self,schema_id: Optional[str] = None, + 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 create_object(self,external_id,object_id,schema_id,schema_version,scope, value,validate_only): + """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_object(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_object(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_object(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): + def _create_from_raw_data(self, raw_element: Dict[str, Any]): + # Mandatory + self.objectId: str = raw_element["objectId"] + self.value: str = raw_element["value"] diff --git a/dynatrace/main.py b/dynatrace/main.py index 29d213f..1dd0476 100644 --- a/dynatrace/main.py +++ b/dynatrace/main.py @@ -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 @@ -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) diff --git a/test/environment_v2/test_settings.py b/test/environment_v2/test_settings.py new file mode 100644 index 0000000..7f8f00a --- /dev/null +++ b/test/environment_v2/test_settings.py @@ -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": 'unittest@contoso.com', "integrationType": "EMAIL"}], + "description": 'unittest', + "identifier":'unittest', + "links": [], + "name": 'unittest', + "responsibilities": {"development": False, + "infrastructure": False, + "lineOfBusiness": True, + "operations": False, + "security": False}, + "supplementaryIdentifiers": [] } +def test_list_objects(dt: Dynatrace): + settings = dt.settings.list_objects(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_object(dt: Dynatrace): + setting = dt.settings.get_object(object_id="vu9U3hXa3q0AAAABABdidWlsdGluOm93bmVyc2hpcC50ZWFtcwAGdGVuYW50AAZ0ZW5hbnQAJGVjN2UyNTdhLWM5MTktM2YzMC05NWFiLTliMzNkMmQwZGRkY77vVN4V2t6t") + assert isinstance(setting, st.Settings) + +def test_post_object(dt: Dynatrace): + + response = dt.settings.create_object(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_object(dt: Dynatrace): + payload["identifier"] = "unittestupdate" + response = dt.settings.update_object("unittest",payload) + print(response) \ No newline at end of file diff --git a/test/mock_data/GET_api_v2_settings_objects_804a7afa1d2a354.json b/test/mock_data/GET_api_v2_settings_objects_804a7afa1d2a354.json new file mode 100644 index 0000000..a9548af --- /dev/null +++ b/test/mock_data/GET_api_v2_settings_objects_804a7afa1d2a354.json @@ -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": "test@contoso.com" + } + ], + "links": [], + "additionalInformation": [] + } + } + ], + "totalCount": 1, + "pageSize": 500 +} \ No newline at end of file diff --git a/test/mock_data/GET_api_v2_settings_objects_vu9U3hXa3q0AAAABABdidWlsdGluOm93bmVyc2hpcC50ZWFtcwAGdGVuYW50AAZ0ZW5hbnQAJGVjN2UyNTdhLWM5MTktM2YzMC05NWFiLTliMzNkMmQwZGRkY77vVN4V2t6t.json b/test/mock_data/GET_api_v2_settings_objects_vu9U3hXa3q0AAAABABdidWlsdGluOm93bmVyc2hpcC50ZWFtcwAGdGVuYW50AAZ0ZW5hbnQAJGVjN2UyNTdhLWM5MTktM2YzMC05NWFiLTliMzNkMmQwZGRkY77vVN4V2t6t.json new file mode 100644 index 0000000..ce6aebb --- /dev/null +++ b/test/mock_data/GET_api_v2_settings_objects_vu9U3hXa3q0AAAABABdidWlsdGluOm93bmVyc2hpcC50ZWFtcwAGdGVuYW50AAZ0ZW5hbnQAJGVjN2UyNTdhLWM5MTktM2YzMC05NWFiLTliMzNkMmQwZGRkY77vVN4V2t6t.json @@ -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": "test@contoso.com" + } + ], + "links": [], + "additionalInformation": [] + } +} \ No newline at end of file diff --git a/test/mock_data/POST_api_v2_settings_objects_a47ba18512efbe8.json b/test/mock_data/POST_api_v2_settings_objects_a47ba18512efbe8.json new file mode 100644 index 0000000..eea4685 --- /dev/null +++ b/test/mock_data/POST_api_v2_settings_objects_a47ba18512efbe8.json @@ -0,0 +1,6 @@ +[ + { + "code": 200, + "objectId": "vu9U3hXa3q0AAAABABdidWlsdGluOm93bmVyc2hpcC50ZWFtcwAGdGVuYW50AAZ0ZW5hbnQAJDVhNjk1MzViLWQ3NDYtMzVmYi05MDdjLTM2ODNkMmMyNWQzOb7vVN4V2t6t" + } +] \ No newline at end of file diff --git a/test/mock_data/PUT_api_v2_settings_objects_unittest_6ea3a764200250e.json b/test/mock_data/PUT_api_v2_settings_objects_unittest_6ea3a764200250e.json new file mode 100644 index 0000000..d8fcd3c --- /dev/null +++ b/test/mock_data/PUT_api_v2_settings_objects_unittest_6ea3a764200250e.json @@ -0,0 +1,4 @@ +{ + "code": 200, + "objectId": "vu9U3hXa3q0AAAABABdidWlsdGluOm93bmVyc2hpcC50ZWFtcwAGdGVuYW50AAZ0ZW5hbnQAJDVhNjk1MzViLWQ3NDYtMzVmYi05MDdjLTM2ODNkMmMyNWQzOb7vVN4V2t6t" +} \ No newline at end of file