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

feat(ingestion/grafana): Add datasets and charts to dashboards with lineage and tags. Lineage back to source #12417

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 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
187 changes: 187 additions & 0 deletions metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py
acrylJonny marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
"""Field extraction and processing utilities"""

from typing import Dict, List, Union

Check warning on line 3 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L3

Added line #L3 was not covered by tests

from datahub.ingestion.source.grafana.models import Panel
from datahub.metadata.schema_classes import (

Check warning on line 6 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L5-L6

Added lines #L5 - L6 were not covered by tests
NumberTypeClass,
SchemaFieldClass,
SchemaFieldDataTypeClass,
StringTypeClass,
TimeTypeClass,
)


def _deduplicate_fields(fields: List[SchemaFieldClass]) -> List[SchemaFieldClass]:

Check warning on line 15 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L15

Added line #L15 was not covered by tests
"""Remove duplicate fields based on fieldPath"""
seen = set()
unique_fields = []

Check warning on line 18 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L17-L18

Added lines #L17 - L18 were not covered by tests

for field in fields:
if field.fieldPath not in seen:
seen.add(field.fieldPath)
unique_fields.append(field)

Check warning on line 23 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L20-L23

Added lines #L20 - L23 were not covered by tests

return unique_fields

Check warning on line 25 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L25

Added line #L25 was not covered by tests


def extract_sql_column_fields(target: Dict) -> List[SchemaFieldClass]:

Check warning on line 28 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L28

Added line #L28 was not covered by tests
"""Extract fields from SQL-style columns"""
fields = []
columns = target.get("sql", {}).get("columns", [])

Check warning on line 31 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L30-L31

Added lines #L30 - L31 were not covered by tests

for col in columns:
if not col.get("parameters"):
continue

Check warning on line 35 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L33-L35

Added lines #L33 - L35 were not covered by tests

for param in col["parameters"]:
if not (param.get("name") and param.get("type") == "column"):
continue

Check warning on line 39 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L37-L39

Added lines #L37 - L39 were not covered by tests

field_type: Union[TimeTypeClass, NumberTypeClass, StringTypeClass]
if col["type"] == "time":
field_type = TimeTypeClass()
elif col["type"] == "number":
field_type = NumberTypeClass()

Check warning on line 45 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L42-L45

Added lines #L42 - L45 were not covered by tests
else:
field_type = StringTypeClass()

Check warning on line 47 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L47

Added line #L47 was not covered by tests

fields.append(

Check warning on line 49 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L49

Added line #L49 was not covered by tests
SchemaFieldClass(
fieldPath=param["name"],
type=SchemaFieldDataTypeClass(type=field_type),
nativeDataType=col["type"],
)
)

return fields

Check warning on line 57 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L57

Added line #L57 was not covered by tests


def extract_prometheus_fields(target: Dict) -> List[SchemaFieldClass]:

Check warning on line 60 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L60

Added line #L60 was not covered by tests
"""Extract fields from Prometheus expressions"""
if not target.get("expr"):
return []

Check warning on line 63 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L62-L63

Added lines #L62 - L63 were not covered by tests

return [

Check warning on line 65 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L65

Added line #L65 was not covered by tests
SchemaFieldClass(
fieldPath=target.get("legendFormat", target["expr"]),
type=SchemaFieldDataTypeClass(type=NumberTypeClass()),
nativeDataType="prometheus_metric",
)
]


def extract_raw_sql_fields(target: Dict) -> List[SchemaFieldClass]:

Check warning on line 74 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L74

Added line #L74 was not covered by tests
"""Extract fields from raw SQL queries"""
fields: List[SchemaFieldClass] = []
raw_sql = target.get("rawSql")
if not raw_sql:
return fields

Check warning on line 79 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L76-L79

Added lines #L76 - L79 were not covered by tests

try:
sql = raw_sql.lower()
select_start = sql.index("select") + 6
from_start = sql.index("from")
select_part = sql[select_start:from_start].strip()

Check warning on line 85 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L81-L85

Added lines #L81 - L85 were not covered by tests

columns = [col.strip().split()[-1].strip() for col in select_part.split(",")]

Check warning on line 87 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L87

Added line #L87 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

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

Assuming that split by , will actually split by columns may be wrong assumption, eg: SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM users
Not sure if we need to address this complexity though. WDYT?


for col in columns:
clean_col = col.split(" as ")[-1].strip('"').strip("'")
fields.append(

Check warning on line 91 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L89-L91

Added lines #L89 - L91 were not covered by tests
SchemaFieldClass(
fieldPath=clean_col,
type=SchemaFieldDataTypeClass(type=StringTypeClass()),
nativeDataType="sql_column",
)
)
except ValueError:
pass

Check warning on line 99 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L98-L99

Added lines #L98 - L99 were not covered by tests

return fields

Check warning on line 101 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L101

Added line #L101 was not covered by tests


def extract_time_format_fields(target: Dict) -> List[SchemaFieldClass]:

Check warning on line 104 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L104

Added line #L104 was not covered by tests
"""Extract fields from time series and table formats"""
if target.get("format") not in ["time_series", "table"]:
return []

Check warning on line 107 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L106-L107

Added lines #L106 - L107 were not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

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

should we log some warning here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've put this in logger but were you looking for this to be in the report?

Copy link
Contributor

Choose a reason for hiding this comment

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

logger should be fine
given we are catching three types of exceptions, adding the exception to the log trace may help to discriminate the issue

        logger.warning(f"Failed to parse SQL {target.get('rawSql')}", ex)


return [

Check warning on line 109 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L109

Added line #L109 was not covered by tests
SchemaFieldClass(
fieldPath="time",
type=SchemaFieldDataTypeClass(type=TimeTypeClass()),
nativeDataType="timestamp",
)
]


def extract_fields_from_panel(panel: Panel) -> List[SchemaFieldClass]:

Check warning on line 118 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L118

Added line #L118 was not covered by tests
"""Extract all fields from a panel"""
fields = []

Check warning on line 120 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L120

Added line #L120 was not covered by tests

# Extract from targets
for target in panel.targets:
fields.extend(extract_sql_column_fields(target))
fields.extend(extract_prometheus_fields(target))
fields.extend(extract_raw_sql_fields(target))
fields.extend(extract_time_format_fields(target))

Check warning on line 127 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L123-L127

Added lines #L123 - L127 were not covered by tests

# Extract from field config
fields.extend(get_fields_from_field_config(panel.field_config))

Check warning on line 130 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L130

Added line #L130 was not covered by tests

# Extract from transformations
fields.extend(get_fields_from_transformations(panel.transformations))

Check warning on line 133 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L133

Added line #L133 was not covered by tests

return _deduplicate_fields(fields)

Check warning on line 135 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L135

Added line #L135 was not covered by tests


def get_fields_from_field_config(field_config: Dict) -> List[SchemaFieldClass]:

Check warning on line 138 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L138

Added line #L138 was not covered by tests
"""Extract fields from field configuration"""
fields = []

Check warning on line 140 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L140

Added line #L140 was not covered by tests

# Process defaults
defaults = field_config.get("defaults", {})
if "unit" in defaults:
fields.append(

Check warning on line 145 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L143-L145

Added lines #L143 - L145 were not covered by tests
SchemaFieldClass(
fieldPath=f"value_{defaults.get('unit', 'unknown')}",
type=SchemaFieldDataTypeClass(type=NumberTypeClass()),
nativeDataType="value",
)
)

# Process overrides
for override in field_config.get("overrides", []):
matcher = override.get("matcher", {})
if matcher.get("id") == "byName":
field_name = matcher.get("options")
if field_name:
fields.append(

Check warning on line 159 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L154-L159

Added lines #L154 - L159 were not covered by tests
SchemaFieldClass(
fieldPath=field_name,
type=SchemaFieldDataTypeClass(type=NumberTypeClass()),
nativeDataType="metric",
)
)

return fields

Check warning on line 167 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L167

Added line #L167 was not covered by tests


def get_fields_from_transformations(

Check warning on line 170 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L170

Added line #L170 was not covered by tests
transformations: List[Dict],
) -> List[SchemaFieldClass]:
"""Extract fields from transformations"""
fields = []

Check warning on line 174 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L174

Added line #L174 was not covered by tests

for transform in transformations:
if transform.get("type") == "organize":
for field_name in transform.get("options", {}).get("indexByName", {}):
fields.append(

Check warning on line 179 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L176-L179

Added lines #L176 - L179 were not covered by tests
SchemaFieldClass(
fieldPath=field_name,
type=SchemaFieldDataTypeClass(type=StringTypeClass()),
nativeDataType="transformed",
)
)

return fields

Check warning on line 187 in metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/field_utils.py#L187

Added line #L187 was not covered by tests
acrylJonny marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
"""API client for Grafana metadata extraction"""

import logging
from typing import List, Optional

Check warning on line 4 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L3-L4

Added lines #L3 - L4 were not covered by tests

import requests
import urllib3.exceptions
from pydantic import SecretStr

Check warning on line 8 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L6-L8

Added lines #L6 - L8 were not covered by tests

from datahub.ingestion.source.grafana.models import Dashboard, Folder
from datahub.ingestion.source.grafana.report import GrafanaSourceReport

Check warning on line 11 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L10-L11

Added lines #L10 - L11 were not covered by tests

logger = logging.getLogger(__name__)

Check warning on line 13 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L13

Added line #L13 was not covered by tests


class GrafanaAPIClient:

Check warning on line 16 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L16

Added line #L16 was not covered by tests
"""Client for making requests to Grafana API"""

def __init__(

Check warning on line 19 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L19

Added line #L19 was not covered by tests
self,
base_url: str,
token: SecretStr,
verify_ssl: bool,
report: GrafanaSourceReport,
) -> None:
self.base_url = base_url
self.verify_ssl = verify_ssl
self.session = self._create_session(token)
self.report = report

Check warning on line 29 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L26-L29

Added lines #L26 - L29 were not covered by tests

def _create_session(self, token: SecretStr) -> requests.Session:
session = requests.Session()
session.headers.update(

Check warning on line 33 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L31-L33

Added lines #L31 - L33 were not covered by tests
{
"Authorization": f"Bearer {token.get_secret_value()}",
"Accept": "application/json",
"Content-Type": "application/json",
}
)
session.verify = self.verify_ssl

Check warning on line 40 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L40

Added line #L40 was not covered by tests

# If SSL verification is disabled, suppress the warnings
if not self.verify_ssl:
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

Check warning on line 44 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L43-L44

Added lines #L43 - L44 were not covered by tests

self.report.warning("SSL Verification is recommended.")

Check warning on line 46 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L46

Added line #L46 was not covered by tests

return session

Check warning on line 48 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L48

Added line #L48 was not covered by tests

def get_folders(self) -> List[Folder]:

Check warning on line 50 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L50

Added line #L50 was not covered by tests
"""Fetch all folders from Grafana"""
try:
response = self.session.get(f"{self.base_url}/api/folders")
response.raise_for_status()
return [Folder.from_dict(folder) for folder in response.json()]
except requests.exceptions.RequestException as e:
self.report.report_failure(

Check warning on line 57 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L52-L57

Added lines #L52 - L57 were not covered by tests
message="Failed to fetch folders",
exc=e,
)
return []

Check warning on line 61 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L61

Added line #L61 was not covered by tests

def get_dashboard(self, uid: str) -> Optional[Dashboard]:

Check warning on line 63 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L63

Added line #L63 was not covered by tests
"""Fetch a specific dashboard by UID"""
try:
response = self.session.get(f"{self.base_url}/api/dashboards/uid/{uid}")
response.raise_for_status()
return Dashboard.from_dict(response.json())
except requests.exceptions.RequestException as e:
self.report.warning(

Check warning on line 70 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L65-L70

Added lines #L65 - L70 were not covered by tests
message="Failed to fetch dashboard",
context=uid,
exc=e,
)
return None

Check warning on line 75 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L75

Added line #L75 was not covered by tests

def get_dashboards(self) -> List[Dashboard]:

Check warning on line 77 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L77

Added line #L77 was not covered by tests
"""Fetch all dashboards from search endpoint"""
try:
response = self.session.get(f"{self.base_url}/api/search?type=dash-db")
response.raise_for_status()

Check warning on line 81 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L79-L81

Added lines #L79 - L81 were not covered by tests

dashboards = []
for result in response.json():
dashboard = self.get_dashboard(result["uid"])
if dashboard:
dashboards.append(dashboard)

Check warning on line 87 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L83-L87

Added lines #L83 - L87 were not covered by tests

return dashboards
except requests.exceptions.RequestException as e:
self.report.report_failure(

Check warning on line 91 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L89-L91

Added lines #L89 - L91 were not covered by tests
message="Failed to fetch dashboards",
exc=e,
)
return []

Check warning on line 95 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_api.py#L95

Added line #L95 was not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from typing import Dict, Optional

Check warning on line 1 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L1

Added line #L1 was not covered by tests

from pydantic import Field, SecretStr, validator

Check warning on line 3 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L3

Added line #L3 was not covered by tests

from datahub.configuration.common import ConfigModel
from datahub.configuration.source_common import DatasetLineageProviderConfigBase
from datahub.ingestion.source.state.stale_entity_removal_handler import (

Check warning on line 7 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L5-L7

Added lines #L5 - L7 were not covered by tests
StatefulStaleMetadataRemovalConfig,
)
from datahub.ingestion.source.state.stateful_ingestion_base import (

Check warning on line 10 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L10

Added line #L10 was not covered by tests
StatefulIngestionConfigBase,
)
from datahub.utilities import config_clean

Check warning on line 13 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L13

Added line #L13 was not covered by tests


class PlatformConnectionConfig(ConfigModel):
platform: str = Field(description="Platform to connect to")
database: Optional[str] = Field(default=None, description="Database name")
database_schema: Optional[str] = Field(default=None, description="Schema name")
platform_instance: Optional[str] = Field(

Check warning on line 20 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L16-L20

Added lines #L16 - L20 were not covered by tests
default=None, description="Platform instance"
)
env: str = Field(default="PROD", description="Environment")

Check warning on line 23 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L23

Added line #L23 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

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

These two may be removed if using PlatformInstanceConfigMixin and EnvConfigMixin in GrafanaSourceConfig, are they really needed at PlatformConnectionConfig?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the to use the parent class

Copy link
Contributor

Choose a reason for hiding this comment

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

platform_instance and env still there as well as platform_instance in GrafanaSourceConfig 🤔

what parent class do you refer to?



class GrafanaSourceConfig(

Check warning on line 26 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L26

Added line #L26 was not covered by tests
StatefulIngestionConfigBase, DatasetLineageProviderConfigBase
):
platform: str = Field(default="grafana", hidden_from_docs=True)
url: str = Field(

Check warning on line 30 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L29-L30

Added lines #L29 - L30 were not covered by tests
description="URL of Grafana instance (e.g. https://grafana.company.com)"
)
service_account_token: SecretStr = Field(description="Grafana API token")
verify_ssl: bool = Field(

Check warning on line 34 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L33-L34

Added lines #L33 - L34 were not covered by tests
default=True,
description="Verify SSL certificate for secure connections (https)",
)
ingest_tags: bool = Field(

Check warning on line 38 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L38

Added line #L38 was not covered by tests
default=True,
description="Whether to ingest tags from Grafana dashboards and charts",
)
ingest_owners: bool = Field(

Check warning on line 42 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L42

Added line #L42 was not covered by tests
default=True,
description="Whether to ingest owners from Grafana dashboards and charts",
)
platform_instance: Optional[str] = Field(

Check warning on line 46 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L46

Added line #L46 was not covered by tests
default=None, description="Platform instance for DataHub"
)
connection_to_platform_map: Dict[str, PlatformConnectionConfig] = Field(

Check warning on line 49 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L49

Added line #L49 was not covered by tests
default={},
description="Map of Grafana connection names to their upstream platform details",
)
stateful_ingestion: Optional[StatefulStaleMetadataRemovalConfig] = None

Check warning on line 53 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L53

Added line #L53 was not covered by tests

@validator("url")
def remove_trailing_slash(cls, v):
return config_clean.remove_trailing_slashes(v)

Check warning on line 57 in metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py

View check run for this annotation

Codecov / codecov/patch

metadata-ingestion/src/datahub/ingestion/source/grafana/grafana_config.py#L55-L57

Added lines #L55 - L57 were not covered by tests
Loading
Loading