Added flag for overriding owners (#10425)

* added flag for overriding owners

* docs update

* adding owners in patch call

* adding owners in patch call

* fix: python test case

* changes as per comment

* changes as per comment

* ui changes
This commit is contained in:
NiharDoshi99 2023-03-10 15:01:56 +05:30 committed by GitHub
parent 4ec185ff22
commit 9b0b06fe25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 118 additions and 11 deletions

View File

@ -397,9 +397,9 @@ class OMetaPatchMixin(Generic[T]):
# Don't change existing data without force
if instance.owner and not force:
logger.error(
logger.warning(
f"The entity with id [{model_str(entity_id)}] already has an owner."
" To overwrite it, set `force` to True."
" To overwrite it, set `overrideOwner` to True."
)
return None

View File

@ -30,6 +30,7 @@ from metadata.generated.schema.entity.services.dashboardService import (
DashboardConnection,
DashboardService,
)
from metadata.generated.schema.entity.teams.user import User
from metadata.generated.schema.metadataIngestion.dashboardServiceMetadataPipeline import (
DashboardServiceMetadataPipeline,
)
@ -112,6 +113,12 @@ class DashboardServiceTopology(ServiceTopology):
processor="yield_dashboard",
consumer=["dashboard_service"],
),
NodeStage(
type_=User,
context="owner",
processor="process_owner",
consumer=["dashboard_service"],
),
NodeStage(
type_=AddLineageRequest,
context="lineage",

View File

@ -27,6 +27,7 @@ from metadata.generated.schema.api.data.createChart import CreateChartRequest
from metadata.generated.schema.api.data.createDashboard import CreateDashboardRequest
from metadata.generated.schema.api.lineage.addLineage import AddLineageRequest
from metadata.generated.schema.entity.data.chart import Chart
from metadata.generated.schema.entity.data.dashboard import Dashboard
from metadata.generated.schema.entity.services.connections.dashboard.domoDashboardConnection import (
DomoDashboardConnection,
)
@ -101,8 +102,8 @@ class DomodashboardSource(DashboardServiceSource):
if owner_details.get("email"):
user = self.metadata.get_user_by_email(owner_details["email"])
if user:
return EntityReference(id=user["id"], type="user")
logger.debug(
return EntityReference(id=user.id.__root__, type="user")
logger.warning(
f"No user for found for email {owner_details['email']} in OMD"
)
except Exception as exc:
@ -111,6 +112,18 @@ class DomodashboardSource(DashboardServiceSource):
)
return None
def process_owner(
self, dashboard_details: DomoDashboardDetails
) -> Optional[Dashboard]:
owner = self.get_owner_details(owners=dashboard_details.owners)
if owner and self.source_config.overrideOwner:
self.metadata.patch_owner(
entity=Dashboard,
entity_id=self.context.dashboard.id,
owner=owner,
force=True,
)
def yield_dashboard(
self, dashboard_details: DomoDashboardDetails
) -> Iterable[CreateDashboardRequest]:
@ -134,7 +147,6 @@ class DomodashboardSource(DashboardServiceSource):
for chart in self.context.charts
],
service=self.context.dashboard_service.fullyQualifiedName.__root__,
owner=self.get_owner_details(dashboard_details.owners),
)
except KeyError as err:
logger.warning(

View File

@ -159,7 +159,6 @@ class LookerSource(DashboardServiceSource):
Returns:
Optional[EntityReference]
"""
try:
if (
dashboard_details.user_id is not None
@ -183,6 +182,18 @@ class LookerSource(DashboardServiceSource):
return self._owners_ref.get(dashboard_details.user_id)
def process_owner(
self, dashboard_details: LookerDashboard
) -> Optional[MetadataDashboard]:
owner = self.get_owner_details(dashboard_details=dashboard_details)
if owner and self.source_config.overrideOwner:
self.metadata.patch_owner(
entity=MetadataDashboard,
entity_id=self.context.dashboard.id,
owner=owner,
force=True,
)
def yield_dashboard(
self, dashboard_details: LookerDashboard
) -> CreateDashboardRequest:
@ -205,7 +216,6 @@ class LookerSource(DashboardServiceSource):
],
dashboardUrl=f"/dashboards/{dashboard_details.id}",
service=self.context.dashboard_service.fullyQualifiedName.__root__,
owner=self.get_owner_details(dashboard_details),
)
@staticmethod

View File

@ -71,7 +71,6 @@ class SupersetAPISource(SupersetSourceMixin):
displayName=dashboard_details["dashboard_title"],
description="",
dashboardUrl=dashboard_details["url"],
owner=self.get_owner_details(dashboard_details),
charts=[
fqn.build(
self.metadata,

View File

@ -77,7 +77,6 @@ class SupersetDBSource(SupersetSourceMixin):
displayName=dashboard_details["dashboard_title"],
description="",
dashboardUrl=f"/superset/dashboard/{dashboard_details['id']}/",
owner=self.get_owner_details(dashboard_details),
charts=[
fqn.build(
self.metadata,

View File

@ -88,6 +88,16 @@ class SupersetSourceMixin(DashboardServiceSource):
return None
def process_owner(self, dashboard_details: dict) -> Optional[Lineage_Dashboard]:
owner = self.get_owner_details(dashboard_details=dashboard_details)
if owner and self.source_config.overrideOwner:
self.metadata.patch_owner(
self.metadata,
entity=Lineage_Dashboard,
entity_id=self.context.dashboard.id,
force=True,
)
def get_owner_details(self, dashboard_details: dict) -> EntityReference:
for owner in dashboard_details.get("owners", []):
user = self._get_user_by_email(owner["email"])

View File

@ -251,6 +251,18 @@ class TableauSource(DashboardServiceSource):
return EntityReference(id=user.id.__root__, type="user")
return None
def process_owner(
self, dashboard_details: TableauDashboard
) -> Optional[LineageDashboard]:
owner = self.get_owner_details(dashboard_details=dashboard_details)
if owner and self.source_config.overrideOwner:
self.metadata.patch_owner(
entity=LineageDashboard,
entity_id=self.context.dashboard.id,
owner=owner,
force=True,
)
def yield_tag(self, *_, **__) -> OMetaTagAndClassification:
"""
Fetch Dashboard Tags
@ -297,7 +309,6 @@ class TableauSource(DashboardServiceSource):
name=dashboard_details.id,
displayName=dashboard_details.name,
description=dashboard_details.description,
owner=self.get_owner_details(dashboard_details),
charts=[
fqn.build(
self.metadata,

View File

@ -147,7 +147,6 @@ EXPECTED_DASH = CreateDashboardRequest(
displayName="My DASH",
description="",
dashboardUrl="/superset/dashboard/14/",
owner=EXPECTED_USER,
charts=[chart.fullyQualifiedName for chart in EXPECTED_CHATRT_ENTITY],
service=EXPECTED_DASH_SERVICE.fullyQualifiedName,
)

View File

@ -67,6 +67,7 @@ source:
sourceConfig:
config:
type: DashboardMetadata
overrideOwner: True
# dbServiceNames:
# - service1
# - service2
@ -108,6 +109,7 @@ The `sourceConfig` is defined [here](https://github.com/open-metadata/OpenMetada
- `dbServiceNames`: Database Service Name for the creation of lineage, if the source supports it.
- `dashboardFilterPattern` and `chartFilterPattern`: Note that the `dashboardFilterPattern` and `chartFilterPattern` both support regex as include or exclude. E.g.,
- `overrideOwner`: Flag to override current owner by new owner from source, if found during metadata ingestion
```yaml
dashboardFilterPattern:

View File

@ -67,6 +67,7 @@ source:
sourceConfig:
config:
type: DashboardMetadata
overrideOwner: True
# dbServiceNames:
# - service1
# - service2
@ -109,6 +110,7 @@ The `sourceConfig` is defined [here](https://github.com/open-metadata/OpenMetada
- `dbServiceNames`: Database Service Name for the creation of lineage, if the source supports it.
- `dashboardFilterPattern` and `chartFilterPattern`: Note that the `dashboardFilterPattern` and `chartFilterPattern` both support regex as include or exclude. E.g.
- `overrideOwner`: Flag to override current owner by new owner from source, if found during metadata ingestion
```yaml
dashboardFilterPattern:

View File

@ -163,6 +163,8 @@ Please follow the instructions below
- **Include**: Explicitly include charts by adding a list of comma-separated regular expressions to the Include field. OpenMetadata will include all charts with names matching one or more of the supplied regular expressions. All other charts will be excluded.
- **Exclude**: Explicitly exclude charts by adding a list of comma-separated regular expressions to the Exclude field. OpenMetadata will exclude all charts with names matching one or more of the supplied regular expressions. All other charts will be included.
- **Database Service Name (Optional)**: Enter the name of Database Service which is already ingested in OpenMetadata to create lineage between dashboards and database tables.
- **Override Current Owner(toggle)**: Set the Override Current Owner toggle to override current owner with new owner, if that is fetched during metadata ingestion
For first time of metadata ingestion, kindly make sure to keep it enabled to get the owner.
- **Enable Debug Log (toggle)**: Set the Enable Debug Log toggle to set the default log level to debug, these logs can be viewed later in Airflow.
### 7. Schedule the Ingestion and Deploy

View File

@ -58,6 +58,7 @@ source:
sourceConfig:
config:
type: DashboardMetadata
overrideOwner: True
# dbServiceNames:
# - service1
# - service2
@ -98,6 +99,7 @@ The `sourceConfig` is defined [here](https://github.com/open-metadata/OpenMetada
- `dbServiceNames`: Database Service Name for the creation of lineage, if the source supports it.
- `dashboardFilterPattern` and `chartFilterPattern`: Note that the `dashboardFilterPattern` and `chartFilterPattern` both support regex as include or exclude. E.g.,
- `overrideOwner`: Flag to override current owner by new owner from source, if found during metadata ingestion
```yaml
dashboardFilterPattern:

View File

@ -58,6 +58,7 @@ source:
sourceConfig:
config:
type: DashboardMetadata
overrideOwner: True
# dbServiceNames:
# - service1
# - service2
@ -98,6 +99,7 @@ The `sourceConfig` is defined [here](https://github.com/open-metadata/OpenMetada
- `dbServiceNames`: Database Service Name for the creation of lineage, if the source supports it.
- `dashboardFilterPattern` and `chartFilterPattern`: Note that the `dashboardFilterPattern` and `chartFilterPattern` both support regex as include or exclude. E.g.,
- `overrideOwner`: Flag to override current owner by new owner from source, if found during metadata ingestion
```yaml
dashboardFilterPattern:

View File

@ -156,6 +156,8 @@ Please follow the instructions below
- **Exclude**: Explicitly exclude charts by adding a list of comma-separated regular expressions to the Exclude field. OpenMetadata will exclude all charts with names matching one or more of the supplied regular expressions. All other charts will be included.
- **Database Service Name (Optional)**: Enter the name of Database Service which is already ingested in OpenMetadata to create lineage between dashboards and database tables.
- **Enable Debug Log (toggle)**: Set the Enable Debug Log toggle to set the default log level to debug, these logs can be viewed later in Airflow.
- **Override Current Owner(toggle)**: Set the Override Current Owner toggle to override current owner with new owner, if that is fetched during metadata ingestion
For first time of metadata ingestion, kindly make sure to keep it enabled to get the owner.
### 7. Schedule the Ingestion and Deploy

View File

@ -89,6 +89,7 @@ source:
sourceConfig:
config:
type: DashboardMetadata
overrideOwner: True
# dbServiceNames:
# - service1
# - service2
@ -159,6 +160,7 @@ The `sourceConfig` is defined [here](https://github.com/open-metadata/OpenMetada
- `dbServiceNames`: Database Service Name for the creation of lineage, if the source supports it.
- `dashboardFilterPattern` and `chartFilterPattern`: Note that the `dashboardFilterPattern` and `chartFilterPattern` both support regex as include or exclude. E.g.,
- `overrideOwner`: Flag to override current owner by new owner from source, if found during metadata ingestion
```yaml
dashboardFilterPattern:

View File

@ -89,6 +89,7 @@ source:
sourceConfig:
config:
type: DashboardMetadata
overrideOwner: True
# dbServiceNames:
# - service1
# - service2
@ -160,6 +161,7 @@ The `sourceConfig` is defined [here](https://github.com/open-metadata/OpenMetada
- `dbServiceNames`: Database Service Name for the creation of lineage, if the source supports it.
- `dashboardFilterPattern` and `chartFilterPattern`: Note that the `dashboardFilterPattern` and `chartFilterPattern` both support regex as include or exclude. E.g.,
- `overrideOwner`: Flag to override current owner by new owner from source, if found during metadata ingestion
```yaml
dashboardFilterPattern:

View File

@ -199,6 +199,8 @@ caption="Configure Metadata Ingestion Page"
- **Exclude**: Explicitly exclude charts by adding a list of comma-separated regular expressions to the Exclude field. OpenMetadata will exclude all charts with names matching one or more of the supplied regular expressions. All other charts will be included.
- **Database Service Name (Optional)**: Enter the name of Database Service which is already ingested in OpenMetadata to create lineage between dashboards and database tables.
- **Enable Debug Log (toggle)**: Set the Enable Debug Log toggle to set the default log level to debug, these logs can be viewed later in Airflow.
- **Override Current Owner(toggle)**: Set the Override Current Owner toggle to override current owner with new owner, if that is fetched during metadata ingestion
For first time of metadata ingestion, kindly make sure to keep it enabled to get the owner.
### 7. Schedule the Ingestion and Deploy

View File

@ -180,6 +180,7 @@ source:
sourceConfig:
config:
type: DashboardMetadata
overrideOwner: True
# dbServiceNames:
# - service1
# - service2
@ -226,6 +227,7 @@ The `sourceConfig` is defined [here](https://github.com/open-metadata/OpenMetada
- `dbServiceNames`: Database Service Name for the creation of lineage, if the source supports it.
- `dashboardFilterPattern` and `chartFilterPattern`: Note that the `dashboardFilterPattern` and `chartFilterPattern` both support regex as include or exclude. E.g.,
- `overrideOwner`: Flag to override current owner by new owner from source, if found during metadata ingestion
```yaml
dashboardFilterPattern:

View File

@ -180,6 +180,7 @@ source:
sourceConfig:
config:
type: DashboardMetadata
overrideOwner: True
# dbServiceNames:
# - service1
# - service2
@ -225,6 +226,7 @@ The `sourceConfig` is defined [here](https://github.com/open-metadata/OpenMetada
- `dbServiceNames`: Database Service Name for the creation of lineage, if the source supports it.
- `dashboardFilterPattern` and `chartFilterPattern`: Note that the `dashboardFilterPattern` and `chartFilterPattern` both support regex as include or exclude. E.g.,
- `overrideOwner`: Flag to override current owner by new owner from source, if found during metadata ingestion
```yaml
dashboardFilterPattern:

View File

@ -189,6 +189,8 @@ caption="Configure Metadata Ingestion Page"
- **Exclude**: Explicitly exclude charts by adding a list of comma-separated regular expressions to the Exclude field. OpenMetadata will exclude all charts with names matching one or more of the supplied regular expressions. All other charts will be included.
- **Database Service Name (Optional)**: Enter the name of Database Service which is already ingested in OpenMetadata to create lineage between dashboards and database tables.
- **Enable Debug Log (toggle)**: Set the Enable Debug Log toggle to set the default log level to debug, these logs can be viewed later in Airflow.
- **Override Current Owner(toggle)**: Set the Override Current Owner toggle to override current owner with new owner, if that is fetched during metadata ingestion
For first time of metadata ingestion, kindly make sure to keep it enabled to get the owner.
### 7. Schedule the Ingestion and Deploy

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 444 KiB

View File

@ -29,6 +29,12 @@
"title": "Database Service Name List",
"description": "List of Database Service Name for creation of lineage",
"type": "array"
},
"overrideOwner": {
"title": "Override Current Owner",
"description": "Enabling this flag will override current owner with new owner from the source,if that is fetched during metadata ingestion. Kindly make to keep it enabled, to get the owner, for first time metadata ingestion.",
"type": "boolean",
"default": "false"
}
},
"additionalProperties": false

View File

@ -171,6 +171,7 @@ const AddIngestion = ({
: undefined,
includeView: Boolean(sourceConfig?.includeViews),
includeTags: Boolean(sourceConfig?.includeTags),
overrideOwner: Boolean(sourceConfig?.overrideOwner),
includeLineage: Boolean(sourceConfig?.includeLineage ?? true),
enableDebugLog: data?.loggerLevel === LogLevels.Debug,
profileSample: sourceConfig?.profileSample,
@ -329,6 +330,7 @@ const AddIngestion = ({
tableFilterPattern,
topicFilterPattern,
useFqnFilter,
overrideOwner,
} = state;
switch (serviceCategory) {
@ -375,6 +377,7 @@ const AddIngestion = ({
showDashboardFilter
),
dbServiceNames: databaseServiceNames,
overrideOwner,
type: ConfigType.DashboardMetadata,
};
}

View File

@ -85,6 +85,7 @@ const ConfigureIngestion = ({
topicFilterPattern,
useFqnFilter,
processPii,
overrideOwner,
} = useMemo(
() => ({
chartFilterPattern: data.chartFilterPattern,
@ -122,6 +123,7 @@ const ConfigureIngestion = ({
topicFilterPattern: data.topicFilterPattern,
useFqnFilter: data.useFqnFilter,
processPii: data.processPii,
overrideOwner: data.overrideOwner,
}),
[data]
);
@ -166,6 +168,8 @@ const ConfigureIngestion = ({
const handleEnableDebugLogCheck = () => toggleField('enableDebugLog');
const handleOverrideOwner = () => toggleField('overrideOwner');
const handleIncludeLineage = () => toggleField('includeLineage');
const handleIncludeTags = () => toggleField('includeTags');
@ -232,6 +236,25 @@ const ConfigureIngestion = ({
);
};
const getOverrideOwnerToggle = () => {
return (
<Field>
<div className="tw-flex tw-gap-1">
<label>{t('label.override-current-owner')}</label>
<ToggleSwitchV1
checked={overrideOwner}
handleCheck={handleOverrideOwner}
testId="enabled-override-owner"
/>
</div>
<p className="tw-text-grey-muted tw-mt-3">
{t('message.enable-override-owner')}
</p>
{getSeparator('')}
</Field>
);
};
const getProfileSample = () => {
return (
<>
@ -582,6 +605,7 @@ const ConfigureIngestion = ({
{getSeparator('')}
{getDashboardDBServiceName()}
{getDebugLogToggle()}
{getOverrideOwnerToggle()}
</Fragment>
);

View File

@ -134,6 +134,7 @@ export interface AddIngestionState {
topicFilterPattern: FilterPattern;
useFqnFilter: boolean;
processPii: boolean;
overrideOwner: boolean;
}
export enum ShowFilter {

View File

@ -502,6 +502,7 @@
"option": "Option",
"or-lowercase": "or",
"org-url": "OrgUrl",
"override-current-owner": "Override Current Owner",
"owned-lowercase": "owned",
"owner": "Owner",
"owner-lowercase": "owner",
@ -915,6 +916,7 @@
"email-verification-token-expired": "Email Verification Token Expired",
"enable-column-profile": "Enable column profile",
"enable-debug-logging": "Enable debug logging",
"enable-override-owner": "Enabling this flag will override current owner with new owner ,if that is fetched during metadata ingestion. Kindly make to keep it enabled for first time metadata ingestion to get the owner.",
"enables-end-to-end-metadata-management": "Enables end-to-end metadata management with data discovery, data quality, observability, and people collaboration",
"endpoint-should-be-valid": "Endpoint should be valid URL.",
"ensure-airflow-set-up-correctly-before-heading-to-ingest-metadata": "Ensure that you have Airflow set up correctly before heading to ingest metadata.",