From 3f2106373ba987ed6f9548b3f24aa659cf72a06b Mon Sep 17 00:00:00 2001 From: dlopes7 Date: Thu, 13 May 2021 19:40:32 -0300 Subject: [PATCH] Implement the rest of config/v1/extensions --- README.md | 112 +++++------ .../{extension.py => extensions.py} | 118 +++++++++++- dynatrace/http_client.py | 10 +- dynatrace/main.py | 2 +- setup.py | 2 +- test/configuration_v1/test_extensions.py | 92 +++++++++ .../GET_api_config_v1_extensions.json | 180 ++++++++++++++++++ ...extensions_activeGateExtensionModules.json | 12 ++ ..._extensions_custom.python.citrixAgent.json | 78 ++++++++ ...ions_custom.python.citrixAgent_global.json | 17 ++ ...tstream_instances_5649014104314746667.json | 29 +++ ....python.salesforce_eventstream_states.json | 15 ++ 12 files changed, 597 insertions(+), 70 deletions(-) rename dynatrace/configuration_v1/{extension.py => extensions.py} (52%) create mode 100644 test/configuration_v1/test_extensions.py create mode 100644 test/mock_data/GET_api_config_v1_extensions.json create mode 100644 test/mock_data/GET_api_config_v1_extensions_activeGateExtensionModules.json create mode 100644 test/mock_data/GET_api_config_v1_extensions_custom.python.citrixAgent.json create mode 100644 test/mock_data/GET_api_config_v1_extensions_custom.python.citrixAgent_global.json create mode 100644 test/mock_data/GET_api_config_v1_extensions_custom.remote.python.salesforce_eventstream_instances_5649014104314746667.json create mode 100644 test/mock_data/GET_api_config_v1_extensions_custom.remote.python.salesforce_eventstream_states.json diff --git a/README.md b/README.md index c4abb2e..15f0c0f 100644 --- a/README.md +++ b/README.md @@ -127,59 +127,59 @@ User sessions | :x: | ### Configuration API V1 -API | Level | Access | -:------------- | :-------------: | :----- | -Alerting Profiles | :x: | | -Anomaly detection - Applications | :x: | | -Anomaly detection - AWS | :x: | | -Anomaly detection - Database services | :x: | | -Anomaly detection - Disk events | :x: | | -Anomaly detection - Hosts | :x: | | -Anomaly detection - Metric events | :x: | | -Anomaly detection - Process groups | :x: | | -Anomaly detection - Services | :x: | | -Anomaly detection - VMware | :x: | | -Automatically applied tags | :x: | | -AWS credentials configuration | :x: | | -AWS PrivateLink | :x: | | -Azure credentials configuration | :x: | | -Calculated metrics - Log monitoring | :x: | | -Calculated metrics - Mobile & custom applications | :x: | | -Calculated metrics - Services | :x: | | -Calculated metrics - Synthetic | :x: | | -Calculated metrics - Web applications | :x: | | -Cloud Foundry credentials configuration | :x: | | -Conditional naming | :x: | | -Credential vault | :x: | | -Dashboards | :warning: | `dt.dashboards` | -Data privacy and security | :x: | | -Extensions | :warning: | `dt.extensions` | -Frequent issue detection | :x: | | -Kubernetes credentials configuration | :x: | | -Maintenance windows | :x: | | -Management zones | :warning: | | -Notifications | :warning: | `dt.notifications` | -OneAgent - Environment-wide configuration | :x: | | -OneAgent in a host group | :x: | | -OneAgent on a host | :x: | | -Plugins | :warning: | `dt.plugins` | -Remote environments | :x: | | -Reports | :x: | | -RUM - Allowed beacon origins for CORS | :x: | | -RUM - Application detection rules | :x: | | -RUM - Application detection rules - Host detection | :x: | | -RUM - Content resources | :x: | | -RUM - Geographic regions - custom client IP headers | :x: | | -RUM - Geographic regions - IP address mapping | :x: | | -RUM - Mobile and custom application configuration | :x: | | -RUM - Web application configuration | :x: | | -Service - Custom services | :x: | | -Service - Detection full web request | :x: | | -Service - Detection full web service | :x: | | -Service - Detection opaque and external web request | :x: | | -Service - Detection opaque and external web service | :x: | | -Service - Failure detection parameter sets | :x: | | -Service - Failure detection rules | :x: | | -Service - IBM MQ tracing | :x: | | -Service - Request attributes | :x: | | -Service - Request naming | :x: | | +API | Level | Access | +:------------- | :-------------: | :----- | +Alerting Profiles | :x: | | +Anomaly detection - Applications | :x: | | +Anomaly detection - AWS | :x: | | +Anomaly detection - Database services | :x: | | +Anomaly detection - Disk events | :x: | | +Anomaly detection - Hosts | :x: | | +Anomaly detection - Metric events | :x: | | +Anomaly detection - Process groups | :x: | | +Anomaly detection - Services | :x: | | +Anomaly detection - VMware | :x: | | +Automatically applied tags | :x: | | +AWS credentials configuration | :x: | | +AWS PrivateLink | :x: | | +Azure credentials configuration | :x: | | +Calculated metrics - Log monitoring | :x: | | +Calculated metrics - Mobile & custom applications | :x: | | +Calculated metrics - Services | :x: | | +Calculated metrics - Synthetic | :x: | | +Calculated metrics - Web applications | :x: | | +Cloud Foundry credentials configuration | :x: | | +Conditional naming | :x: | | +Credential vault | :x: | | +Dashboards | :warning: | `dt.dashboards` | +Data privacy and security | :x: | | +Extensions | :heavy_check_mark: | `dt.extensions` | +Frequent issue detection | :x: | | +Kubernetes credentials configuration | :x: | | +Maintenance windows | :x: | | +Management zones | :warning: | | +Notifications | :warning: | `dt.notifications` | +OneAgent - Environment-wide configuration | :x: | | +OneAgent in a host group | :x: | | +OneAgent on a host | :x: | | +Plugins | :warning: | `dt.plugins` | +Remote environments | :x: | | +Reports | :x: | | +RUM - Allowed beacon origins for CORS | :x: | | +RUM - Application detection rules | :x: | | +RUM - Application detection rules - Host detection | :x: | | +RUM - Content resources | :x: | | +RUM - Geographic regions - custom client IP headers | :x: | | +RUM - Geographic regions - IP address mapping | :x: | | +RUM - Mobile and custom application configuration | :x: | | +RUM - Web application configuration | :x: | | +Service - Custom services | :x: | | +Service - Detection full web request | :x: | | +Service - Detection full web service | :x: | | +Service - Detection opaque and external web request | :x: | | +Service - Detection opaque and external web service | :x: | | +Service - Failure detection parameter sets | :x: | | +Service - Failure detection rules | :x: | | +Service - IBM MQ tracing | :x: | | +Service - Request attributes | :x: | | +Service - Request naming | :x: | | diff --git a/dynatrace/configuration_v1/extension.py b/dynatrace/configuration_v1/extensions.py similarity index 52% rename from dynatrace/configuration_v1/extension.py rename to dynatrace/configuration_v1/extensions.py index 73f0046..81dc0bf 100644 --- a/dynatrace/configuration_v1/extension.py +++ b/dynatrace/configuration_v1/extensions.py @@ -1,4 +1,7 @@ -from typing import List, Dict, Any, Optional +from datetime import datetime +from enum import Enum +from pathlib import Path +from typing import List, Dict, Any, Optional, Union from requests import Response @@ -10,6 +13,8 @@ class ExtensionService: + + # TODO - Early adopter as of May 12th 2021. Check back for updates def __init__(self, http_client: HttpClient): self.__http_client = http_client pass @@ -26,7 +31,21 @@ def list(self, page_size: int = 200) -> PaginatedList["ExtensionDto"]: def get(self, extension_id: str): response = self.__http_client.make_request(f"/api/config/v1/extensions/{extension_id}").json() - return Extension(self.__http_client, None, response) + return Extension(raw_element=response) + + def post(self, zip_file_path: str) -> EntityShortRepresentation: + + file = Path(zip_file_path) + with open(file, "rb") as f: + response = self.__http_client.make_request("/api/config/v1/extensions", method="POST", files={"file": f}) + + return EntityShortRepresentation(raw_element=response.json()) + + def validate(self, zip_file_path: str) -> Response: + + file = Path(zip_file_path) + with open(file, "rb") as f: + return self.__http_client.make_request("/api/config/v1/extensions/validator", method="POST", files={"file": f}) def list_instances(self, extension_id: str, page_size: int = 200) -> PaginatedList["ExtensionShortRepresentation"]: params = {"pageSize": page_size} @@ -40,11 +59,46 @@ def list_instances(self, extension_id: str, page_size: int = 200) -> PaginatedLi def get_instance(self, extension_id: str, configuration_id: str): response = self.__http_client.make_request(f"/api/config/v1/extensions/{extension_id}/instances/{configuration_id}").json() - return ExtensionConfigurationDto(self.__http_client, None, response) + return ExtensionConfigurationDto(http_client=self.__http_client, raw_element=response) def post_instance(self, extension_configuration: "ExtensionConfigurationDto"): return extension_configuration.post() + def validate_instance(self, extension_configuration: "ExtensionConfigurationDto") -> Response: + return extension_configuration.validate() + + def get_instance_configuration(self, extension_id: str, configuration_id: str) -> "ExtensionConfigurationDto": + response = self.__http_client.make_request(f"/api/config/v1/extensions/{extension_id}/instances/{configuration_id}").json() + return ExtensionConfigurationDto(http_client=self.__http_client, raw_element=response) + + # TODO - Can't implement put_instance because of APM-300262, fixed in 1.219 + + def delete_instance_configuration(self, extension_id: str, configuration_id: str) -> Response: + return self.__http_client.make_request(f"/api/config/v1/extensions/{extension_id}/instances/{configuration_id}", method="DELETE") + + def get_global_configuration(self, extension_id: str) -> "GlobalExtensionConfiguration": + response = self.__http_client.make_request(f"/api/config/v1/extensions/{extension_id}/global").json() + return GlobalExtensionConfiguration(raw_element=response) + + def get_binary(self, extension_id: str) -> bytes: + return self.__http_client.make_request(f"/api/config/v1/extensions/{extension_id}/binary").content + + def list_states(self, extension_id: str) -> PaginatedList["ExtensionState"]: + return PaginatedList( + ExtensionState, + self.__http_client, + f"/api/config/v1/extensions/{extension_id}/states", + list_item="states", + ) + + def list_activegate_extension_modules(self) -> PaginatedList[EntityShortRepresentation]: + return PaginatedList( + EntityShortRepresentation, + self.__http_client, + f"/api/config/v1/extensions/activeGateExtensionModules", + list_item="values", + ) + def create_instance( self, extension_id: str, @@ -52,7 +106,7 @@ def create_instance( enabled: Optional[bool] = True, use_global: Optional[bool] = True, host_id: Optional[str] = None, - active_gate: Optional[EntityShortRepresentation] = None, + activegate: Optional[EntityShortRepresentation] = None, endpoint_id: Optional[str] = None, endpoint_name: Optional[str] = None, ) -> "ExtensionConfigurationDto": @@ -63,12 +117,12 @@ def create_instance( "useGlobal": use_global, "properties": properties, "hostId": host_id, - "activeGate": active_gate._raw_element if active_gate else {}, + "activeGate": activegate._raw_element if activegate else {}, "endpointId": endpoint_id, "endpointName": endpoint_name, } - return ExtensionConfigurationDto(self.__http_client, None, raw_element) + return ExtensionConfigurationDto(http_client=self.__http_client, raw_element=raw_element) class ExtensionProperty(DynatraceObject): @@ -83,6 +137,9 @@ class ExtensionConfigurationDto(DynatraceObject): def post(self): return self._http_client.make_request(f"/api/config/v1/extensions/{self.extension_id}/instances", params=self._raw_element, method="POST") + def validate(self): + return self._http_client.make_request(f"/api/config/v1/extensions/{self.extension_id}/instances/validator", params=self._raw_element, method="POST") + def _create_from_raw_data(self, raw_element): self.extension_id: str = raw_element.get("extensionId") self.enabled: bool = raw_element.get("enabled") @@ -107,18 +164,27 @@ class Extension(DynatraceObject): def _create_from_raw_data(self, raw_element): self.id: str = raw_element.get("id") self.name: str = raw_element.get("name") - self.type: str = raw_element.get("type") + self.type: str = ExtensionType(raw_element.get("type")) self.version: str = raw_element.get("version") self.metric_group: str = raw_element.get("metricGroup") self.metadata: ConfigurationMetadata = ConfigurationMetadata(self._http_client, None, raw_element.get("metadata")) self.properties: List[ExtensionProperty] = [ExtensionProperty(self._http_client, None, prop) for prop in raw_element.get("properties")] +class ExtensionType(Enum): + ACTIVEGATE = "ACTIVEGATE" + CODEMODULE = "CODEMODULE" + JMX = "JMX" + ONEAGENT = "ONEAGENT" + PMI = "PMI" + UNKNOWN = "UNKNOWN" + + class ExtensionDto(DynatraceObject): def _create_from_raw_data(self, raw_element): self.id: str = raw_element.get("id") self.name: str = raw_element.get("name") - self.type: str = raw_element.get("type") + self.type: ExtensionType = ExtensionType(raw_element.get("type")) def get_full_extension(self) -> Extension: """ @@ -141,3 +207,39 @@ def delete(self) -> Response: Deletes the ZIP file of this extension """ return self._http_client.make_request(f"/api/config/v1/extensions/{self.id}", method="DELETE") + + +class GlobalExtensionConfiguration(DynatraceObject): + def _create_from_raw_data(self, raw_element: Dict[str, Any]): + self.enabled: bool = raw_element.get("enabled") + self.extension_id: Optional[str] = raw_element.get("extensionId") + self.infraOnlyEnabled: Optional[bool] = raw_element.get("infraOnlyEnabled") + self.properties: Optional[Dict[str, Any]] = raw_element.get("properties") + + +class ExtensionStateEnum(Enum): + ERROR_AUTH = "ERROR_AUTH" + ERROR_COMMUNICATION_FAILURE = "ERROR_COMMUNICATION_FAILURE" + ERROR_CONFIG = "ERROR_CONFIG" + ERROR_TIMEOUT = "ERROR_TIMEOUT" + ERROR_UNKNOWN = "ERROR_UNKNOWN" + INCOMPATIBLE = "INCOMPATIBLE" + LIMIT_REACHED = "LIMIT_REACHED" + NOTHING_TO_REPORT = "NOTHING_TO_REPORT" + OK = "OK" + STATE_TYPE_UNKNOWN = "STATE_TYPE_UNKNOWN" + UNINITIALIZED = "UNINITIALIZED" + UNSUPPORTED = "UNSUPPORTED" + WAITING_FOR_STATE = "WAITING_FOR_STATE" + + +class ExtensionState(DynatraceObject): + def _create_from_raw_data(self, raw_element: Dict[str, Any]): + self.extension_id: Optional[str] = raw_element.get("extensionId") + self.version: Optional[str] = raw_element.get("version") + self.endpoint_id: Optional[str] = raw_element.get("endpointId") + self.state: Optional[ExtensionStateEnum] = ExtensionStateEnum(raw_element.get("state")) + self.state_description: Optional[str] = raw_element.get("stateDescription") + self.host_id: Optional[str] = raw_element.get("hostId") + self.process_id: Optional[str] = raw_element.get("processId") + self.timestamp: Optional[datetime] = datetime.utcfromtimestamp(raw_element.get("timestamp") / 1000) diff --git a/dynatrace/http_client.py b/dynatrace/http_client.py index 0305459..605ff13 100644 --- a/dynatrace/http_client.py +++ b/dynatrace/http_client.py @@ -65,7 +65,7 @@ def __init__( self.mc_b925d32c = mc_b925d32c self.mc_sso_csrf_cookie = mc_sso_csrf_cookie - def make_request(self, path: str, params: Optional[Dict] = None, headers: Optional[Dict] = None, method="GET", data=None) -> requests.Response: + def make_request(self, path: str, params: Optional[Dict] = None, headers: Optional[Dict] = None, method="GET", data=None, files=None) -> requests.Response: url = f"{self.base_url}{path}" body = None @@ -74,7 +74,9 @@ def make_request(self, path: str, params: Optional[Dict] = None, headers: Option params = None if headers is None: - headers = {"content-type": "application/json"} + headers = {} + if files is None: + headers.update({"content-type": "application/json"}) headers.update(self.auth_header) cookies = None @@ -86,7 +88,7 @@ def make_request(self, path: str, params: Optional[Dict] = None, headers: Option s.mount("https://", HTTPAdapter(max_retries=self.retries)) self.log.debug(f"Making {method} request to '{url}' with params {params} and body: {body}") - r = s.request(method, url, headers=headers, params=params, json=body, verify=False, proxies=self.proxies, data=data, cookies=cookies) + r = s.request(method, url, headers=headers, params=params, json=body, verify=False, proxies=self.proxies, data=data, cookies=cookies, files=files) self.log.debug(f"Received response '{r}'") while r.status_code == 429 and self.too_many_requests_strategy == TOO_MANY_REQUESTS_WAIT: @@ -96,6 +98,6 @@ def make_request(self, path: str, params: Optional[Dict] = None, headers: Option r = requests.request(method, url, headers=headers, params=params, json=body, verify=False, proxies=self.proxies) if r.status_code >= 400: - raise Exception(f"Error making request to {url}: {r}. Response: {r.text}, Parameters: {params}, Body: {body}, Headers: {r.headers}") + raise Exception(f"Error making request to {url}: {r}. Response: {r.text}") return r diff --git a/dynatrace/main.py b/dynatrace/main.py index 921face..1f29827 100644 --- a/dynatrace/main.py +++ b/dynatrace/main.py @@ -3,7 +3,7 @@ from dynatrace.configuration_v1.alerting_profiles import AlertingProfileService from dynatrace.configuration_v1.dashboard import DashboardService -from dynatrace.configuration_v1.extension import ExtensionService +from dynatrace.configuration_v1.extensions import ExtensionService from dynatrace.configuration_v1.maintenance_windows import MaintenanceWindowService from dynatrace.configuration_v1.metric_events import MetricEventService from dynatrace.configuration_v1.notifications import NotificationService diff --git a/setup.py b/setup.py index e64c751..538c003 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="dtapi", - version="1.1.20", + version="1.1.21", packages=find_packages(), install_requires=["requests>=2.21"], tests_require=["pytest", "mock", "tox"], diff --git a/test/configuration_v1/test_extensions.py b/test/configuration_v1/test_extensions.py new file mode 100644 index 0000000..0310120 --- /dev/null +++ b/test/configuration_v1/test_extensions.py @@ -0,0 +1,92 @@ +from datetime import datetime + +from dynatrace import Dynatrace +from dynatrace.configuration_v1.extensions import ExtensionDto, ExtensionType, Extension, ExtensionProperty, GlobalExtensionConfiguration, ExtensionState, ExtensionStateEnum, ExtensionConfigurationDto +from dynatrace.environment_v2.monitored_entities import EntityShortRepresentation +from dynatrace.pagination import PaginatedList + + +def test_list(dt: Dynatrace): + extensions = dt.extensions.list() + assert isinstance(extensions, PaginatedList) + + extensions_list = list(extensions) + assert len(extensions_list) == 35 + first = extensions_list[0] + + assert isinstance(first, ExtensionDto) + assert first.id == "custom.remote.python.certificates" + assert first.name == "Certificates Plugin" + assert first.type == ExtensionType.ACTIVEGATE + + +def test_get(dt: Dynatrace): + extension = dt.extensions.get("custom.python.citrixAgent") + assert isinstance(extension, Extension) + assert extension.id == "custom.python.citrixAgent" + assert extension.name == "Citrix Virtual Apps & Virtual Desktops" + assert extension.version == "2.034" + assert extension.type == ExtensionType.ONEAGENT + assert extension.metric_group == "tech.Citrix" + assert isinstance(extension.properties, list) + + first_property = extension.properties[0] + assert isinstance(first_property, ExtensionProperty) + assert first_property.key == "openkit_verify_certificates" + assert first_property.type == "BOOLEAN" + + +def test_get_global_configuration(dt: Dynatrace): + global_config = dt.extensions.get_global_configuration("custom.python.citrixAgent") + assert isinstance(global_config, GlobalExtensionConfiguration) + assert global_config.extension_id == "custom.python.citrixAgent" + assert global_config.enabled + assert not global_config.infraOnlyEnabled + assert global_config.properties["log_level"] == "INFO" + + +def test_get_state(dt: Dynatrace): + states = dt.extensions.list_states("custom.remote.python.salesforce_eventstream") + assert isinstance(states, PaginatedList) + + list_states = list(states) + assert isinstance(list_states, list) + + first = list_states[0] + assert isinstance(first, ExtensionState) + assert first.extension_id == "custom.remote.python.salesforce_eventstream" + assert first.version == "" + assert first.endpoint_id == "5649014104314746667" + assert first.state == ExtensionStateEnum.ERROR_CONFIG + assert first.state_description == "Extension doesn't exist on given host" + assert first.timestamp == datetime.utcfromtimestamp(1620943873929 / 1000) + assert first.host_id is None + assert first.process_id is None + + +def test_get_instance_configuration(dt: Dynatrace): + config = dt.extensions.get_instance_configuration("custom.remote.python.salesforce_eventstream", "5649014104314746667") + assert isinstance(config, ExtensionConfigurationDto) + + # TODO - This is a bug on Dynatrace, watch for the fix, this is the configuration ID + assert config.extension_id == "5649014104314746667" + + assert config.enabled + assert config.active_gate.id == "-7885258652650793909" + assert config.active_gate.name == "arch-david" + assert config.endpoint_id == "5649014104314746667" + assert config.endpoint_name == "curious-hawk" + assert config.properties["openkit_application_id"] == "87eee414-9338-446b-988b-bbdbf495c4f4" + + +def test_list_activegate_extension_modules(dt: Dynatrace): + modules = dt.extensions.list_activegate_extension_modules() + assert isinstance(modules, PaginatedList) + + list_modules = list(modules) + assert isinstance(list_modules, list) + + first = list_modules[0] + assert isinstance(first, EntityShortRepresentation) + assert first.id == "-7885258652650793909" + assert first.name == "arch-david" diff --git a/test/mock_data/GET_api_config_v1_extensions.json b/test/mock_data/GET_api_config_v1_extensions.json new file mode 100644 index 0000000..fdd3b3e --- /dev/null +++ b/test/mock_data/GET_api_config_v1_extensions.json @@ -0,0 +1,180 @@ +{ + "extensions": [ + { + "id": "custom.remote.python.certificates", + "name": "Certificates Plugin", + "type": "ACTIVEGATE" + }, + { + "id": "custom.remote.python.dbquery", + "name": "Generic DB Query Plugin", + "type": "ACTIVEGATE" + }, + { + "id": "custom.remote.python.salesforce_eventstream", + "name": "Salesforce EventStream", + "type": "ACTIVEGATE" + }, + { + "id": "dynatrace.jmx.Hadoop.HDFS", + "name": "Apache Hadoop HDFS", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.Hadoop.yarn", + "name": "Apache Hadoop YARN", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.activemq", + "name": "ActiveMQ JMX", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.appserver.jetty", + "name": "Jetty JMX", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.cassandra", + "name": "Cassandra JMX", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.hornetq", + "name": "HornetQ JMX", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.jboss.connectionpool", + "name": "JBoss Connection Pools", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.kafka", + "name": "Kafka JMX", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.liberty.appserver", + "name": "WebSphere Liberty Appserver", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.liberty.connectionpool", + "name": "WebSphere Liberty Connection Pools", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.netflix.servo", + "name": "Netflix OSS JMX", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.solr", + "name": "Solr JMX", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.spark", + "name": "Apache Spark", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.tomcat.connectionpool", + "name": "Tomcat Connection Pools", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.weblogic.connectionpool", + "name": "WebLogic Connection Pools", + "type": "JMX" + }, + { + "id": "dynatrace.jmx.wso2-api-manager", + "name": "WSO2 API Manager", + "type": "JMX" + }, + { + "id": "dynatrace.python.coredns", + "name": "CoreDNS", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.couchbase", + "name": "Couchbase", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.couchdb", + "name": "CouchDB", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.docker", + "name": "Docker technology monitoring", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.elasticsearch", + "name": "Elasticsearch", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.haproxy", + "name": "HAProxy", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.memcached", + "name": "Memcached", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.mongodb", + "name": "MongoDB", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.mssql", + "name": "MS SQL", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.mysql", + "name": "MySQL", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.ntp", + "name": "NTP", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.phpfpm", + "name": "PHP-FPM", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.postgresql", + "name": "PostgreSQL", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.rabbitmq", + "name": "RabbitMQ", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.python.redis", + "name": "Redis", + "type": "ONEAGENT" + }, + { + "id": "dynatrace.remote.python.elasticsearch", + "name": "Elasticsearch Cloud", + "type": "ACTIVEGATE" + } + ], + "totalResults": 35 +} \ No newline at end of file diff --git a/test/mock_data/GET_api_config_v1_extensions_activeGateExtensionModules.json b/test/mock_data/GET_api_config_v1_extensions_activeGateExtensionModules.json new file mode 100644 index 0000000..b94208f --- /dev/null +++ b/test/mock_data/GET_api_config_v1_extensions_activeGateExtensionModules.json @@ -0,0 +1,12 @@ +{ + "values": [ + { + "id": "-7885258652650793909", + "name": "arch-david" + }, + { + "id": "-7683927725266039098", + "name": "windows-david" + } + ] +} \ No newline at end of file diff --git a/test/mock_data/GET_api_config_v1_extensions_custom.python.citrixAgent.json b/test/mock_data/GET_api_config_v1_extensions_custom.python.citrixAgent.json new file mode 100644 index 0000000..eb5d136 --- /dev/null +++ b/test/mock_data/GET_api_config_v1_extensions_custom.python.citrixAgent.json @@ -0,0 +1,78 @@ +{ + "id": "custom.python.citrixAgent", + "name": "Citrix Virtual Apps & Virtual Desktops", + "version": "2.034", + "type": "ONEAGENT", + "metricGroup": "tech.Citrix", + "metadata": { + "configurationVersions": [ + 0 + ], + "clusterVersion": "1.217.103.20210511-092057" + }, + "properties": [ + { + "key": "openkit_verify_certificates", + "type": "BOOLEAN", + "defaultValue": "" + }, + { + "key": "openkit_use_oneagent_endpoints", + "type": "BOOLEAN", + "defaultValue": "false" + }, + { + "key": "openkit_application_id", + "type": "STRING", + "defaultValue": "" + }, + { + "key": "monitoring_mode", + "type": "DROPDOWN", + "defaultValue": "Basic", + "dropdownValues": [ + "Basic", + "Default", + "Advanced" + ] + }, + { + "key": "openkit_beacon_url", + "type": "STRING", + "defaultValue": "" + }, + { + "key": "openkit_proxy_username", + "type": "STRING", + "defaultValue": "" + }, + { + "key": "log_level", + "type": "DROPDOWN", + "defaultValue": "INFO", + "dropdownValues": [ + "INFO", + "DEBUG" + ] + }, + { + "key": "citrixagent_run", + "type": "DROPDOWN", + "defaultValue": "Enabled", + "dropdownValues": [ + "Enabled", + "Disabled" + ] + }, + { + "key": "openkit_proxy_address", + "type": "STRING", + "defaultValue": "" + }, + { + "key": "openkit_proxy_password", + "type": "PASSWORD", + "defaultValue": "" + } + ] +} \ No newline at end of file diff --git a/test/mock_data/GET_api_config_v1_extensions_custom.python.citrixAgent_global.json b/test/mock_data/GET_api_config_v1_extensions_custom.python.citrixAgent_global.json new file mode 100644 index 0000000..1f6df55 --- /dev/null +++ b/test/mock_data/GET_api_config_v1_extensions_custom.python.citrixAgent_global.json @@ -0,0 +1,17 @@ +{ + "extensionId": "custom.python.citrixAgent", + "enabled": true, + "infraOnlyEnabled": false, + "properties": { + "openkit_verify_certificates": "", + "openkit_use_oneagent_endpoints": "false", + "openkit_application_id": "", + "monitoring_mode": "Basic", + "openkit_beacon_url": "", + "openkit_proxy_username": "", + "log_level": "INFO", + "citrixagent_run": "Enabled", + "openkit_proxy_address": "", + "openkit_proxy_password": null + } +} \ No newline at end of file diff --git a/test/mock_data/GET_api_config_v1_extensions_custom.remote.python.salesforce_eventstream_instances_5649014104314746667.json b/test/mock_data/GET_api_config_v1_extensions_custom.remote.python.salesforce_eventstream_instances_5649014104314746667.json new file mode 100644 index 0000000..79a1ffc --- /dev/null +++ b/test/mock_data/GET_api_config_v1_extensions_custom.remote.python.salesforce_eventstream_instances_5649014104314746667.json @@ -0,0 +1,29 @@ +{ + "extensionId": "5649014104314746667", + "enabled": true, + "useGlobal": null, + "properties": { + "salesforce_password": null, + "capture_listview": "true", + "max_session_age_minutes": "1440", + "proxy_address": "http://192.168.15.101:3128", + "proxy_username": "", + "capture_uri": "true", + "log_level": "INFO", + "salesforce_username": "david.lopes@dynapoc.unicredit0001", + "proxy_password": null, + "capture_report": "true", + "capture_lightning_uri": "true", + "salesforce_security_token": null, + "openkit_application_id": "87eee414-9338-446b-988b-bbdbf495c4f4", + "openkit_beacon_url": "https://localhost:9999/mbeacon/eaa50379", + "capture_api": "true", + "capture_user_details": "true" + }, + "activeGate": { + "id": "-7885258652650793909", + "name": "arch-david" + }, + "endpointId": "5649014104314746667", + "endpointName": "curious-hawk" +} \ No newline at end of file diff --git a/test/mock_data/GET_api_config_v1_extensions_custom.remote.python.salesforce_eventstream_states.json b/test/mock_data/GET_api_config_v1_extensions_custom.remote.python.salesforce_eventstream_states.json new file mode 100644 index 0000000..13564fd --- /dev/null +++ b/test/mock_data/GET_api_config_v1_extensions_custom.remote.python.salesforce_eventstream_states.json @@ -0,0 +1,15 @@ +{ + "states": [ + { + "extensionId": "custom.remote.python.salesforce_eventstream", + "version": "", + "endpointId": "5649014104314746667", + "state": "ERROR_CONFIG", + "stateDescription": "Extension doesn't exist on given host", + "timestamp": 1620943873929, + "hostId": null, + "processId": null + } + ], + "totalResults": 1 +} \ No newline at end of file