# coding=utf-8
# *** WARNING: this file was generated by the Pulumi Terraform Bridge (tfgen) Tool. ***
# *** Do not edit by hand unless you're certain you know what you are doing! ***

import copy
import warnings
import pulumi
import pulumi.runtime
from typing import Any, Mapping, Optional, Sequence, Union, overload
from . import _utilities
from . import outputs
from ._inputs import *

__all__ = ['GrantsArgs', 'Grants']

@pulumi.input_type
class GrantsArgs:
    def __init__(__self__, *,
                 grants: pulumi.Input[Sequence[pulumi.Input['GrantsGrantArgs']]],
                 catalog: Optional[pulumi.Input[str]] = None,
                 external_location: Optional[pulumi.Input[str]] = None,
                 foreign_connection: Optional[pulumi.Input[str]] = None,
                 function: Optional[pulumi.Input[str]] = None,
                 metastore: Optional[pulumi.Input[str]] = None,
                 model: Optional[pulumi.Input[str]] = None,
                 pipeline: Optional[pulumi.Input[str]] = None,
                 recipient: Optional[pulumi.Input[str]] = None,
                 schema: Optional[pulumi.Input[str]] = None,
                 share: Optional[pulumi.Input[str]] = None,
                 storage_credential: Optional[pulumi.Input[str]] = None,
                 table: Optional[pulumi.Input[str]] = None,
                 volume: Optional[pulumi.Input[str]] = None):
        """
        The set of arguments for constructing a Grants resource.
        """
        pulumi.set(__self__, "grants", grants)
        if catalog is not None:
            pulumi.set(__self__, "catalog", catalog)
        if external_location is not None:
            pulumi.set(__self__, "external_location", external_location)
        if foreign_connection is not None:
            pulumi.set(__self__, "foreign_connection", foreign_connection)
        if function is not None:
            pulumi.set(__self__, "function", function)
        if metastore is not None:
            pulumi.set(__self__, "metastore", metastore)
        if model is not None:
            pulumi.set(__self__, "model", model)
        if pipeline is not None:
            pulumi.set(__self__, "pipeline", pipeline)
        if recipient is not None:
            pulumi.set(__self__, "recipient", recipient)
        if schema is not None:
            pulumi.set(__self__, "schema", schema)
        if share is not None:
            pulumi.set(__self__, "share", share)
        if storage_credential is not None:
            pulumi.set(__self__, "storage_credential", storage_credential)
        if table is not None:
            pulumi.set(__self__, "table", table)
        if volume is not None:
            pulumi.set(__self__, "volume", volume)

    @property
    @pulumi.getter
    def grants(self) -> pulumi.Input[Sequence[pulumi.Input['GrantsGrantArgs']]]:
        return pulumi.get(self, "grants")

    @grants.setter
    def grants(self, value: pulumi.Input[Sequence[pulumi.Input['GrantsGrantArgs']]]):
        pulumi.set(self, "grants", value)

    @property
    @pulumi.getter
    def catalog(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "catalog")

    @catalog.setter
    def catalog(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "catalog", value)

    @property
    @pulumi.getter(name="externalLocation")
    def external_location(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "external_location")

    @external_location.setter
    def external_location(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "external_location", value)

    @property
    @pulumi.getter(name="foreignConnection")
    def foreign_connection(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "foreign_connection")

    @foreign_connection.setter
    def foreign_connection(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "foreign_connection", value)

    @property
    @pulumi.getter
    def function(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "function")

    @function.setter
    def function(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "function", value)

    @property
    @pulumi.getter
    def metastore(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "metastore")

    @metastore.setter
    def metastore(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "metastore", value)

    @property
    @pulumi.getter
    def model(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "model")

    @model.setter
    def model(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "model", value)

    @property
    @pulumi.getter
    def pipeline(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "pipeline")

    @pipeline.setter
    def pipeline(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "pipeline", value)

    @property
    @pulumi.getter
    def recipient(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "recipient")

    @recipient.setter
    def recipient(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "recipient", value)

    @property
    @pulumi.getter
    def schema(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "schema")

    @schema.setter
    def schema(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "schema", value)

    @property
    @pulumi.getter
    def share(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "share")

    @share.setter
    def share(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "share", value)

    @property
    @pulumi.getter(name="storageCredential")
    def storage_credential(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "storage_credential")

    @storage_credential.setter
    def storage_credential(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "storage_credential", value)

    @property
    @pulumi.getter
    def table(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "table")

    @table.setter
    def table(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "table", value)

    @property
    @pulumi.getter
    def volume(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "volume")

    @volume.setter
    def volume(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "volume", value)


@pulumi.input_type
class _GrantsState:
    def __init__(__self__, *,
                 catalog: Optional[pulumi.Input[str]] = None,
                 external_location: Optional[pulumi.Input[str]] = None,
                 foreign_connection: Optional[pulumi.Input[str]] = None,
                 function: Optional[pulumi.Input[str]] = None,
                 grants: Optional[pulumi.Input[Sequence[pulumi.Input['GrantsGrantArgs']]]] = None,
                 metastore: Optional[pulumi.Input[str]] = None,
                 model: Optional[pulumi.Input[str]] = None,
                 pipeline: Optional[pulumi.Input[str]] = None,
                 recipient: Optional[pulumi.Input[str]] = None,
                 schema: Optional[pulumi.Input[str]] = None,
                 share: Optional[pulumi.Input[str]] = None,
                 storage_credential: Optional[pulumi.Input[str]] = None,
                 table: Optional[pulumi.Input[str]] = None,
                 volume: Optional[pulumi.Input[str]] = None):
        """
        Input properties used for looking up and filtering Grants resources.
        """
        if catalog is not None:
            pulumi.set(__self__, "catalog", catalog)
        if external_location is not None:
            pulumi.set(__self__, "external_location", external_location)
        if foreign_connection is not None:
            pulumi.set(__self__, "foreign_connection", foreign_connection)
        if function is not None:
            pulumi.set(__self__, "function", function)
        if grants is not None:
            pulumi.set(__self__, "grants", grants)
        if metastore is not None:
            pulumi.set(__self__, "metastore", metastore)
        if model is not None:
            pulumi.set(__self__, "model", model)
        if pipeline is not None:
            pulumi.set(__self__, "pipeline", pipeline)
        if recipient is not None:
            pulumi.set(__self__, "recipient", recipient)
        if schema is not None:
            pulumi.set(__self__, "schema", schema)
        if share is not None:
            pulumi.set(__self__, "share", share)
        if storage_credential is not None:
            pulumi.set(__self__, "storage_credential", storage_credential)
        if table is not None:
            pulumi.set(__self__, "table", table)
        if volume is not None:
            pulumi.set(__self__, "volume", volume)

    @property
    @pulumi.getter
    def catalog(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "catalog")

    @catalog.setter
    def catalog(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "catalog", value)

    @property
    @pulumi.getter(name="externalLocation")
    def external_location(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "external_location")

    @external_location.setter
    def external_location(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "external_location", value)

    @property
    @pulumi.getter(name="foreignConnection")
    def foreign_connection(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "foreign_connection")

    @foreign_connection.setter
    def foreign_connection(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "foreign_connection", value)

    @property
    @pulumi.getter
    def function(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "function")

    @function.setter
    def function(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "function", value)

    @property
    @pulumi.getter
    def grants(self) -> Optional[pulumi.Input[Sequence[pulumi.Input['GrantsGrantArgs']]]]:
        return pulumi.get(self, "grants")

    @grants.setter
    def grants(self, value: Optional[pulumi.Input[Sequence[pulumi.Input['GrantsGrantArgs']]]]):
        pulumi.set(self, "grants", value)

    @property
    @pulumi.getter
    def metastore(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "metastore")

    @metastore.setter
    def metastore(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "metastore", value)

    @property
    @pulumi.getter
    def model(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "model")

    @model.setter
    def model(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "model", value)

    @property
    @pulumi.getter
    def pipeline(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "pipeline")

    @pipeline.setter
    def pipeline(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "pipeline", value)

    @property
    @pulumi.getter
    def recipient(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "recipient")

    @recipient.setter
    def recipient(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "recipient", value)

    @property
    @pulumi.getter
    def schema(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "schema")

    @schema.setter
    def schema(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "schema", value)

    @property
    @pulumi.getter
    def share(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "share")

    @share.setter
    def share(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "share", value)

    @property
    @pulumi.getter(name="storageCredential")
    def storage_credential(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "storage_credential")

    @storage_credential.setter
    def storage_credential(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "storage_credential", value)

    @property
    @pulumi.getter
    def table(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "table")

    @table.setter
    def table(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "table", value)

    @property
    @pulumi.getter
    def volume(self) -> Optional[pulumi.Input[str]]:
        return pulumi.get(self, "volume")

    @volume.setter
    def volume(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "volume", value)


class Grants(pulumi.CustomResource):
    @overload
    def __init__(__self__,
                 resource_name: str,
                 opts: Optional[pulumi.ResourceOptions] = None,
                 catalog: Optional[pulumi.Input[str]] = None,
                 external_location: Optional[pulumi.Input[str]] = None,
                 foreign_connection: Optional[pulumi.Input[str]] = None,
                 function: Optional[pulumi.Input[str]] = None,
                 grants: Optional[pulumi.Input[Sequence[pulumi.Input[Union['GrantsGrantArgs', 'GrantsGrantArgsDict']]]]] = None,
                 metastore: Optional[pulumi.Input[str]] = None,
                 model: Optional[pulumi.Input[str]] = None,
                 pipeline: Optional[pulumi.Input[str]] = None,
                 recipient: Optional[pulumi.Input[str]] = None,
                 schema: Optional[pulumi.Input[str]] = None,
                 share: Optional[pulumi.Input[str]] = None,
                 storage_credential: Optional[pulumi.Input[str]] = None,
                 table: Optional[pulumi.Input[str]] = None,
                 volume: Optional[pulumi.Input[str]] = None,
                 __props__=None):
        """
        > **Note**
          This article refers to the privileges and inheritance model in Privilege Model version 1.0. If you created your metastore during the public preview (before August 25, 2022), you can upgrade to Privilege Model version 1.0 following [Upgrade to privilege inheritance](https://docs.databricks.com/data-governance/unity-catalog/hive-metastore.html)

        > **Note**
          Unity Catalog APIs are accessible via **workspace-level APIs**. This design may change in the future. Account-level principal grants can be assigned with any valid workspace as the Unity Catalog is decoupled from specific workspaces. More information in [the official documentation](https://docs.databricks.com/data-governance/unity-catalog/index.html).

        Two different resources help you manage your Unity Catalog grants for a securable. Each of these resources serves a different use case:

        - databricks_grants: Authoritative. Sets the grants of a securable and replaces any existing grants defined inside or outside of Pulumi.
        - databricks_grant: Authoritative for a given principal. Updates the grants of a securable to a single principal. Other principals within the grants for the securables are preserved.

        In Unity Catalog all users initially have no access to data. Only Metastore Admins can create objects and can grant/revoke access on individual objects to users and groups. Every securable object in Unity Catalog has an owner. The owner can be any account-level user or group, called principals in general. The principal that creates an object becomes its owner. Owners receive `ALL_PRIVILEGES` on the securable object (e.g., `SELECT` and `MODIFY` on a table), as well as the permission to grant privileges to other principals.

        Securable objects are hierarchical and privileges are inherited downward. The highest level object that privileges are inherited from is the catalog. This means that granting a privilege on a catalog or schema automatically grants the privilege to all current and future objects within the catalog or schema. Privileges that are granted on a metastore are not inherited.

        Every `Grants` resource must have exactly one securable identifier and one or more `grant` blocks with the following arguments:

        - `principal` - User name, group name or service principal application ID.
        - `privileges` - One or more privileges that are specific to a securable type.

        For the latest list of privilege types that apply to each securable object in Unity Catalog, please refer to the [official documentation](https://docs.databricks.com/en/data-governance/unity-catalog/manage-privileges/privileges.html#privilege-types-by-securable-object-in-unity-catalog)

        Pulumi will handle any configuration drift on every `pulumi up` run, even when grants are changed outside of Pulumi state.

        Unlike the [SQL specification](https://docs.databricks.com/sql/language-manual/sql-ref-privileges.html#privilege-types), all privileges to be written with underscore instead of space, e.g. `CREATE_TABLE` and not `CREATE TABLE`. Below summarizes which privilege types apply to each securable object in the catalog:

        ## Metastore grants

        You can grant `CREATE_CATALOG`, `CREATE_CONNECTION`, `CREATE_EXTERNAL_LOCATION`, `CREATE_PROVIDER`, `CREATE_RECIPIENT`, `CREATE_SHARE`, `CREATE_STORAGE_CREDENTIAL`, `MANAGE_ALLOWLIST`, `SET_SHARE_PERMISSION`, `USE_MARKETPLACE_ASSETS`, `USE_CONNECTION`, `USE_PROVIDER`, `USE_RECIPIENT` and `USE_SHARE` privileges to Metastore assigned to the workspace.

        ```python
        import pulumi
        import pulumi_databricks as databricks

        sandbox = databricks.Grants("sandbox",
            metastore="metastore_id",
            grants=[
                {
                    "principal": "Data Engineers",
                    "privileges": [
                        "CREATE_CATALOG",
                        "CREATE_EXTERNAL_LOCATION",
                    ],
                },
                {
                    "principal": "Data Sharer",
                    "privileges": [
                        "CREATE_RECIPIENT",
                        "CREATE_SHARE",
                    ],
                },
            ])
        ```

        ## Catalog grants

        You can grant `ALL_PRIVILEGES`, `APPLY_TAG`, `CREATE_CONNECTION`, `CREATE_SCHEMA`, `USE_CATALOG` privileges to Catalog specified in the `catalog` attribute. You can also grant `CREATE_FUNCTION`, `CREATE_TABLE`, `CREATE_VOLUME`, `EXECUTE`, `MODIFY`, `REFRESH`, `SELECT`, `READ_VOLUME`, `WRITE_VOLUME` and `USE_SCHEMA` at the catalog level to apply them to the pertinent current and future securable objects within the catalog:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        sandbox = databricks.Catalog("sandbox",
            name="sandbox",
            comment="this catalog is managed by terraform",
            properties={
                "purpose": "testing",
            })
        sandbox_grants = databricks.Grants("sandbox",
            catalog=sandbox.name,
            grants=[
                {
                    "principal": "Data Scientists",
                    "privileges": [
                        "USE_CATALOG",
                        "USE_SCHEMA",
                        "CREATE_TABLE",
                        "SELECT",
                    ],
                },
                {
                    "principal": "Data Engineers",
                    "privileges": [
                        "USE_CATALOG",
                        "USE_SCHEMA",
                        "CREATE_SCHEMA",
                        "CREATE_TABLE",
                        "MODIFY",
                    ],
                },
                {
                    "principal": "Data Analyst",
                    "privileges": [
                        "USE_CATALOG",
                        "USE_SCHEMA",
                        "SELECT",
                    ],
                },
            ])
        ```

        ## Schema grants

        You can grant `ALL_PRIVILEGES`, `APPLY_TAG`, `CREATE_FUNCTION`, `CREATE_TABLE`, `CREATE_VOLUME` and `USE_SCHEMA` privileges to _`catalog.schema`_ specified in the `schema` attribute. You can also grant `EXECUTE`, `MODIFY`, `REFRESH`, `SELECT`, `READ_VOLUME`, `WRITE_VOLUME` at the schema level to apply them to the pertinent current and future securable objects within the schema:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        things = databricks.Schema("things",
            catalog_name=sandbox["id"],
            name="things",
            comment="this schema is managed by terraform",
            properties={
                "kind": "various",
            })
        things_grants = databricks.Grants("things",
            schema=things.id,
            grants=[{
                "principal": "Data Engineers",
                "privileges": [
                    "USE_SCHEMA",
                    "MODIFY",
                ],
            }])
        ```

        ## Table grants

        You can grant `ALL_PRIVILEGES`, `APPLY_TAG`, `SELECT` and `MODIFY` privileges to _`catalog.schema.table`_ specified in the `table` attribute.

        ```python
        import pulumi
        import pulumi_databricks as databricks

        customers = databricks.Grants("customers",
            table="main.reporting.customers",
            grants=[
                {
                    "principal": "Data Engineers",
                    "privileges": [
                        "MODIFY",
                        "SELECT",
                    ],
                },
                {
                    "principal": "Data Analysts",
                    "privileges": ["SELECT"],
                },
            ])
        ```

        You can also apply grants dynamically with get_tables data resource:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        things = databricks.get_tables(catalog_name="sandbox",
            schema_name="things")
        things_grants = []
        for range in [{"key": k, "value": v} for [k, v] in enumerate(things.ids)]:
            things_grants.append(databricks.Grants(f"things-{range['key']}",
                table=range["value"],
                grants=[{
                    "principal": "sensitive",
                    "privileges": [
                        "SELECT",
                        "MODIFY",
                    ],
                }]))
        ```

        ## View grants

        You can grant `ALL_PRIVILEGES`, `APPLY_TAG` and `SELECT` privileges to _`catalog.schema.view`_ specified in `table` attribute.

        ```python
        import pulumi
        import pulumi_databricks as databricks

        customer360 = databricks.Grants("customer360",
            table="main.reporting.customer360",
            grants=[{
                "principal": "Data Analysts",
                "privileges": ["SELECT"],
            }])
        ```

        You can also apply grants dynamically with get_views data resource:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        customers = databricks.get_views(catalog_name="main",
            schema_name="customers")
        customers_grants = []
        for range in [{"key": k, "value": v} for [k, v] in enumerate(customers.ids)]:
            customers_grants.append(databricks.Grants(f"customers-{range['key']}",
                table=range["value"],
                grants=[{
                    "principal": "sensitive",
                    "privileges": [
                        "SELECT",
                        "MODIFY",
                    ],
                }]))
        ```

        ## Volume grants

        You can grant `ALL_PRIVILEGES`, `READ_VOLUME` and `WRITE_VOLUME` privileges to _`catalog.schema.volume`_ specified in the `volume` attribute.

        ```python
        import pulumi
        import pulumi_databricks as databricks

        this = databricks.Volume("this",
            name="quickstart_volume",
            catalog_name=sandbox["name"],
            schema_name=things["name"],
            volume_type="EXTERNAL",
            storage_location=some["url"],
            comment="this volume is managed by terraform")
        volume = databricks.Grants("volume",
            volume=this.id,
            grants=[{
                "principal": "Data Engineers",
                "privileges": ["WRITE_VOLUME"],
            }])
        ```

        ## Registered model grants

        You can grant `ALL_PRIVILEGES`, `APPLY_TAG`, and `EXECUTE` privileges to _`catalog.schema.model`_ specified in the `model` attribute.

        ```python
        import pulumi
        import pulumi_databricks as databricks

        customers = databricks.Grants("customers",
            model="main.reporting.customer_model",
            grants=[
                {
                    "principal": "Data Engineers",
                    "privileges": [
                        "APPLY_TAG",
                        "EXECUTE",
                    ],
                },
                {
                    "principal": "Data Analysts",
                    "privileges": ["EXECUTE"],
                },
            ])
        ```

        ## Function grants

        You can grant `ALL_PRIVILEGES` and `EXECUTE` privileges to _`catalog.schema.function`_ specified in the `function` attribute.

        ```python
        import pulumi
        import pulumi_databricks as databricks

        udf = databricks.Grants("udf",
            function="main.reporting.udf",
            grants=[
                {
                    "principal": "Data Engineers",
                    "privileges": ["EXECUTE"],
                },
                {
                    "principal": "Data Analysts",
                    "privileges": ["EXECUTE"],
                },
            ])
        ```

        ## Storage credential grants

        You can grant `ALL_PRIVILEGES`, `CREATE_EXTERNAL_LOCATION`, `CREATE_EXTERNAL_TABLE`, `READ_FILES` and `WRITE_FILES` privileges to StorageCredential id specified in `storage_credential` attribute:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        external = databricks.StorageCredential("external",
            name=external_data_access["name"],
            aws_iam_role={
                "role_arn": external_data_access["arn"],
            },
            comment="Managed by TF")
        external_creds = databricks.Grants("external_creds",
            storage_credential=external.id,
            grants=[{
                "principal": "Data Engineers",
                "privileges": ["CREATE_EXTERNAL_TABLE"],
            }])
        ```

        ## External location grants

        You can grant `ALL_PRIVILEGES`, `CREATE_EXTERNAL_TABLE`, `CREATE_MANAGED_STORAGE`, `CREATE EXTERNAL VOLUME`, `READ_FILES` and `WRITE_FILES` privileges to ExternalLocation id specified in `external_location` attribute:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        some = databricks.ExternalLocation("some",
            name="external",
            url=f"s3://{external_aws_s3_bucket['id']}/some",
            credential_name=external["id"],
            comment="Managed by TF")
        some_grants = databricks.Grants("some",
            external_location=some.id,
            grants=[
                {
                    "principal": "Data Engineers",
                    "privileges": [
                        "CREATE_EXTERNAL_TABLE",
                        "READ_FILES",
                    ],
                },
                {
                    "principal": my_sp["applicationId"],
                    "privileges": [
                        "CREATE_EXTERNAL_TABLE",
                        "READ_FILES",
                    ],
                },
                {
                    "principal": my_group["displayName"],
                    "privileges": [
                        "CREATE_EXTERNAL_TABLE",
                        "READ_FILES",
                    ],
                },
                {
                    "principal": my_user["userName"],
                    "privileges": [
                        "CREATE_EXTERNAL_TABLE",
                        "READ_FILES",
                    ],
                },
            ])
        ```

        ## Connection grants

        You can grant `ALL_PRIVILEGES`, `USE_CONNECTION` and `CREATE_FOREIGN_CATALOG` to Connection specified in `foreign_connection` attribute:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        mysql = databricks.Connection("mysql",
            name="mysql_connection",
            connection_type="MYSQL",
            comment="this is a connection to mysql db",
            options={
                "host": "test.mysql.database.azure.com",
                "port": "3306",
                "user": "user",
                "password": "password",
            },
            properties={
                "purpose": "testing",
            })
        some = databricks.Grants("some",
            foreign_connection=mysql.name,
            grants=[{
                "principal": "Data Engineers",
                "privileges": [
                    "CREATE_FOREIGN_CATALOG",
                    "USE_CONNECTION",
                ],
            }])
        ```

        ## Delta Sharing share grants

        You can grant `SELECT` to Recipient on Share name specified in `share` attribute:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        some = databricks.Share("some", name="my_share")
        some_recipient = databricks.Recipient("some", name="my_recipient")
        some_grants = databricks.Grants("some",
            share=some.name,
            grants=[{
                "principal": some_recipient.name,
                "privileges": ["SELECT"],
            }])
        ```

        ## Other access control

        You can control Databricks General Permissions through Permissions resource.

        ## Import

        The resource can be imported using combination of securable type (`table`, `catalog`, `foreign_connection`, ...) and it's name:

        bash

        ```sh
        $ pulumi import databricks:index/grants:Grants this catalog/abc
        ```

        :param str resource_name: The name of the resource.
        :param pulumi.ResourceOptions opts: Options for the resource.
        """
        ...
    @overload
    def __init__(__self__,
                 resource_name: str,
                 args: GrantsArgs,
                 opts: Optional[pulumi.ResourceOptions] = None):
        """
        > **Note**
          This article refers to the privileges and inheritance model in Privilege Model version 1.0. If you created your metastore during the public preview (before August 25, 2022), you can upgrade to Privilege Model version 1.0 following [Upgrade to privilege inheritance](https://docs.databricks.com/data-governance/unity-catalog/hive-metastore.html)

        > **Note**
          Unity Catalog APIs are accessible via **workspace-level APIs**. This design may change in the future. Account-level principal grants can be assigned with any valid workspace as the Unity Catalog is decoupled from specific workspaces. More information in [the official documentation](https://docs.databricks.com/data-governance/unity-catalog/index.html).

        Two different resources help you manage your Unity Catalog grants for a securable. Each of these resources serves a different use case:

        - databricks_grants: Authoritative. Sets the grants of a securable and replaces any existing grants defined inside or outside of Pulumi.
        - databricks_grant: Authoritative for a given principal. Updates the grants of a securable to a single principal. Other principals within the grants for the securables are preserved.

        In Unity Catalog all users initially have no access to data. Only Metastore Admins can create objects and can grant/revoke access on individual objects to users and groups. Every securable object in Unity Catalog has an owner. The owner can be any account-level user or group, called principals in general. The principal that creates an object becomes its owner. Owners receive `ALL_PRIVILEGES` on the securable object (e.g., `SELECT` and `MODIFY` on a table), as well as the permission to grant privileges to other principals.

        Securable objects are hierarchical and privileges are inherited downward. The highest level object that privileges are inherited from is the catalog. This means that granting a privilege on a catalog or schema automatically grants the privilege to all current and future objects within the catalog or schema. Privileges that are granted on a metastore are not inherited.

        Every `Grants` resource must have exactly one securable identifier and one or more `grant` blocks with the following arguments:

        - `principal` - User name, group name or service principal application ID.
        - `privileges` - One or more privileges that are specific to a securable type.

        For the latest list of privilege types that apply to each securable object in Unity Catalog, please refer to the [official documentation](https://docs.databricks.com/en/data-governance/unity-catalog/manage-privileges/privileges.html#privilege-types-by-securable-object-in-unity-catalog)

        Pulumi will handle any configuration drift on every `pulumi up` run, even when grants are changed outside of Pulumi state.

        Unlike the [SQL specification](https://docs.databricks.com/sql/language-manual/sql-ref-privileges.html#privilege-types), all privileges to be written with underscore instead of space, e.g. `CREATE_TABLE` and not `CREATE TABLE`. Below summarizes which privilege types apply to each securable object in the catalog:

        ## Metastore grants

        You can grant `CREATE_CATALOG`, `CREATE_CONNECTION`, `CREATE_EXTERNAL_LOCATION`, `CREATE_PROVIDER`, `CREATE_RECIPIENT`, `CREATE_SHARE`, `CREATE_STORAGE_CREDENTIAL`, `MANAGE_ALLOWLIST`, `SET_SHARE_PERMISSION`, `USE_MARKETPLACE_ASSETS`, `USE_CONNECTION`, `USE_PROVIDER`, `USE_RECIPIENT` and `USE_SHARE` privileges to Metastore assigned to the workspace.

        ```python
        import pulumi
        import pulumi_databricks as databricks

        sandbox = databricks.Grants("sandbox",
            metastore="metastore_id",
            grants=[
                {
                    "principal": "Data Engineers",
                    "privileges": [
                        "CREATE_CATALOG",
                        "CREATE_EXTERNAL_LOCATION",
                    ],
                },
                {
                    "principal": "Data Sharer",
                    "privileges": [
                        "CREATE_RECIPIENT",
                        "CREATE_SHARE",
                    ],
                },
            ])
        ```

        ## Catalog grants

        You can grant `ALL_PRIVILEGES`, `APPLY_TAG`, `CREATE_CONNECTION`, `CREATE_SCHEMA`, `USE_CATALOG` privileges to Catalog specified in the `catalog` attribute. You can also grant `CREATE_FUNCTION`, `CREATE_TABLE`, `CREATE_VOLUME`, `EXECUTE`, `MODIFY`, `REFRESH`, `SELECT`, `READ_VOLUME`, `WRITE_VOLUME` and `USE_SCHEMA` at the catalog level to apply them to the pertinent current and future securable objects within the catalog:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        sandbox = databricks.Catalog("sandbox",
            name="sandbox",
            comment="this catalog is managed by terraform",
            properties={
                "purpose": "testing",
            })
        sandbox_grants = databricks.Grants("sandbox",
            catalog=sandbox.name,
            grants=[
                {
                    "principal": "Data Scientists",
                    "privileges": [
                        "USE_CATALOG",
                        "USE_SCHEMA",
                        "CREATE_TABLE",
                        "SELECT",
                    ],
                },
                {
                    "principal": "Data Engineers",
                    "privileges": [
                        "USE_CATALOG",
                        "USE_SCHEMA",
                        "CREATE_SCHEMA",
                        "CREATE_TABLE",
                        "MODIFY",
                    ],
                },
                {
                    "principal": "Data Analyst",
                    "privileges": [
                        "USE_CATALOG",
                        "USE_SCHEMA",
                        "SELECT",
                    ],
                },
            ])
        ```

        ## Schema grants

        You can grant `ALL_PRIVILEGES`, `APPLY_TAG`, `CREATE_FUNCTION`, `CREATE_TABLE`, `CREATE_VOLUME` and `USE_SCHEMA` privileges to _`catalog.schema`_ specified in the `schema` attribute. You can also grant `EXECUTE`, `MODIFY`, `REFRESH`, `SELECT`, `READ_VOLUME`, `WRITE_VOLUME` at the schema level to apply them to the pertinent current and future securable objects within the schema:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        things = databricks.Schema("things",
            catalog_name=sandbox["id"],
            name="things",
            comment="this schema is managed by terraform",
            properties={
                "kind": "various",
            })
        things_grants = databricks.Grants("things",
            schema=things.id,
            grants=[{
                "principal": "Data Engineers",
                "privileges": [
                    "USE_SCHEMA",
                    "MODIFY",
                ],
            }])
        ```

        ## Table grants

        You can grant `ALL_PRIVILEGES`, `APPLY_TAG`, `SELECT` and `MODIFY` privileges to _`catalog.schema.table`_ specified in the `table` attribute.

        ```python
        import pulumi
        import pulumi_databricks as databricks

        customers = databricks.Grants("customers",
            table="main.reporting.customers",
            grants=[
                {
                    "principal": "Data Engineers",
                    "privileges": [
                        "MODIFY",
                        "SELECT",
                    ],
                },
                {
                    "principal": "Data Analysts",
                    "privileges": ["SELECT"],
                },
            ])
        ```

        You can also apply grants dynamically with get_tables data resource:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        things = databricks.get_tables(catalog_name="sandbox",
            schema_name="things")
        things_grants = []
        for range in [{"key": k, "value": v} for [k, v] in enumerate(things.ids)]:
            things_grants.append(databricks.Grants(f"things-{range['key']}",
                table=range["value"],
                grants=[{
                    "principal": "sensitive",
                    "privileges": [
                        "SELECT",
                        "MODIFY",
                    ],
                }]))
        ```

        ## View grants

        You can grant `ALL_PRIVILEGES`, `APPLY_TAG` and `SELECT` privileges to _`catalog.schema.view`_ specified in `table` attribute.

        ```python
        import pulumi
        import pulumi_databricks as databricks

        customer360 = databricks.Grants("customer360",
            table="main.reporting.customer360",
            grants=[{
                "principal": "Data Analysts",
                "privileges": ["SELECT"],
            }])
        ```

        You can also apply grants dynamically with get_views data resource:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        customers = databricks.get_views(catalog_name="main",
            schema_name="customers")
        customers_grants = []
        for range in [{"key": k, "value": v} for [k, v] in enumerate(customers.ids)]:
            customers_grants.append(databricks.Grants(f"customers-{range['key']}",
                table=range["value"],
                grants=[{
                    "principal": "sensitive",
                    "privileges": [
                        "SELECT",
                        "MODIFY",
                    ],
                }]))
        ```

        ## Volume grants

        You can grant `ALL_PRIVILEGES`, `READ_VOLUME` and `WRITE_VOLUME` privileges to _`catalog.schema.volume`_ specified in the `volume` attribute.

        ```python
        import pulumi
        import pulumi_databricks as databricks

        this = databricks.Volume("this",
            name="quickstart_volume",
            catalog_name=sandbox["name"],
            schema_name=things["name"],
            volume_type="EXTERNAL",
            storage_location=some["url"],
            comment="this volume is managed by terraform")
        volume = databricks.Grants("volume",
            volume=this.id,
            grants=[{
                "principal": "Data Engineers",
                "privileges": ["WRITE_VOLUME"],
            }])
        ```

        ## Registered model grants

        You can grant `ALL_PRIVILEGES`, `APPLY_TAG`, and `EXECUTE` privileges to _`catalog.schema.model`_ specified in the `model` attribute.

        ```python
        import pulumi
        import pulumi_databricks as databricks

        customers = databricks.Grants("customers",
            model="main.reporting.customer_model",
            grants=[
                {
                    "principal": "Data Engineers",
                    "privileges": [
                        "APPLY_TAG",
                        "EXECUTE",
                    ],
                },
                {
                    "principal": "Data Analysts",
                    "privileges": ["EXECUTE"],
                },
            ])
        ```

        ## Function grants

        You can grant `ALL_PRIVILEGES` and `EXECUTE` privileges to _`catalog.schema.function`_ specified in the `function` attribute.

        ```python
        import pulumi
        import pulumi_databricks as databricks

        udf = databricks.Grants("udf",
            function="main.reporting.udf",
            grants=[
                {
                    "principal": "Data Engineers",
                    "privileges": ["EXECUTE"],
                },
                {
                    "principal": "Data Analysts",
                    "privileges": ["EXECUTE"],
                },
            ])
        ```

        ## Storage credential grants

        You can grant `ALL_PRIVILEGES`, `CREATE_EXTERNAL_LOCATION`, `CREATE_EXTERNAL_TABLE`, `READ_FILES` and `WRITE_FILES` privileges to StorageCredential id specified in `storage_credential` attribute:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        external = databricks.StorageCredential("external",
            name=external_data_access["name"],
            aws_iam_role={
                "role_arn": external_data_access["arn"],
            },
            comment="Managed by TF")
        external_creds = databricks.Grants("external_creds",
            storage_credential=external.id,
            grants=[{
                "principal": "Data Engineers",
                "privileges": ["CREATE_EXTERNAL_TABLE"],
            }])
        ```

        ## External location grants

        You can grant `ALL_PRIVILEGES`, `CREATE_EXTERNAL_TABLE`, `CREATE_MANAGED_STORAGE`, `CREATE EXTERNAL VOLUME`, `READ_FILES` and `WRITE_FILES` privileges to ExternalLocation id specified in `external_location` attribute:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        some = databricks.ExternalLocation("some",
            name="external",
            url=f"s3://{external_aws_s3_bucket['id']}/some",
            credential_name=external["id"],
            comment="Managed by TF")
        some_grants = databricks.Grants("some",
            external_location=some.id,
            grants=[
                {
                    "principal": "Data Engineers",
                    "privileges": [
                        "CREATE_EXTERNAL_TABLE",
                        "READ_FILES",
                    ],
                },
                {
                    "principal": my_sp["applicationId"],
                    "privileges": [
                        "CREATE_EXTERNAL_TABLE",
                        "READ_FILES",
                    ],
                },
                {
                    "principal": my_group["displayName"],
                    "privileges": [
                        "CREATE_EXTERNAL_TABLE",
                        "READ_FILES",
                    ],
                },
                {
                    "principal": my_user["userName"],
                    "privileges": [
                        "CREATE_EXTERNAL_TABLE",
                        "READ_FILES",
                    ],
                },
            ])
        ```

        ## Connection grants

        You can grant `ALL_PRIVILEGES`, `USE_CONNECTION` and `CREATE_FOREIGN_CATALOG` to Connection specified in `foreign_connection` attribute:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        mysql = databricks.Connection("mysql",
            name="mysql_connection",
            connection_type="MYSQL",
            comment="this is a connection to mysql db",
            options={
                "host": "test.mysql.database.azure.com",
                "port": "3306",
                "user": "user",
                "password": "password",
            },
            properties={
                "purpose": "testing",
            })
        some = databricks.Grants("some",
            foreign_connection=mysql.name,
            grants=[{
                "principal": "Data Engineers",
                "privileges": [
                    "CREATE_FOREIGN_CATALOG",
                    "USE_CONNECTION",
                ],
            }])
        ```

        ## Delta Sharing share grants

        You can grant `SELECT` to Recipient on Share name specified in `share` attribute:

        ```python
        import pulumi
        import pulumi_databricks as databricks

        some = databricks.Share("some", name="my_share")
        some_recipient = databricks.Recipient("some", name="my_recipient")
        some_grants = databricks.Grants("some",
            share=some.name,
            grants=[{
                "principal": some_recipient.name,
                "privileges": ["SELECT"],
            }])
        ```

        ## Other access control

        You can control Databricks General Permissions through Permissions resource.

        ## Import

        The resource can be imported using combination of securable type (`table`, `catalog`, `foreign_connection`, ...) and it's name:

        bash

        ```sh
        $ pulumi import databricks:index/grants:Grants this catalog/abc
        ```

        :param str resource_name: The name of the resource.
        :param GrantsArgs args: The arguments to use to populate this resource's properties.
        :param pulumi.ResourceOptions opts: Options for the resource.
        """
        ...
    def __init__(__self__, resource_name: str, *args, **kwargs):
        resource_args, opts = _utilities.get_resource_args_opts(GrantsArgs, pulumi.ResourceOptions, *args, **kwargs)
        if resource_args is not None:
            __self__._internal_init(resource_name, opts, **resource_args.__dict__)
        else:
            __self__._internal_init(resource_name, *args, **kwargs)

    def _internal_init(__self__,
                 resource_name: str,
                 opts: Optional[pulumi.ResourceOptions] = None,
                 catalog: Optional[pulumi.Input[str]] = None,
                 external_location: Optional[pulumi.Input[str]] = None,
                 foreign_connection: Optional[pulumi.Input[str]] = None,
                 function: Optional[pulumi.Input[str]] = None,
                 grants: Optional[pulumi.Input[Sequence[pulumi.Input[Union['GrantsGrantArgs', 'GrantsGrantArgsDict']]]]] = None,
                 metastore: Optional[pulumi.Input[str]] = None,
                 model: Optional[pulumi.Input[str]] = None,
                 pipeline: Optional[pulumi.Input[str]] = None,
                 recipient: Optional[pulumi.Input[str]] = None,
                 schema: Optional[pulumi.Input[str]] = None,
                 share: Optional[pulumi.Input[str]] = None,
                 storage_credential: Optional[pulumi.Input[str]] = None,
                 table: Optional[pulumi.Input[str]] = None,
                 volume: Optional[pulumi.Input[str]] = None,
                 __props__=None):
        opts = pulumi.ResourceOptions.merge(_utilities.get_resource_opts_defaults(), opts)
        if not isinstance(opts, pulumi.ResourceOptions):
            raise TypeError('Expected resource options to be a ResourceOptions instance')
        if opts.id is None:
            if __props__ is not None:
                raise TypeError('__props__ is only valid when passed in combination with a valid opts.id to get an existing resource')
            __props__ = GrantsArgs.__new__(GrantsArgs)

            __props__.__dict__["catalog"] = catalog
            __props__.__dict__["external_location"] = external_location
            __props__.__dict__["foreign_connection"] = foreign_connection
            __props__.__dict__["function"] = function
            if grants is None and not opts.urn:
                raise TypeError("Missing required property 'grants'")
            __props__.__dict__["grants"] = grants
            __props__.__dict__["metastore"] = metastore
            __props__.__dict__["model"] = model
            __props__.__dict__["pipeline"] = pipeline
            __props__.__dict__["recipient"] = recipient
            __props__.__dict__["schema"] = schema
            __props__.__dict__["share"] = share
            __props__.__dict__["storage_credential"] = storage_credential
            __props__.__dict__["table"] = table
            __props__.__dict__["volume"] = volume
        super(Grants, __self__).__init__(
            'databricks:index/grants:Grants',
            resource_name,
            __props__,
            opts)

    @staticmethod
    def get(resource_name: str,
            id: pulumi.Input[str],
            opts: Optional[pulumi.ResourceOptions] = None,
            catalog: Optional[pulumi.Input[str]] = None,
            external_location: Optional[pulumi.Input[str]] = None,
            foreign_connection: Optional[pulumi.Input[str]] = None,
            function: Optional[pulumi.Input[str]] = None,
            grants: Optional[pulumi.Input[Sequence[pulumi.Input[Union['GrantsGrantArgs', 'GrantsGrantArgsDict']]]]] = None,
            metastore: Optional[pulumi.Input[str]] = None,
            model: Optional[pulumi.Input[str]] = None,
            pipeline: Optional[pulumi.Input[str]] = None,
            recipient: Optional[pulumi.Input[str]] = None,
            schema: Optional[pulumi.Input[str]] = None,
            share: Optional[pulumi.Input[str]] = None,
            storage_credential: Optional[pulumi.Input[str]] = None,
            table: Optional[pulumi.Input[str]] = None,
            volume: Optional[pulumi.Input[str]] = None) -> 'Grants':
        """
        Get an existing Grants resource's state with the given name, id, and optional extra
        properties used to qualify the lookup.

        :param str resource_name: The unique name of the resulting resource.
        :param pulumi.Input[str] id: The unique provider ID of the resource to lookup.
        :param pulumi.ResourceOptions opts: Options for the resource.
        """
        opts = pulumi.ResourceOptions.merge(opts, pulumi.ResourceOptions(id=id))

        __props__ = _GrantsState.__new__(_GrantsState)

        __props__.__dict__["catalog"] = catalog
        __props__.__dict__["external_location"] = external_location
        __props__.__dict__["foreign_connection"] = foreign_connection
        __props__.__dict__["function"] = function
        __props__.__dict__["grants"] = grants
        __props__.__dict__["metastore"] = metastore
        __props__.__dict__["model"] = model
        __props__.__dict__["pipeline"] = pipeline
        __props__.__dict__["recipient"] = recipient
        __props__.__dict__["schema"] = schema
        __props__.__dict__["share"] = share
        __props__.__dict__["storage_credential"] = storage_credential
        __props__.__dict__["table"] = table
        __props__.__dict__["volume"] = volume
        return Grants(resource_name, opts=opts, __props__=__props__)

    @property
    @pulumi.getter
    def catalog(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "catalog")

    @property
    @pulumi.getter(name="externalLocation")
    def external_location(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "external_location")

    @property
    @pulumi.getter(name="foreignConnection")
    def foreign_connection(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "foreign_connection")

    @property
    @pulumi.getter
    def function(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "function")

    @property
    @pulumi.getter
    def grants(self) -> pulumi.Output[Sequence['outputs.GrantsGrant']]:
        return pulumi.get(self, "grants")

    @property
    @pulumi.getter
    def metastore(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "metastore")

    @property
    @pulumi.getter
    def model(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "model")

    @property
    @pulumi.getter
    def pipeline(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "pipeline")

    @property
    @pulumi.getter
    def recipient(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "recipient")

    @property
    @pulumi.getter
    def schema(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "schema")

    @property
    @pulumi.getter
    def share(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "share")

    @property
    @pulumi.getter(name="storageCredential")
    def storage_credential(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "storage_credential")

    @property
    @pulumi.getter
    def table(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "table")

    @property
    @pulumi.getter
    def volume(self) -> pulumi.Output[Optional[str]]:
        return pulumi.get(self, "volume")

