Skip to content

Commit

Permalink
PORT-7618 | Dynatrace Ocean Integration with Invalid Entity Fields (#742
Browse files Browse the repository at this point in the history
)

# Description

What - Fixed bug affecting Entity blueprints where fields: firstSeenTms,
lastSeenTms, and tags; are missing
Why - So bugs won't be in the integration
How - Added query parameters to explicitly fetch these missing fields

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Screenshots
<img width="870" alt="Screenshot 2024-04-17 at 18 40 16"
src="https://github.com/port-labs/ocean/assets/33290249/c50ade96-0eae-42c7-beff-0adcffb182ba">


## API Documentation
[Monitored Entity
API](https://docs.dynatrace.com/docs/dynatrace-api/environment-api/entity-v2/get-entities-list#parameters)
  • Loading branch information
lordsarcastic authored Jun 25, 2024
1 parent d5bc6e3 commit be30f9b
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ resources:
selector:
query: "true"
entityTypes: ["APPLICATION", "SERVICE"]
entityFields: "firstSeenTms,lastSeenTms,tags"
port:
entity:
mappings:
Expand Down
11 changes: 11 additions & 0 deletions integrations/dynatrace/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- towncrier release notes start -->

# Port_Ocean 0.1.27 (2024-06-25)

### Features

- Fields included in response for Entity Types can now be configured (0.1.27)

### Bug Fixes

- Fixed bug causing missing fields in entities (0.1.27)


# Port_Ocean 0.1.26 (2024-06-23)

### Improvements
Expand Down
16 changes: 12 additions & 4 deletions integrations/dynatrace/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from port_ocean.context.event import event
from port_ocean.utils import http_async_client

from integration import DynatraceResourceConfig
from integration import DynatraceResourceConfig, EntityFieldsType


class ResourceKey(StrEnum):
Expand Down Expand Up @@ -61,20 +61,28 @@ async def get_slos(self) -> AsyncGenerator[list[dict[str, Any]], None]:
yield slos

async def _get_entities_from_type(
self, type_: str
self, type_: str, entity_fields: EntityFieldsType | None
) -> AsyncGenerator[list[dict[str, Any]], None]:
params = {
"entitySelector": f'type("{type_}")',
"pageSize": 100,
}
if entity_fields:
params["fields"] = entity_fields
async for entities in self._get_paginated_resources(
f"{self.host_url}/entities",
"entities",
params={"entitySelector": f'type("{type_}")', "pageSize": 100},
params=params,
):
yield entities

async def get_entities(self) -> AsyncGenerator[list[dict[str, Any]], None]:
selector = typing.cast(DynatraceResourceConfig, event.resource_config).selector

for entity_type in selector.entity_types:
async for entities in self._get_entities_from_type(entity_type):
async for entities in self._get_entities_from_type(
entity_type, selector.entity_fields
):
yield entities

async def get_single_problem(self, problem_id: str) -> dict[str, Any]:
Expand Down
27 changes: 27 additions & 0 deletions integrations/dynatrace/integration.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import re
from typing import Literal

from port_ocean.core.handlers.port_app_config.api import APIPortAppConfig
from port_ocean.core.handlers.port_app_config.models import (
PortAppConfig,
Expand All @@ -8,16 +11,40 @@
from pydantic.fields import Field


class EntityFieldsType(str):
@classmethod
def validate(cls, value: str) -> None:
# Regular expression to validate the format of the aggregation value
regex = (
r"^(\+?(firstSeenTms|lastSeenTms|tags|fromRelationships|icon"
r"|managementZones|properties|toRelationships|properties\.\d+)"
r"(,\+?(firstSeenTms|lastSeenTms|tags|fromRelationships|icon|"
r"managementZones|properties|toRelationships|properties\.\w+))*)*$"
)
if not re.match(regex, value):
raise ValueError(
"Invalid entity field format. Use 'firstSeenTms', 'lastSeenTms', 'tags', "
"'fronRelationships', 'icon', 'managementZones', 'properties', "
"'toRelationships', 'properties.FIELD' or comma-separated list"
" of specified values. Values can be prefixed with '+'."
)


class DynatraceEntitySelector(Selector):
entity_types: list[str] = Field(
default=["APPLICATION", "SERVICE"],
description="List of entity types to be fetched",
alias="entityTypes",
)

entity_fields: EntityFieldsType | None = Field(
description="List of fields to include in each entity", alias="entityFields"
)


class DynatraceResourceConfig(ResourceConfig):
selector: DynatraceEntitySelector
kind: Literal["entity"]


class DynatracePortAppConfig(PortAppConfig):
Expand Down
2 changes: 1 addition & 1 deletion integrations/dynatrace/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "dynatrace"
version = "0.1.26"
version = "0.1.27"
description = "An integration used to import Dynatrace resources into Port"
authors = ["Ayodeji Adeoti <<[email protected]>>"]

Expand Down

0 comments on commit be30f9b

Please sign in to comment.