Skip to content

Commit

Permalink
add secrets to secrets manager and delete service principal on accoun…
Browse files Browse the repository at this point in the history
…t level
  • Loading branch information
Anton Shchederkin committed Dec 18, 2024
1 parent 0c96744 commit 27ba236
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from databricks.sdk.service.iam import ServicePrincipal
from pydantic import BaseModel

from databricks_cdk.utils import CnfResponse, get_workspace_client
from databricks_cdk.utils import CnfResponse, get_workspace_client, get_account_client

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -104,8 +104,10 @@ def update_service_principal(
def delete_service_principal(properties: ServicePrincipalProperties, physical_resource_id: str) -> CnfResponse:
"""Delete a service pricncipal on databricks"""
workspace_client = get_workspace_client(properties.workspace_url)
account_client = get_account_client()
try:
workspace_client.service_principals.delete(id=physical_resource_id)
account_client.service_principals.delete(id=physical_resource_id)
except NotFound:
logger.warning("Service principal not found, never existed or already removed")

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import json
import logging
from typing import Optional

import boto3
from databricks.sdk.service.oauth2 import SecretInfo
from databricks.sdk import AccountClient
from databricks.sdk.errors import NotFound
from pydantic import BaseModel

from databricks_cdk.utils import CnfResponse, get_account_client
from databricks_cdk.resources.service_principals.service_principal import get_service_principal

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -61,14 +64,24 @@ def get_service_principal_secrets(


def create_service_principal_secrets(properties: ServicePrincipalSecretsProperties, account_client: AccountClient) -> CnfResponse:
"""Create service principal secrets on databricks."""
"""
Create service principal secrets on databricks.
It will create a new service principal secrets and store it in secrets manager.
"""
service_principal = get_service_principal(properties.service_principal_id, account_client)
created_service_principal_secrets = account_client.service_principal_secrets.create(
service_principal_id=properties.service_principal_id
)

if created_service_principal_secrets.id is None:
raise ServicePrincipalSecretsCreationError("Failed to create service principal secrets")

secret_name = f"{service_principal.display_name}/{service_principal.id}"
add_to_secrets_manager(
secret_name=secret_name,
client_id=service_principal.application_id,
client_secret=created_service_principal_secrets.secret
)
return CnfResponse(
physical_resource_id=created_service_principal_secrets.id
)
Expand All @@ -77,12 +90,34 @@ def create_service_principal_secrets(properties: ServicePrincipalSecretsProperti
def delete_service_principal_secrets(properties: ServicePrincipalSecretsProperties, physical_resource_id: str) -> CnfResponse:
"""Delete service pricncipal secrets on databricks."""
account_client = get_account_client()

try:
account_client.service_principal_secrets.delete(
service_principal_id=properties.service_principal_id,
secret_id=physical_resource_id
)
except NotFound:
logger.warning("Service principal secrets with id %s not found", physical_resource_id)


service_principal = get_service_principal(properties.service_principal_id, account_client)
secret_name = f"{service_principal.display_name}/{service_principal.id}"
delete_from_secrets_manager(secret_name)
return CnfResponse(physical_resource_id=physical_resource_id)


def add_to_secrets_manager(secret_name: str, client_id: str, client_secret: str) -> None:
"""Adds credentials to secrets manager at /databricks/service_principal/secrets/{{secret_name}}"""
client = boto3.client("secretsmanager")
secret_full_name = f"/databricks/service_principal/secrets/{secret_name}"
secret_string = {"client_id": client_id, "client_secret": client_secret}
client.create_secret(Name=secret_full_name, SecretString=json.dumps(secret_string))["ARN"]


def delete_from_secrets_manager(secret_name: str) -> None:
"""Removes credentials from secrets manager at /databricks/service_principal/secrets/{{secret_name}}"""
client = boto3.client("secretsmanager")
secret_full_name = f"/databricks/service_principal/secrets/{secret_name}"
try:
client.delete_secret(SecretId=secret_full_name, ForceDeleteWithoutRecovery=True)
except client.exceptions.ResourceNotFoundException:
logger.warning("Secret with name %s not found", secret_full_name)

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (secret)
as clear text.
This expression logs
sensitive data (secret)
as clear text.
This expression logs
sensitive data (secret)
as clear text.
2 changes: 1 addition & 1 deletion typescript/src/resources/deploy-lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ export class DatabricksDeployLambda extends IDatabricksDeployLambda {
effect: aws_iam.Effect.ALLOW,
actions: ["secretsmanager:CreateSecret", "secretsmanager:DeleteSecret", "secretsmanager:UpdateSecret"],
resources: [
`arn:aws:secretsmanager:${this.props.region}:${this.props.accountId}:secret:/databricks/token/*`,
`arn:aws:secretsmanager:${this.props.region}:${this.props.accountId}:secret:/databricks/*`,
]
}));

Expand Down

0 comments on commit 27ba236

Please sign in to comment.