Skip to content

Commit

Permalink
Merge pull request #67 from databricks-industry-solutions/feature/lak…
Browse files Browse the repository at this point in the history
…ehouse_app_permissions

Permission grants to Lakehouse App Service Principal
  • Loading branch information
erinaldidb authored Nov 1, 2024
2 parents 25ef123 + 819400e commit 08898f5
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 6 deletions.
102 changes: 98 additions & 4 deletions 07-OHIF-Lakehouse-App.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,43 @@

# COMMAND ----------

init_widgets()
# MAGIC %md
# MAGIC # Initializing Environment and Setting Up Application
# MAGIC
# MAGIC Initialize widgets to capture the SQL warehouse ID, table, and volume. We also set up the environment and define the application name as "pixels-ohif-viewer".

# COMMAND ----------

sql_warehouse_id, table, volume = init_widgets(show_volume=True)
init_env()

app_name = "pixels-ohif-viewer"

# COMMAND ----------

# MAGIC %md
# MAGIC # Setting Up and Deploying the Lakehouse Application
# MAGIC
# MAGIC The next step will perform several critical steps to set up and deploy our Lakehouse Application:
# MAGIC
# MAGIC 1. **Import Necessary Libraries**: We start by importing required libraries and modules such as `AppResource`, `AppResourceSqlWarehouse`, and others from the `databricks.sdk.service.apps`, along with `Path` from `pathlib`, and `dbx.pixels.resources`.
# MAGIC
# MAGIC 2. **Initialize Workspace Client**: An instance of `WorkspaceClient` is created to interact with the Databricks workspace.
# MAGIC
# MAGIC 3. **Prepare Application Configuration**: The application's configuration is prepared by reading a template configuration file (`app-config.yaml`), replacing placeholders with actual values (like the pixels table name), and writing the modified configuration to `app.yaml`.
# MAGIC
# MAGIC 4. **Define SQL Warehouse Resource**: We define a `sql_resource` with the SQL warehouse ID and permissions required for the application to use the SQL warehouse.
# MAGIC
# MAGIC 5. **Create and Deploy the Application**: The application is created and deployed using the `create_and_wait` and `deploy_and_wait` methods of the `WorkspaceClient`. This process involves specifying the application name, resources (like the SQL warehouse resource), and the path to the application's source code.
# MAGIC
# MAGIC 6. **Extract Service Principal ID**: After deployment, the service principal ID is extracted from the deployment artifacts for permission grants.
# MAGIC
# MAGIC 7. **Output Deployment Status and URL**: Finally, the deployment status message and the application URL are printed, indicating the completion of the deployment process and how to access the deployed application.
# MAGIC
# MAGIC This cell encapsulates the entire process of preparing, creating, and deploying the Lakehouse Application, making it a pivotal step in the application setup workflow.

# COMMAND ----------

from databricks.sdk.service.apps import AppResource, AppResourceSqlWarehouse, AppResourceSqlWarehouseSqlWarehousePermission

from pathlib import Path
Expand All @@ -48,6 +78,70 @@
)

print(f"Creating Lakehouse App with name {app_name}, this step will require few minutes to complete")
app = w.apps.create_and_wait(name=app_name, resources=[sql_resource])
print(w.apps.deploy_and_wait(app_name=app_name, source_code_path=lha_path).status.message)
print(app.url)

app_created = w.apps.create_and_wait(name=app_name, resources=[sql_resource])
app_deploy = w.apps.deploy_and_wait(app_name=app_name, source_code_path=lha_path)

service_principal_id = app_deploy.deployment_artifacts.source_code_path.split("/")[3]

print(app_deploy.status.message)
print(app_created.url)

# COMMAND ----------

# MAGIC %md
# MAGIC # Granting Permissions
# MAGIC
# MAGIC The next cell is responsible for granting the necessary permissions to the service principal for accessing the catalog, schema, table, and volume.
# MAGIC
# MAGIC This ensures that the Lakehouse App has the required access to perform its operations.

# COMMAND ----------

from databricks.sdk.service import catalog

#Grant USE CATALOG permissions on CATALOG
w.grants.update(full_name=table.split(".")[0],
securable_type=catalog.SecurableType.CATALOG,
changes=[
catalog.PermissionsChange(
add=[catalog.Privilege.USE_CATALOG],
principal=service_principal_id
)
]
)

#Grant USE SCHEMA permissions on SCHEMA
w.grants.update(full_name=table.split(".")[0]+"."+table.split(".")[1],
securable_type=catalog.SecurableType.SCHEMA,
changes=[
catalog.PermissionsChange(
add=[catalog.Privilege.USE_SCHEMA],
principal=service_principal_id
)
]
)

#Grant SELECT permissions on TABLE
w.grants.update(full_name=table,
securable_type=catalog.SecurableType.TABLE,
changes=[
catalog.PermissionsChange(
add=[catalog.Privilege.SELECT],
principal=service_principal_id
)
]
)

#Grant READ_VOLUME permissions on VOLUME
w.grants.update(full_name=volume,
securable_type=catalog.SecurableType.VOLUME,
changes=[
catalog.PermissionsChange(
add=[catalog.Privilege.READ_VOLUME],
principal=service_principal_id
)
]
)

print("PERMISSIONS GRANTED")
11 changes: 9 additions & 2 deletions config/proxy_prep.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,18 @@

# COMMAND ----------

def init_widgets():
def init_widgets(show_volume=False):

dbutils.widgets.text("table", "main.pixels_solacc.object_catalog", label="1.0 Catalog Schema Table to store object metadata into")
table = dbutils.widgets.get("table")
dbutils.widgets.text("sqlWarehouseID", "", label="2.0 SQL Warehouse")
sql_warehouse_id = dbutils.widgets.get("sqlWarehouseID")
table = dbutils.widgets.get("table")

if show_volume:
dbutils.widgets.text("volume", "main.pixels_solacc.pixels_volume", label="3.0 Catalog Schema Volume where pixel volumes are stored into")
volume = dbutils.widgets.get("volume")
return sql_warehouse_id, table, volume

return sql_warehouse_id, table

# COMMAND ----------
Expand Down

0 comments on commit 08898f5

Please sign in to comment.