From c2470f1d9be52171994627639b790867b1e2143c Mon Sep 17 00:00:00 2001 From: Sam Black Date: Tue, 30 Jul 2024 13:49:14 -0400 Subject: [PATCH] feat(propagation): Add models for Action feature settings (#11029) --- .../datahub/graphql/GmsGraphQLEngine.java | 14 +- .../authorization/AuthorizationUtils.java | 5 + .../DocPropagationSettingsResolver.java | 57 +++ .../UpdateDocPropagationSettingsResolver.java | 77 +++++ .../src/main/resources/app.graphql | 30 ++ .../global/DocPropagationFeatureSettings.pdl | 8 + .../settings/global/FeatureSettings.pdl | 22 ++ .../settings/global/GlobalSettingsInfo.pdl | 8 + .../com.linkedin.entity.aspects.snapshot.json | 114 +++++- ...com.linkedin.entity.entities.snapshot.json | 114 +++++- .../com.linkedin.entity.runs.snapshot.json | 114 +++++- ...nkedin.operations.operations.snapshot.json | 114 +++++- ...m.linkedin.platform.platform.snapshot.json | 114 +++++- .../war/src/main/resources/boot/policies.json | 327 +++++++++--------- .../authorization/PoliciesConfig.java | 7 +- 15 files changed, 954 insertions(+), 171 deletions(-) create mode 100644 datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/settings/docPropagation/DocPropagationSettingsResolver.java create mode 100644 datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/settings/docPropagation/UpdateDocPropagationSettingsResolver.java create mode 100644 metadata-models/src/main/pegasus/com/linkedin/settings/global/DocPropagationFeatureSettings.pdl create mode 100644 metadata-models/src/main/pegasus/com/linkedin/settings/global/FeatureSettings.pdl diff --git a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java index d991493186351..af5d6bc81d614 100644 --- a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java +++ b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java @@ -285,6 +285,8 @@ import com.linkedin.datahub.graphql.resolvers.search.SearchAcrossEntitiesResolver; import com.linkedin.datahub.graphql.resolvers.search.SearchAcrossLineageResolver; import com.linkedin.datahub.graphql.resolvers.search.SearchResolver; +import com.linkedin.datahub.graphql.resolvers.settings.docPropagation.DocPropagationSettingsResolver; +import com.linkedin.datahub.graphql.resolvers.settings.docPropagation.UpdateDocPropagationSettingsResolver; import com.linkedin.datahub.graphql.resolvers.settings.user.UpdateCorpUserViewsSettingsResolver; import com.linkedin.datahub.graphql.resolvers.settings.view.GlobalViewsSettingsResolver; import com.linkedin.datahub.graphql.resolvers.settings.view.UpdateGlobalViewsSettingsResolver; @@ -1091,8 +1093,10 @@ private void configureQueryResolvers(final RuntimeWiring.Builder builder) { new BrowseV2Resolver(this.entityClient, this.viewService, this.formService)) .dataFetcher("businessAttribute", getResolver(businessAttributeType)) .dataFetcher( - "listBusinessAttributes", - new ListBusinessAttributesResolver(this.entityClient))); + "listBusinessAttributes", new ListBusinessAttributesResolver(this.entityClient)) + .dataFetcher( + "docPropagationSettings", + new DocPropagationSettingsResolver(this.settingsService))); } private DataFetcher getEntitiesResolver() { @@ -1344,7 +1348,11 @@ private void configureMutationResolvers(final RuntimeWiring.Builder builder) { .dataFetcher( "createForm", new CreateFormResolver(this.entityClient, this.formService)) .dataFetcher("deleteForm", new DeleteFormResolver(this.entityClient)) - .dataFetcher("updateForm", new UpdateFormResolver(this.entityClient)); + .dataFetcher("updateForm", new UpdateFormResolver(this.entityClient)) + .dataFetcher( + "updateDocPropagationSettings", + new UpdateDocPropagationSettingsResolver(this.settingsService)); + if (featureFlags.isBusinessAttributeEntityEnabled()) { typeWiring .dataFetcher( diff --git a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/authorization/AuthorizationUtils.java b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/authorization/AuthorizationUtils.java index b9b4e4f4ef292..4fb49d79a0aa7 100644 --- a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/authorization/AuthorizationUtils.java +++ b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/authorization/AuthorizationUtils.java @@ -398,6 +398,11 @@ public static boolean canManageForms(@Nonnull QueryContext context) { PoliciesConfig.MANAGE_DOCUMENTATION_FORMS_PRIVILEGE); } + public static boolean canManageFeatures(@Nonnull QueryContext context) { + return AuthUtil.isAuthorized( + context.getAuthorizer(), context.getActorUrn(), PoliciesConfig.MANAGE_FEATURES_PRIVILEGE); + } + public static boolean isAuthorized( @Nonnull Authorizer authorizer, @Nonnull String actor, diff --git a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/settings/docPropagation/DocPropagationSettingsResolver.java b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/settings/docPropagation/DocPropagationSettingsResolver.java new file mode 100644 index 0000000000000..84d3bcd7b376c --- /dev/null +++ b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/settings/docPropagation/DocPropagationSettingsResolver.java @@ -0,0 +1,57 @@ +package com.linkedin.datahub.graphql.resolvers.settings.docPropagation; + +import com.linkedin.datahub.graphql.QueryContext; +import com.linkedin.datahub.graphql.concurrency.GraphQLConcurrencyUtils; +import com.linkedin.datahub.graphql.generated.DocPropagationSettings; +import com.linkedin.metadata.service.SettingsService; +import com.linkedin.settings.global.GlobalSettingsInfo; +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; +import lombok.extern.slf4j.Slf4j; + +/** Retrieves the Global Settings related to the Actions feature. */ +@Slf4j +public class DocPropagationSettingsResolver + implements DataFetcher> { + + private final SettingsService _settingsService; + + public DocPropagationSettingsResolver(final SettingsService settingsService) { + _settingsService = Objects.requireNonNull(settingsService, "settingsService must not be null"); + } + + @Override + public CompletableFuture get(final DataFetchingEnvironment environment) + throws Exception { + final QueryContext context = environment.getContext(); + return GraphQLConcurrencyUtils.supplyAsync( + () -> { + try { + final GlobalSettingsInfo globalSettings = + _settingsService.getGlobalSettings(context.getOperationContext()); + final DocPropagationSettings defaultSettings = new DocPropagationSettings(); + defaultSettings.setDocColumnPropagation(true); + return globalSettings != null && globalSettings.hasDocPropagation() + ? mapDocPropagationSettings(globalSettings.getDocPropagation()) + : defaultSettings; + } catch (Exception e) { + throw new RuntimeException("Failed to retrieve Action Settings", e); + } + }, + this.getClass().getSimpleName(), + "get"); + } + + private static DocPropagationSettings mapDocPropagationSettings( + @Nonnull final com.linkedin.settings.global.DocPropagationFeatureSettings settings) { + final DocPropagationSettings result = new DocPropagationSettings(); + + // Map docColumnPropagation settings field + result.setDocColumnPropagation(settings.isColumnPropagationEnabled()); + + return result; + } +} diff --git a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/settings/docPropagation/UpdateDocPropagationSettingsResolver.java b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/settings/docPropagation/UpdateDocPropagationSettingsResolver.java new file mode 100644 index 0000000000000..198c36faad0bd --- /dev/null +++ b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/settings/docPropagation/UpdateDocPropagationSettingsResolver.java @@ -0,0 +1,77 @@ +package com.linkedin.datahub.graphql.resolvers.settings.docPropagation; + +import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.*; + +import com.linkedin.datahub.graphql.QueryContext; +import com.linkedin.datahub.graphql.authorization.AuthorizationUtils; +import com.linkedin.datahub.graphql.concurrency.GraphQLConcurrencyUtils; +import com.linkedin.datahub.graphql.exception.AuthorizationException; +import com.linkedin.datahub.graphql.generated.UpdateDocPropagationSettingsInput; +import com.linkedin.metadata.service.SettingsService; +import com.linkedin.settings.global.DocPropagationFeatureSettings; +import com.linkedin.settings.global.GlobalSettingsInfo; +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; + +/** Resolver responsible for updating the actions settings. */ +public class UpdateDocPropagationSettingsResolver + implements DataFetcher> { + + private final SettingsService _settingsService; + + public UpdateDocPropagationSettingsResolver(@Nonnull final SettingsService settingsService) { + _settingsService = Objects.requireNonNull(settingsService, "settingsService must not be null"); + } + + @Override + public CompletableFuture get(final DataFetchingEnvironment environment) + throws Exception { + final QueryContext context = environment.getContext(); + final UpdateDocPropagationSettingsInput input = + bindArgument(environment.getArgument("input"), UpdateDocPropagationSettingsInput.class); + + return GraphQLConcurrencyUtils.supplyAsync( + () -> { + if (AuthorizationUtils.canManageFeatures(context)) { + try { + // First, fetch the existing global settings. This does a R-M-F. + final GlobalSettingsInfo maybeGlobalSettings = + _settingsService.getGlobalSettings(context.getOperationContext()); + + final GlobalSettingsInfo newGlobalSettings = + maybeGlobalSettings != null ? maybeGlobalSettings : new GlobalSettingsInfo(); + + final DocPropagationFeatureSettings newDocPropagationSettings = + newGlobalSettings.hasDocPropagation() + ? newGlobalSettings.getDocPropagation() + : new DocPropagationFeatureSettings().setEnabled(true); + + // Next, patch the actions settings. + updateDocPropagationSettings(newDocPropagationSettings, input); + newGlobalSettings.setDocPropagation(newDocPropagationSettings); + + // Finally, write back to GMS. + _settingsService.updateGlobalSettings( + context.getOperationContext(), newGlobalSettings); + return true; + } catch (Exception e) { + throw new RuntimeException( + String.format("Failed to update action settings! %s", input), e); + } + } + throw new AuthorizationException( + "Unauthorized to perform this action. Please contact your DataHub administrator."); + }, + this.getClass().getSimpleName(), + "get"); + } + + private static void updateDocPropagationSettings( + @Nonnull final com.linkedin.settings.global.DocPropagationFeatureSettings settings, + @Nonnull final UpdateDocPropagationSettingsInput input) { + settings.setColumnPropagationEnabled(input.getDocColumnPropagation()); + } +} diff --git a/datahub-graphql-core/src/main/resources/app.graphql b/datahub-graphql-core/src/main/resources/app.graphql index be3418f146c0f..024a7a989f9db 100644 --- a/datahub-graphql-core/src/main/resources/app.graphql +++ b/datahub-graphql-core/src/main/resources/app.graphql @@ -17,6 +17,11 @@ extend type Query { Requires the 'Manage Global Views' Platform Privilege. """ globalViewsSettings: GlobalViewsSettings + + """ + Fetch the global settings related to the docs propagation feature. + """ + docPropagationSettings: DocPropagationSettings } extend type Mutation { @@ -25,6 +30,11 @@ extend type Mutation { Requires the 'Manage Global Views' Platform Privilege. """ updateGlobalViewsSettings(input: UpdateGlobalViewsSettingsInput!): Boolean! + + """ + Update the doc propagation settings. + """ + updateDocPropagationSettings(input: UpdateDocPropagationSettingsInput!): Boolean! } """ @@ -525,3 +535,23 @@ type GlobalViewsSettings { """ defaultView: String } + +""" +Input required to update doc propagation settings. +""" +input UpdateDocPropagationSettingsInput { + """ + The default doc propagation setting for the platform. + """ + docColumnPropagation: Boolean +} + +""" +Global (platform-level) settings related to the doc propagation feature +""" +type DocPropagationSettings { + """ + The default doc propagation setting for the platform. + """ + docColumnPropagation: Boolean +} \ No newline at end of file diff --git a/metadata-models/src/main/pegasus/com/linkedin/settings/global/DocPropagationFeatureSettings.pdl b/metadata-models/src/main/pegasus/com/linkedin/settings/global/DocPropagationFeatureSettings.pdl new file mode 100644 index 0000000000000..9838184734d86 --- /dev/null +++ b/metadata-models/src/main/pegasus/com/linkedin/settings/global/DocPropagationFeatureSettings.pdl @@ -0,0 +1,8 @@ +namespace com.linkedin.settings.global + + +record DocPropagationFeatureSettings includes FeatureSettings { + + columnPropagationEnabled: boolean = true + +} \ No newline at end of file diff --git a/metadata-models/src/main/pegasus/com/linkedin/settings/global/FeatureSettings.pdl b/metadata-models/src/main/pegasus/com/linkedin/settings/global/FeatureSettings.pdl new file mode 100644 index 0000000000000..dbc82c8e71a6b --- /dev/null +++ b/metadata-models/src/main/pegasus/com/linkedin/settings/global/FeatureSettings.pdl @@ -0,0 +1,22 @@ +namespace com.linkedin.settings.global + +/** + * A standardized settings template for a feature. + */ + +record FeatureSettings { + + enabled: boolean + + /** + * The configuration for the feature, in JSON format. + */ + config: optional string + + /** + * The version of the configuration schema that has been used to serialize + the config. + * If not provided, the version is assumed to be the latest version. + */ + configVersion: optional string +} \ No newline at end of file diff --git a/metadata-models/src/main/pegasus/com/linkedin/settings/global/GlobalSettingsInfo.pdl b/metadata-models/src/main/pegasus/com/linkedin/settings/global/GlobalSettingsInfo.pdl index 91dca1de0c452..8d4121b767dc3 100644 --- a/metadata-models/src/main/pegasus/com/linkedin/settings/global/GlobalSettingsInfo.pdl +++ b/metadata-models/src/main/pegasus/com/linkedin/settings/global/GlobalSettingsInfo.pdl @@ -16,4 +16,12 @@ record GlobalSettingsInfo { * Settings related to the Views Feature */ views: optional GlobalViewsSettings + /** + * Settings related to the documentation propagation feature + */ + docPropagation: DocPropagationFeatureSettings = { + "enabled": true + "columnPropagationEnabled": true + } + } \ No newline at end of file diff --git a/metadata-service/restli-api/src/main/snapshot/com.linkedin.entity.aspects.snapshot.json b/metadata-service/restli-api/src/main/snapshot/com.linkedin.entity.aspects.snapshot.json index eb92cf75a4d4e..c85e57a35eac7 100644 --- a/metadata-service/restli-api/src/main/snapshot/com.linkedin.entity.aspects.snapshot.json +++ b/metadata-service/restli-api/src/main/snapshot/com.linkedin.entity.aspects.snapshot.json @@ -902,6 +902,51 @@ "type" : "string", "doc" : "Additional context about the association", "optional" : true + }, { + "name" : "attribution", + "type" : { + "type" : "record", + "name" : "MetadataAttribution", + "doc" : "Information about who, why, and how this metadata was applied", + "fields" : [ { + "name" : "time", + "type" : "Time", + "doc" : "When this metadata was updated." + }, { + "name" : "actor", + "type" : "Urn", + "doc" : "The entity (e.g. a member URN) responsible for applying the assocated metadata. This can\neither be a user (in case of UI edits) or the datahub system for automation." + }, { + "name" : "source", + "type" : "Urn", + "doc" : "The DataHub source responsible for applying the associated metadata. This will only be filled out\nwhen a DataHub source is responsible. This includes the specific metadata test urn, the automation urn.", + "optional" : true + }, { + "name" : "sourceDetail", + "type" : { + "type" : "map", + "values" : "string" + }, + "doc" : "The details associated with why this metadata was applied. For example, this could include\nthe actual regex rule, sql statement, ingestion pipeline ID, etc.", + "default" : { } + } ] + }, + "doc" : "Information about who, why, and how this metadata was applied", + "optional" : true, + "Searchable" : { + "/actor" : { + "fieldName" : "tagAttributionActors", + "fieldType" : "URN" + }, + "/source" : { + "fieldName" : "tagAttributionSources", + "fieldType" : "URN" + }, + "/time" : { + "fieldName" : "tagAttributionDates", + "fieldType" : "DATETIME" + } + } } ] } }, @@ -1010,6 +1055,25 @@ "type" : "string", "doc" : "Additional context about the association", "optional" : true + }, { + "name" : "attribution", + "type" : "MetadataAttribution", + "doc" : "Information about who, why, and how this metadata was applied", + "optional" : true, + "Searchable" : { + "/actor" : { + "fieldName" : "termAttributionActors", + "fieldType" : "URN" + }, + "/source" : { + "fieldName" : "termAttributionSources", + "fieldType" : "URN" + }, + "/time" : { + "fieldName" : "termAttributionDates", + "fieldType" : "DATETIME" + } + } } ] }, "com.linkedin.common.GlossaryTermUrn", { "type" : "record", @@ -1121,7 +1185,7 @@ "owningTeam" : "urn:li:internalTeam:datahub" } } - }, { + }, "com.linkedin.common.MetadataAttribution", { "type" : "record", "name" : "Owner", "namespace" : "com.linkedin.common", @@ -3060,6 +3124,18 @@ } }, "Searchable" : { + "/tags/*/attribution/actor" : { + "fieldName" : "fieldTagAttributionActors", + "fieldType" : "URN" + }, + "/tags/*/attribution/source" : { + "fieldName" : "fieldTagAttributionSources", + "fieldType" : "URN" + }, + "/tags/*/attribution/time" : { + "fieldName" : "fieldTagAttributionDates", + "fieldType" : "DATETIME" + }, "/tags/*/tag" : { "boostScore" : 0.5, "fieldName" : "fieldTags", @@ -3078,6 +3154,18 @@ } }, "Searchable" : { + "/terms/*/attribution/actor" : { + "fieldName" : "fieldTermAttributionActors", + "fieldType" : "URN" + }, + "/terms/*/attribution/source" : { + "fieldName" : "fieldTermAttributionSources", + "fieldType" : "URN" + }, + "/terms/*/attribution/time" : { + "fieldName" : "fieldTermAttributionDates", + "fieldType" : "DATETIME" + }, "/terms/*/urn" : { "boostScore" : 0.5, "fieldName" : "fieldGlossaryTerms", @@ -3247,6 +3335,18 @@ } }, "Searchable" : { + "/tags/*/attribution/actor" : { + "fieldName" : "editedFieldTagAttributionActors", + "fieldType" : "URN" + }, + "/tags/*/attribution/source" : { + "fieldName" : "editedFieldTagAttributionSources", + "fieldType" : "URN" + }, + "/tags/*/attribution/time" : { + "fieldName" : "editedFieldTagAttributionDates", + "fieldType" : "DATETIME" + }, "/tags/*/tag" : { "boostScore" : 0.5, "fieldName" : "editedFieldTags", @@ -3265,6 +3365,18 @@ } }, "Searchable" : { + "/terms/*/attribution/actor" : { + "fieldName" : "editedFieldTermAttributionActors", + "fieldType" : "URN" + }, + "/terms/*/attribution/source" : { + "fieldName" : "editedFieldTermAttributionSources", + "fieldType" : "URN" + }, + "/terms/*/attribution/time" : { + "fieldName" : "editedFieldTermAttributionDates", + "fieldType" : "DATETIME" + }, "/terms/*/urn" : { "boostScore" : 0.5, "fieldName" : "editedFieldGlossaryTerms", diff --git a/metadata-service/restli-api/src/main/snapshot/com.linkedin.entity.entities.snapshot.json b/metadata-service/restli-api/src/main/snapshot/com.linkedin.entity.entities.snapshot.json index 0c983a021d4e7..305b3de156350 100644 --- a/metadata-service/restli-api/src/main/snapshot/com.linkedin.entity.entities.snapshot.json +++ b/metadata-service/restli-api/src/main/snapshot/com.linkedin.entity.entities.snapshot.json @@ -897,6 +897,51 @@ "type" : "string", "doc" : "Additional context about the association", "optional" : true + }, { + "name" : "attribution", + "type" : { + "type" : "record", + "name" : "MetadataAttribution", + "doc" : "Information about who, why, and how this metadata was applied", + "fields" : [ { + "name" : "time", + "type" : "Time", + "doc" : "When this metadata was updated." + }, { + "name" : "actor", + "type" : "Urn", + "doc" : "The entity (e.g. a member URN) responsible for applying the assocated metadata. This can\neither be a user (in case of UI edits) or the datahub system for automation." + }, { + "name" : "source", + "type" : "Urn", + "doc" : "The DataHub source responsible for applying the associated metadata. This will only be filled out\nwhen a DataHub source is responsible. This includes the specific metadata test urn, the automation urn.", + "optional" : true + }, { + "name" : "sourceDetail", + "type" : { + "type" : "map", + "values" : "string" + }, + "doc" : "The details associated with why this metadata was applied. For example, this could include\nthe actual regex rule, sql statement, ingestion pipeline ID, etc.", + "default" : { } + } ] + }, + "doc" : "Information about who, why, and how this metadata was applied", + "optional" : true, + "Searchable" : { + "/actor" : { + "fieldName" : "tagAttributionActors", + "fieldType" : "URN" + }, + "/source" : { + "fieldName" : "tagAttributionSources", + "fieldType" : "URN" + }, + "/time" : { + "fieldName" : "tagAttributionDates", + "fieldType" : "DATETIME" + } + } } ] } }, @@ -1005,6 +1050,25 @@ "type" : "string", "doc" : "Additional context about the association", "optional" : true + }, { + "name" : "attribution", + "type" : "MetadataAttribution", + "doc" : "Information about who, why, and how this metadata was applied", + "optional" : true, + "Searchable" : { + "/actor" : { + "fieldName" : "termAttributionActors", + "fieldType" : "URN" + }, + "/source" : { + "fieldName" : "termAttributionSources", + "fieldType" : "URN" + }, + "/time" : { + "fieldName" : "termAttributionDates", + "fieldType" : "DATETIME" + } + } } ] }, "com.linkedin.common.GlossaryTermUrn", { "type" : "record", @@ -1152,7 +1216,7 @@ "owningTeam" : "urn:li:internalTeam:datahub" } } - }, { + }, "com.linkedin.common.MetadataAttribution", { "type" : "record", "name" : "Owner", "namespace" : "com.linkedin.common", @@ -3443,6 +3507,18 @@ } }, "Searchable" : { + "/tags/*/attribution/actor" : { + "fieldName" : "fieldTagAttributionActors", + "fieldType" : "URN" + }, + "/tags/*/attribution/source" : { + "fieldName" : "fieldTagAttributionSources", + "fieldType" : "URN" + }, + "/tags/*/attribution/time" : { + "fieldName" : "fieldTagAttributionDates", + "fieldType" : "DATETIME" + }, "/tags/*/tag" : { "boostScore" : 0.5, "fieldName" : "fieldTags", @@ -3461,6 +3537,18 @@ } }, "Searchable" : { + "/terms/*/attribution/actor" : { + "fieldName" : "fieldTermAttributionActors", + "fieldType" : "URN" + }, + "/terms/*/attribution/source" : { + "fieldName" : "fieldTermAttributionSources", + "fieldType" : "URN" + }, + "/terms/*/attribution/time" : { + "fieldName" : "fieldTermAttributionDates", + "fieldType" : "DATETIME" + }, "/terms/*/urn" : { "boostScore" : 0.5, "fieldName" : "fieldGlossaryTerms", @@ -3630,6 +3718,18 @@ } }, "Searchable" : { + "/tags/*/attribution/actor" : { + "fieldName" : "editedFieldTagAttributionActors", + "fieldType" : "URN" + }, + "/tags/*/attribution/source" : { + "fieldName" : "editedFieldTagAttributionSources", + "fieldType" : "URN" + }, + "/tags/*/attribution/time" : { + "fieldName" : "editedFieldTagAttributionDates", + "fieldType" : "DATETIME" + }, "/tags/*/tag" : { "boostScore" : 0.5, "fieldName" : "editedFieldTags", @@ -3648,6 +3748,18 @@ } }, "Searchable" : { + "/terms/*/attribution/actor" : { + "fieldName" : "editedFieldTermAttributionActors", + "fieldType" : "URN" + }, + "/terms/*/attribution/source" : { + "fieldName" : "editedFieldTermAttributionSources", + "fieldType" : "URN" + }, + "/terms/*/attribution/time" : { + "fieldName" : "editedFieldTermAttributionDates", + "fieldType" : "DATETIME" + }, "/terms/*/urn" : { "boostScore" : 0.5, "fieldName" : "editedFieldGlossaryTerms", diff --git a/metadata-service/restli-api/src/main/snapshot/com.linkedin.entity.runs.snapshot.json b/metadata-service/restli-api/src/main/snapshot/com.linkedin.entity.runs.snapshot.json index 4af65cdb48b50..dc226adf635c4 100644 --- a/metadata-service/restli-api/src/main/snapshot/com.linkedin.entity.runs.snapshot.json +++ b/metadata-service/restli-api/src/main/snapshot/com.linkedin.entity.runs.snapshot.json @@ -639,6 +639,51 @@ "type" : "string", "doc" : "Additional context about the association", "optional" : true + }, { + "name" : "attribution", + "type" : { + "type" : "record", + "name" : "MetadataAttribution", + "doc" : "Information about who, why, and how this metadata was applied", + "fields" : [ { + "name" : "time", + "type" : "Time", + "doc" : "When this metadata was updated." + }, { + "name" : "actor", + "type" : "Urn", + "doc" : "The entity (e.g. a member URN) responsible for applying the assocated metadata. This can\neither be a user (in case of UI edits) or the datahub system for automation." + }, { + "name" : "source", + "type" : "Urn", + "doc" : "The DataHub source responsible for applying the associated metadata. This will only be filled out\nwhen a DataHub source is responsible. This includes the specific metadata test urn, the automation urn.", + "optional" : true + }, { + "name" : "sourceDetail", + "type" : { + "type" : "map", + "values" : "string" + }, + "doc" : "The details associated with why this metadata was applied. For example, this could include\nthe actual regex rule, sql statement, ingestion pipeline ID, etc.", + "default" : { } + } ] + }, + "doc" : "Information about who, why, and how this metadata was applied", + "optional" : true, + "Searchable" : { + "/actor" : { + "fieldName" : "tagAttributionActors", + "fieldType" : "URN" + }, + "/source" : { + "fieldName" : "tagAttributionSources", + "fieldType" : "URN" + }, + "/time" : { + "fieldName" : "tagAttributionDates", + "fieldType" : "DATETIME" + } + } } ] } }, @@ -747,6 +792,25 @@ "type" : "string", "doc" : "Additional context about the association", "optional" : true + }, { + "name" : "attribution", + "type" : "MetadataAttribution", + "doc" : "Information about who, why, and how this metadata was applied", + "optional" : true, + "Searchable" : { + "/actor" : { + "fieldName" : "termAttributionActors", + "fieldType" : "URN" + }, + "/source" : { + "fieldName" : "termAttributionSources", + "fieldType" : "URN" + }, + "/time" : { + "fieldName" : "termAttributionDates", + "fieldType" : "DATETIME" + } + } } ] }, "com.linkedin.common.GlossaryTermUrn", { "type" : "record", @@ -858,7 +922,7 @@ "owningTeam" : "urn:li:internalTeam:datahub" } } - }, { + }, "com.linkedin.common.MetadataAttribution", { "type" : "record", "name" : "Owner", "namespace" : "com.linkedin.common", @@ -2788,6 +2852,18 @@ } }, "Searchable" : { + "/tags/*/attribution/actor" : { + "fieldName" : "fieldTagAttributionActors", + "fieldType" : "URN" + }, + "/tags/*/attribution/source" : { + "fieldName" : "fieldTagAttributionSources", + "fieldType" : "URN" + }, + "/tags/*/attribution/time" : { + "fieldName" : "fieldTagAttributionDates", + "fieldType" : "DATETIME" + }, "/tags/*/tag" : { "boostScore" : 0.5, "fieldName" : "fieldTags", @@ -2806,6 +2882,18 @@ } }, "Searchable" : { + "/terms/*/attribution/actor" : { + "fieldName" : "fieldTermAttributionActors", + "fieldType" : "URN" + }, + "/terms/*/attribution/source" : { + "fieldName" : "fieldTermAttributionSources", + "fieldType" : "URN" + }, + "/terms/*/attribution/time" : { + "fieldName" : "fieldTermAttributionDates", + "fieldType" : "DATETIME" + }, "/terms/*/urn" : { "boostScore" : 0.5, "fieldName" : "fieldGlossaryTerms", @@ -2975,6 +3063,18 @@ } }, "Searchable" : { + "/tags/*/attribution/actor" : { + "fieldName" : "editedFieldTagAttributionActors", + "fieldType" : "URN" + }, + "/tags/*/attribution/source" : { + "fieldName" : "editedFieldTagAttributionSources", + "fieldType" : "URN" + }, + "/tags/*/attribution/time" : { + "fieldName" : "editedFieldTagAttributionDates", + "fieldType" : "DATETIME" + }, "/tags/*/tag" : { "boostScore" : 0.5, "fieldName" : "editedFieldTags", @@ -2993,6 +3093,18 @@ } }, "Searchable" : { + "/terms/*/attribution/actor" : { + "fieldName" : "editedFieldTermAttributionActors", + "fieldType" : "URN" + }, + "/terms/*/attribution/source" : { + "fieldName" : "editedFieldTermAttributionSources", + "fieldType" : "URN" + }, + "/terms/*/attribution/time" : { + "fieldName" : "editedFieldTermAttributionDates", + "fieldType" : "DATETIME" + }, "/terms/*/urn" : { "boostScore" : 0.5, "fieldName" : "editedFieldGlossaryTerms", diff --git a/metadata-service/restli-api/src/main/snapshot/com.linkedin.operations.operations.snapshot.json b/metadata-service/restli-api/src/main/snapshot/com.linkedin.operations.operations.snapshot.json index e788c5d28ce71..7bc02ce2017fd 100644 --- a/metadata-service/restli-api/src/main/snapshot/com.linkedin.operations.operations.snapshot.json +++ b/metadata-service/restli-api/src/main/snapshot/com.linkedin.operations.operations.snapshot.json @@ -639,6 +639,51 @@ "type" : "string", "doc" : "Additional context about the association", "optional" : true + }, { + "name" : "attribution", + "type" : { + "type" : "record", + "name" : "MetadataAttribution", + "doc" : "Information about who, why, and how this metadata was applied", + "fields" : [ { + "name" : "time", + "type" : "Time", + "doc" : "When this metadata was updated." + }, { + "name" : "actor", + "type" : "Urn", + "doc" : "The entity (e.g. a member URN) responsible for applying the assocated metadata. This can\neither be a user (in case of UI edits) or the datahub system for automation." + }, { + "name" : "source", + "type" : "Urn", + "doc" : "The DataHub source responsible for applying the associated metadata. This will only be filled out\nwhen a DataHub source is responsible. This includes the specific metadata test urn, the automation urn.", + "optional" : true + }, { + "name" : "sourceDetail", + "type" : { + "type" : "map", + "values" : "string" + }, + "doc" : "The details associated with why this metadata was applied. For example, this could include\nthe actual regex rule, sql statement, ingestion pipeline ID, etc.", + "default" : { } + } ] + }, + "doc" : "Information about who, why, and how this metadata was applied", + "optional" : true, + "Searchable" : { + "/actor" : { + "fieldName" : "tagAttributionActors", + "fieldType" : "URN" + }, + "/source" : { + "fieldName" : "tagAttributionSources", + "fieldType" : "URN" + }, + "/time" : { + "fieldName" : "tagAttributionDates", + "fieldType" : "DATETIME" + } + } } ] } }, @@ -747,6 +792,25 @@ "type" : "string", "doc" : "Additional context about the association", "optional" : true + }, { + "name" : "attribution", + "type" : "MetadataAttribution", + "doc" : "Information about who, why, and how this metadata was applied", + "optional" : true, + "Searchable" : { + "/actor" : { + "fieldName" : "termAttributionActors", + "fieldType" : "URN" + }, + "/source" : { + "fieldName" : "termAttributionSources", + "fieldType" : "URN" + }, + "/time" : { + "fieldName" : "termAttributionDates", + "fieldType" : "DATETIME" + } + } } ] }, "com.linkedin.common.GlossaryTermUrn", { "type" : "record", @@ -858,7 +922,7 @@ "owningTeam" : "urn:li:internalTeam:datahub" } } - }, { + }, "com.linkedin.common.MetadataAttribution", { "type" : "record", "name" : "Owner", "namespace" : "com.linkedin.common", @@ -2782,6 +2846,18 @@ } }, "Searchable" : { + "/tags/*/attribution/actor" : { + "fieldName" : "fieldTagAttributionActors", + "fieldType" : "URN" + }, + "/tags/*/attribution/source" : { + "fieldName" : "fieldTagAttributionSources", + "fieldType" : "URN" + }, + "/tags/*/attribution/time" : { + "fieldName" : "fieldTagAttributionDates", + "fieldType" : "DATETIME" + }, "/tags/*/tag" : { "boostScore" : 0.5, "fieldName" : "fieldTags", @@ -2800,6 +2876,18 @@ } }, "Searchable" : { + "/terms/*/attribution/actor" : { + "fieldName" : "fieldTermAttributionActors", + "fieldType" : "URN" + }, + "/terms/*/attribution/source" : { + "fieldName" : "fieldTermAttributionSources", + "fieldType" : "URN" + }, + "/terms/*/attribution/time" : { + "fieldName" : "fieldTermAttributionDates", + "fieldType" : "DATETIME" + }, "/terms/*/urn" : { "boostScore" : 0.5, "fieldName" : "fieldGlossaryTerms", @@ -2969,6 +3057,18 @@ } }, "Searchable" : { + "/tags/*/attribution/actor" : { + "fieldName" : "editedFieldTagAttributionActors", + "fieldType" : "URN" + }, + "/tags/*/attribution/source" : { + "fieldName" : "editedFieldTagAttributionSources", + "fieldType" : "URN" + }, + "/tags/*/attribution/time" : { + "fieldName" : "editedFieldTagAttributionDates", + "fieldType" : "DATETIME" + }, "/tags/*/tag" : { "boostScore" : 0.5, "fieldName" : "editedFieldTags", @@ -2987,6 +3087,18 @@ } }, "Searchable" : { + "/terms/*/attribution/actor" : { + "fieldName" : "editedFieldTermAttributionActors", + "fieldType" : "URN" + }, + "/terms/*/attribution/source" : { + "fieldName" : "editedFieldTermAttributionSources", + "fieldType" : "URN" + }, + "/terms/*/attribution/time" : { + "fieldName" : "editedFieldTermAttributionDates", + "fieldType" : "DATETIME" + }, "/terms/*/urn" : { "boostScore" : 0.5, "fieldName" : "editedFieldGlossaryTerms", diff --git a/metadata-service/restli-api/src/main/snapshot/com.linkedin.platform.platform.snapshot.json b/metadata-service/restli-api/src/main/snapshot/com.linkedin.platform.platform.snapshot.json index dbdba0040d443..cf43490cbdd6d 100644 --- a/metadata-service/restli-api/src/main/snapshot/com.linkedin.platform.platform.snapshot.json +++ b/metadata-service/restli-api/src/main/snapshot/com.linkedin.platform.platform.snapshot.json @@ -897,6 +897,51 @@ "type" : "string", "doc" : "Additional context about the association", "optional" : true + }, { + "name" : "attribution", + "type" : { + "type" : "record", + "name" : "MetadataAttribution", + "doc" : "Information about who, why, and how this metadata was applied", + "fields" : [ { + "name" : "time", + "type" : "Time", + "doc" : "When this metadata was updated." + }, { + "name" : "actor", + "type" : "Urn", + "doc" : "The entity (e.g. a member URN) responsible for applying the assocated metadata. This can\neither be a user (in case of UI edits) or the datahub system for automation." + }, { + "name" : "source", + "type" : "Urn", + "doc" : "The DataHub source responsible for applying the associated metadata. This will only be filled out\nwhen a DataHub source is responsible. This includes the specific metadata test urn, the automation urn.", + "optional" : true + }, { + "name" : "sourceDetail", + "type" : { + "type" : "map", + "values" : "string" + }, + "doc" : "The details associated with why this metadata was applied. For example, this could include\nthe actual regex rule, sql statement, ingestion pipeline ID, etc.", + "default" : { } + } ] + }, + "doc" : "Information about who, why, and how this metadata was applied", + "optional" : true, + "Searchable" : { + "/actor" : { + "fieldName" : "tagAttributionActors", + "fieldType" : "URN" + }, + "/source" : { + "fieldName" : "tagAttributionSources", + "fieldType" : "URN" + }, + "/time" : { + "fieldName" : "tagAttributionDates", + "fieldType" : "DATETIME" + } + } } ] } }, @@ -1005,6 +1050,25 @@ "type" : "string", "doc" : "Additional context about the association", "optional" : true + }, { + "name" : "attribution", + "type" : "MetadataAttribution", + "doc" : "Information about who, why, and how this metadata was applied", + "optional" : true, + "Searchable" : { + "/actor" : { + "fieldName" : "termAttributionActors", + "fieldType" : "URN" + }, + "/source" : { + "fieldName" : "termAttributionSources", + "fieldType" : "URN" + }, + "/time" : { + "fieldName" : "termAttributionDates", + "fieldType" : "DATETIME" + } + } } ] }, "com.linkedin.common.GlossaryTermUrn", { "type" : "record", @@ -1152,7 +1216,7 @@ "owningTeam" : "urn:li:internalTeam:datahub" } } - }, { + }, "com.linkedin.common.MetadataAttribution", { "type" : "record", "name" : "Owner", "namespace" : "com.linkedin.common", @@ -3437,6 +3501,18 @@ } }, "Searchable" : { + "/tags/*/attribution/actor" : { + "fieldName" : "fieldTagAttributionActors", + "fieldType" : "URN" + }, + "/tags/*/attribution/source" : { + "fieldName" : "fieldTagAttributionSources", + "fieldType" : "URN" + }, + "/tags/*/attribution/time" : { + "fieldName" : "fieldTagAttributionDates", + "fieldType" : "DATETIME" + }, "/tags/*/tag" : { "boostScore" : 0.5, "fieldName" : "fieldTags", @@ -3455,6 +3531,18 @@ } }, "Searchable" : { + "/terms/*/attribution/actor" : { + "fieldName" : "fieldTermAttributionActors", + "fieldType" : "URN" + }, + "/terms/*/attribution/source" : { + "fieldName" : "fieldTermAttributionSources", + "fieldType" : "URN" + }, + "/terms/*/attribution/time" : { + "fieldName" : "fieldTermAttributionDates", + "fieldType" : "DATETIME" + }, "/terms/*/urn" : { "boostScore" : 0.5, "fieldName" : "fieldGlossaryTerms", @@ -3624,6 +3712,18 @@ } }, "Searchable" : { + "/tags/*/attribution/actor" : { + "fieldName" : "editedFieldTagAttributionActors", + "fieldType" : "URN" + }, + "/tags/*/attribution/source" : { + "fieldName" : "editedFieldTagAttributionSources", + "fieldType" : "URN" + }, + "/tags/*/attribution/time" : { + "fieldName" : "editedFieldTagAttributionDates", + "fieldType" : "DATETIME" + }, "/tags/*/tag" : { "boostScore" : 0.5, "fieldName" : "editedFieldTags", @@ -3642,6 +3742,18 @@ } }, "Searchable" : { + "/terms/*/attribution/actor" : { + "fieldName" : "editedFieldTermAttributionActors", + "fieldType" : "URN" + }, + "/terms/*/attribution/source" : { + "fieldName" : "editedFieldTermAttributionSources", + "fieldType" : "URN" + }, + "/terms/*/attribution/time" : { + "fieldName" : "editedFieldTermAttributionDates", + "fieldType" : "DATETIME" + }, "/terms/*/urn" : { "boostScore" : 0.5, "fieldName" : "editedFieldGlossaryTerms", diff --git a/metadata-service/war/src/main/resources/boot/policies.json b/metadata-service/war/src/main/resources/boot/policies.json index 53c773d130f32..b684fd88e61c2 100644 --- a/metadata-service/war/src/main/resources/boot/policies.json +++ b/metadata-service/war/src/main/resources/boot/policies.json @@ -2,15 +2,15 @@ { "urn": "urn:li:dataHubPolicy:0", "info": { - "actors":{ - "resourceOwners":false, - "allUsers":false, - "allGroups":false, - "users":[ + "actors": { + "resourceOwners": false, + "allUsers": false, + "allGroups": false, + "users": [ "urn:li:corpuser:datahub" ] }, - "privileges":[ + "privileges": [ "MANAGE_POLICIES", "MANAGE_INGESTION", "MANAGE_SECRETS", @@ -36,27 +36,28 @@ "CREATE_BUSINESS_ATTRIBUTE", "MANAGE_BUSINESS_ATTRIBUTE", "MANAGE_STRUCTURED_PROPERTIES", - "MANAGE_DOCUMENTATION_FORMS" + "MANAGE_DOCUMENTATION_FORMS", + "MANAGE_FEATURES" ], - "displayName":"Root User - All Platform Privileges", - "description":"Grants all platform privileges to root user.", - "state":"ACTIVE", - "type":"PLATFORM", - "editable":false + "displayName": "Root User - All Platform Privileges", + "description": "Grants all platform privileges to root user.", + "state": "ACTIVE", + "type": "PLATFORM", + "editable": false } }, { "urn": "urn:li:dataHubPolicy:1", "info": { - "actors":{ - "resourceOwners":false, - "allUsers":false, - "allGroups":false, - "users":[ + "actors": { + "resourceOwners": false, + "allUsers": false, + "allGroups": false, + "users": [ "urn:li:corpuser:datahub" ] }, - "privileges":[ + "privileges": [ "EDIT_ENTITY", "VIEW_ENTITY_PAGE", "EDIT_LINEAGE", @@ -72,43 +73,43 @@ "DELETE_ENTITY", "ES_EXPLAIN_QUERY_PRIVILEGE" ], - "displayName":"Root User - Edit and View All Resources", - "description":"Grants all edit and view privileges for all resources to root user.", - "state":"ACTIVE", - "type":"METADATA", - "editable":false + "displayName": "Root User - Edit and View All Resources", + "description": "Grants all edit and view privileges for all resources to root user.", + "state": "ACTIVE", + "type": "METADATA", + "editable": false } }, { "urn": "urn:li:dataHubPolicy:7", "info": { - "actors":{ - "resourceOwners":false, - "allUsers":true, - "allGroups":false, - "users":[] + "actors": { + "resourceOwners": false, + "allUsers": true, + "allGroups": false, + "users": [] }, - "privileges":[ + "privileges": [ "VIEW_ANALYTICS", "GENERATE_PERSONAL_ACCESS_TOKENS" ], - "displayName":"All Users - Base Platform Privileges", - "description":"Grants base platform privileges to ALL users of DataHub. Change this policy to alter that behavior.", - "state":"ACTIVE", - "type":"PLATFORM", - "editable":true + "displayName": "All Users - Base Platform Privileges", + "description": "Grants base platform privileges to ALL users of DataHub. Change this policy to alter that behavior.", + "state": "ACTIVE", + "type": "PLATFORM", + "editable": true } }, { "urn": "urn:li:dataHubPolicy:view-entity-page-all", "info": { - "actors":{ - "resourceOwners":false, - "allUsers":true, - "allGroups":false, - "users":[] + "actors": { + "resourceOwners": false, + "allUsers": true, + "allGroups": false, + "users": [] }, - "privileges":[ + "privileges": [ "VIEW_ENTITY_PAGE", "SEARCH_PRIVILEGE", "GET_COUNTS_PRIVILEGE", @@ -117,47 +118,47 @@ "GET_TIMELINE_PRIVILEGE", "ES_EXPLAIN_QUERY_PRIVILEGE" ], - "displayName":"All Users - View Entity Page", - "description":"Grants entity view to all users", - "state":"ACTIVE", - "type":"METADATA", - "editable":true + "displayName": "All Users - View Entity Page", + "description": "Grants entity view to all users", + "state": "ACTIVE", + "type": "METADATA", + "editable": true } }, { "urn": "urn:li:dataHubPolicy:view-dataset-sensitive", "info": { - "actors":{ - "resourceOwners":false, - "allUsers":true, - "allGroups":false, - "users":[] + "actors": { + "resourceOwners": false, + "allUsers": true, + "allGroups": false, + "users": [] }, - "privileges":[ + "privileges": [ "VIEW_DATASET_USAGE", "VIEW_DATASET_PROFILE" ], - "displayName":"All Users - View Dataset Sensitive Information", - "description":"Grants viewing privileges of usage and profile information of all datasets for all users", - "state":"ACTIVE", - "type":"METADATA", - "editable":true + "displayName": "All Users - View Dataset Sensitive Information", + "description": "Grants viewing privileges of usage and profile information of all datasets for all users", + "state": "ACTIVE", + "type": "METADATA", + "editable": true } }, { "urn": "urn:li:dataHubPolicy:admin-platform-policy", "info": { - "actors":{ - "resourceOwners":false, - "allUsers":false, - "allGroups":false, - "users":[], - "groups":[], - "roles":[ + "actors": { + "resourceOwners": false, + "allUsers": false, + "allGroups": false, + "users": [], + "groups": [], + "roles": [ "urn:li:dataHubRole:Admin" ] }, - "privileges":[ + "privileges": [ "MANAGE_POLICIES", "MANAGE_INGESTION", "MANAGE_SECRETS", @@ -183,29 +184,30 @@ "CREATE_BUSINESS_ATTRIBUTE", "MANAGE_BUSINESS_ATTRIBUTE", "MANAGE_STRUCTURED_PROPERTIES", - "MANAGE_DOCUMENTATION_FORMS" + "MANAGE_DOCUMENTATION_FORMS", + "MANAGE_FEATURES" ], - "displayName":"Admins - Platform Policy", - "description":"Admins have all platform privileges.", - "state":"ACTIVE", - "type":"PLATFORM", - "editable":false + "displayName": "Admins - Platform Policy", + "description": "Admins have all platform privileges.", + "state": "ACTIVE", + "type": "PLATFORM", + "editable": false } }, { "urn": "urn:li:dataHubPolicy:admin-metadata-policy", "info": { - "actors":{ - "resourceOwners":false, - "allUsers":false, - "allGroups":false, - "users":[], - "groups":[], - "roles":[ + "actors": { + "resourceOwners": false, + "allUsers": false, + "allGroups": false, + "users": [], + "groups": [], + "roles": [ "urn:li:dataHubRole:Admin" ] }, - "privileges":[ + "privileges": [ "VIEW_ENTITY_PAGE", "EDIT_ENTITY_TAGS", "EDIT_ENTITY_GLOSSARY_TERMS", @@ -243,27 +245,27 @@ "ES_EXPLAIN_QUERY_PRIVILEGE", "EDIT_ENTITY_PROPERTIES" ], - "displayName":"Admins - Metadata Policy", - "description":"Admins have all metadata privileges.", - "state":"ACTIVE", - "type":"METADATA", - "editable":false + "displayName": "Admins - Metadata Policy", + "description": "Admins have all metadata privileges.", + "state": "ACTIVE", + "type": "METADATA", + "editable": false } }, { "urn": "urn:li:dataHubPolicy:editor-platform-policy", "info": { - "actors":{ - "resourceOwners":false, - "allUsers":false, - "allGroups":false, - "users":[], - "groups":[], - "roles":[ + "actors": { + "resourceOwners": false, + "allUsers": false, + "allGroups": false, + "users": [], + "groups": [], + "roles": [ "urn:li:dataHubRole:Editor" ] }, - "privileges":[ + "privileges": [ "GENERATE_PERSONAL_ACCESS_TOKENS", "MANAGE_DOMAINS", "MANAGE_GLOBAL_ANNOUNCEMENTS", @@ -271,29 +273,30 @@ "MANAGE_TAGS", "MANAGE_BUSINESS_ATTRIBUTE", "MANAGE_STRUCTURED_PROPERTIES", - "MANAGE_DOCUMENTATION_FORMS" + "MANAGE_DOCUMENTATION_FORMS", + "MANAGE_FEATURES" ], - "displayName":"Editors - Platform Policy", - "description":"Editors can manage ingestion and view analytics.", - "state":"ACTIVE", - "type":"PLATFORM", - "editable":false + "displayName": "Editors - Platform Policy", + "description": "Editors can manage ingestion and view analytics.", + "state": "ACTIVE", + "type": "PLATFORM", + "editable": false } }, { "urn": "urn:li:dataHubPolicy:editor-metadata-policy", "info": { - "actors":{ - "resourceOwners":false, - "allUsers":false, - "allGroups":false, - "users":[], - "groups":[], - "roles":[ + "actors": { + "resourceOwners": false, + "allUsers": false, + "allGroups": false, + "users": [], + "groups": [], + "roles": [ "urn:li:dataHubRole:Editor" ] }, - "privileges":[ + "privileges": [ "VIEW_ENTITY_PAGE", "EDIT_ENTITY_TAGS", "EDIT_ENTITY_GLOSSARY_TERMS", @@ -324,23 +327,23 @@ "ES_EXPLAIN_QUERY_PRIVILEGE", "EDIT_ENTITY_PROPERTIES" ], - "displayName":"Editors - Metadata Policy", - "description":"Editors have all metadata privileges.", - "state":"ACTIVE", - "type":"METADATA", - "editable":false + "displayName": "Editors - Metadata Policy", + "description": "Editors have all metadata privileges.", + "state": "ACTIVE", + "type": "METADATA", + "editable": false } }, { "urn": "urn:li:dataHubPolicy:editor-metadata-policy-entities", "info": { - "actors":{ - "resourceOwners":false, - "allUsers":false, - "allGroups":false, - "users":[], - "groups":[], - "roles":[ + "actors": { + "resourceOwners": false, + "allUsers": false, + "allGroups": false, + "users": [], + "groups": [], + "roles": [ "urn:li:dataHubRole:Editor" ] }, @@ -369,51 +372,51 @@ ] } }, - "privileges":[ + "privileges": [ "EDIT_ENTITY" ], - "displayName":"Editors - Edit Metadata Entities", - "description":"Editors can edit primary metadata entities.", - "state":"ACTIVE", - "type":"METADATA", - "editable":true + "displayName": "Editors - Edit Metadata Entities", + "description": "Editors can edit primary metadata entities.", + "state": "ACTIVE", + "type": "METADATA", + "editable": true } }, { "urn": "urn:li:dataHubPolicy:reader-platform-policy", "info": { - "actors":{ - "resourceOwners":false, - "allUsers":false, - "allGroups":false, - "users":[], - "groups":[], - "roles":[ + "actors": { + "resourceOwners": false, + "allUsers": false, + "allGroups": false, + "users": [], + "groups": [], + "roles": [ "urn:li:dataHubRole:Reader" ] }, - "privileges":[], - "displayName":"Readers - Platform Policy", - "description":"Readers can view analytics.", - "state":"ACTIVE", - "type":"PLATFORM", - "editable":false + "privileges": [], + "displayName": "Readers - Platform Policy", + "description": "Readers can view analytics.", + "state": "ACTIVE", + "type": "PLATFORM", + "editable": false } }, { "urn": "urn:li:dataHubPolicy:reader-metadata-policy", "info": { - "actors":{ - "resourceOwners":false, - "allUsers":false, - "allGroups":false, - "users":[], - "groups":[], - "roles":[ + "actors": { + "resourceOwners": false, + "allUsers": false, + "allGroups": false, + "users": [], + "groups": [], + "roles": [ "urn:li:dataHubRole:Reader" ] }, - "privileges":[ + "privileges": [ "VIEW_ENTITY_PAGE", "VIEW_DATASET_USAGE", "VIEW_DATASET_PROFILE", @@ -424,24 +427,24 @@ "GET_TIMELINE_PRIVILEGE", "ES_EXPLAIN_QUERY_PRIVILEGE" ], - "displayName":"Readers - Metadata Policy", - "description":"Readers can view all assets.", - "state":"ACTIVE", - "type":"METADATA", - "editable":false + "displayName": "Readers - Metadata Policy", + "description": "Readers can view all assets.", + "state": "ACTIVE", + "type": "METADATA", + "editable": false } }, { "urn": "urn:li:dataHubPolicy:asset-owners-metadata-policy", "info": { - "actors":{ - "resourceOwners":true, - "allUsers":false, - "allGroups":false, - "users":[], - "groups":[] + "actors": { + "resourceOwners": true, + "allUsers": false, + "allGroups": false, + "users": [], + "groups": [] }, - "privileges":[ + "privileges": [ "VIEW_ENTITY_PAGE", "EDIT_ENTITY_TAGS", "EDIT_ENTITY_GLOSSARY_TERMS", @@ -475,11 +478,11 @@ "ES_EXPLAIN_QUERY_PRIVILEGE", "EDIT_ENTITY_PROPERTIES" ], - "displayName":"Asset Owners - Metadata Policy", - "description":"Asset Owners have all metadata privileges ONLY for assets they own.", - "state":"ACTIVE", - "type":"METADATA", - "editable":true + "displayName": "Asset Owners - Metadata Policy", + "description": "Asset Owners have all metadata privileges ONLY for assets they own.", + "state": "ACTIVE", + "type": "METADATA", + "editable": true } } -] +] \ No newline at end of file diff --git a/metadata-utils/src/main/java/com/linkedin/metadata/authorization/PoliciesConfig.java b/metadata-utils/src/main/java/com/linkedin/metadata/authorization/PoliciesConfig.java index c20b287a47141..a282c6be673d0 100644 --- a/metadata-utils/src/main/java/com/linkedin/metadata/authorization/PoliciesConfig.java +++ b/metadata-utils/src/main/java/com/linkedin/metadata/authorization/PoliciesConfig.java @@ -163,6 +163,10 @@ public class PoliciesConfig { "Manage Documentation Forms", "Manage forms assigned to assets to assist in documentation efforts."); + public static final Privilege MANAGE_FEATURES_PRIVILEGE = + Privilege.of( + "MANAGE_FEATURES", "Manage Features", "Umbrella privilege to manage all features."); + public static final List PLATFORM_PRIVILEGES = ImmutableList.of( MANAGE_POLICIES_PRIVILEGE, @@ -189,7 +193,8 @@ public class PoliciesConfig { MANAGE_BUSINESS_ATTRIBUTE_PRIVILEGE, MANAGE_CONNECTIONS_PRIVILEGE, MANAGE_STRUCTURED_PROPERTIES_PRIVILEGE, - MANAGE_DOCUMENTATION_FORMS_PRIVILEGE); + MANAGE_DOCUMENTATION_FORMS_PRIVILEGE, + MANAGE_FEATURES_PRIVILEGE); // Resource Privileges //