Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,11 @@ jobs:
env:
BATON_LOG_LEVEL: debug
# Add any environment variables needed to run baton-bitbucket-datacenter
DATABRICKS_CLIENT_ID: ${{ secrets.DATABRICKS_CLIENT_ID }}
DATABRICKS_CLIENT_SECRET: ${{ secrets.DATABRICKS_CLIENT_SECRET }}
BATON_DATABRICKS_CLIENT_ID: ${{ secrets.DATABRICKS_CLIENT_ID }}
BATON_DATABRICKS_CLIENT_SECRET: ${{ secrets.DATABRICKS_CLIENT_SECRET }}
BATON_ACCOUNT_ID: ${{ secrets.BATON_ACCOUNT_ID }}
BATON_WORKSPACES: ${{ secrets.BATON_WORKSPACES }}
BATON_WORKSPACE_TOKENS: ${{ secrets.BATON_WORKSPACE_TOKENS }}
# The following parameters are passed to grant/revoke commands
CONNECTOR_GRANT: 'group:778441812670942:member:user:5346803201281760'
CONNECTOR_ENTITLEMENT: 'group:778441812670942:member'
CONNECTOR_PRINCIPAL_TYPE: 'user'
CONNECTOR_PRINCIPAL: '5346803201281760'
# BATON_WORKSPACES: ${{ secrets.BATON_WORKSPACES }}
# BATON_WORKSPACE_TOKENS: ${{ secrets.BATON_WORKSPACE_TOKENS }}
steps:
- name: Install Go
uses: actions/setup-go@v5
Expand All @@ -63,5 +58,11 @@ jobs:
run: ./scripts/get-baton.sh && mv baton /usr/local/bin
- name: Build baton-databricks
run: go build ./cmd/baton-databricks
- name: Run baton-databricks
run: ./baton-databricks
- name: Test grant/revoking entitlements
env:
BATON: baton
BATON_DATABRICKS: ./baton-databricks
CONNECTOR_ENTITLEMENT: 'group:account/8c6f99ec-78ce-4654-8f92-e716b3dd67a7/group/66271399072731:member'
CONNECTOR_PRINCIPAL_TYPE: 'user'
CONNECTOR_PRINCIPAL: '5346803201281760'
run: ./scripts/grant-revoke.sh
37 changes: 28 additions & 9 deletions pkg/connector/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,21 @@ func (g *groupBuilder) Grant(ctx context.Context, principal *v2.Resource, entitl
return nil, fmt.Errorf("databricks-connector: only users, groups and service principals can be granted group permissions")
}

parentId, principalId, err := parseResourceId(principal.Id.Resource)
if err != nil {
return nil, fmt.Errorf("databricks-connector: failed to parse principal resource id: %w", err)
var parentId *v2.ResourceId
var principalId *v2.ResourceId
var err error
if principal.Id.ResourceType == groupResourceType.Id {
parentId, principalId, err = parseResourceId(principal.Id.Resource)
if err != nil {
return nil, fmt.Errorf("databricks-connector: failed to parse principal resource id: %w", err)
}
} else {
parentId = principal.ParentResourceId
principalId = principal.Id
}

var workspaceId string
if parentId.ResourceType == workspaceResourceType.Id {
if parentId != nil && parentId.ResourceType == workspaceResourceType.Id {
workspaceId = parentId.Resource
}

Expand Down Expand Up @@ -387,6 +395,17 @@ func (g *groupBuilder) Revoke(ctx context.Context, grant *v2.Grant) (annotations
return nil, fmt.Errorf("databricks-connector: only users, groups and service principals can have group permissions revoked")
}

principalId := principal.Id.Resource

var err error
if principal.Id.ResourceType == groupResourceType.Id {
_, principal, err := parseResourceId(principal.Id.Resource)
if err != nil {
return nil, fmt.Errorf("databricks-connector: failed to parse principal resource id: %w", err)
}
principalId = principal.Resource
}

parentResourceId, groupId, err := parseResourceId(entitlement.Resource.Id.Resource)
if err != nil {
return nil, fmt.Errorf("databricks-connector: failed to parse entitlement resource id: %w", err)
Expand All @@ -410,7 +429,7 @@ func (g *groupBuilder) Revoke(ctx context.Context, grant *v2.Grant) (annotations
}

for i, member := range group.Members {
if member.ID == principal.Id.Resource {
if member.ID == principalId {
group.Members = slices.Delete(group.Members, i, i+1)
break
}
Expand All @@ -436,7 +455,7 @@ func (g *groupBuilder) Revoke(ctx context.Context, grant *v2.Grant) (annotations
return nil, nil
}

principalID, err := preparePrincipalId(ctx, g.client, workspaceId, principal.Id.ResourceType, principal.Id.Resource)
principalId, err := preparePrincipalId(ctx, g.client, workspaceId, principal.Id.ResourceType, principal.Id.Resource)
if err != nil {
return nil, fmt.Errorf("databricks-connector: failed to prepare principal id: %w", err)
}
Expand All @@ -447,20 +466,20 @@ func (g *groupBuilder) Revoke(ctx context.Context, grant *v2.Grant) (annotations
}

// check if it contains the principals and remove the principal to the rule set
if slices.Contains(ruleSet.Principals, principalID) {
if slices.Contains(ruleSet.Principals, principalId) {
// if there is only one principal, remove the whole rule set
if len(ruleSet.Principals) == 1 {
ruleSets = slices.Delete(ruleSets, i, i+1)
} else {
pI := slices.Index(ruleSet.Principals, principalID)
pI := slices.Index(ruleSet.Principals, principalId)
ruleSets[i].Principals = slices.Delete(ruleSet.Principals, pI, pI+1)
}
break
}

l.Info(
"databricks-connector: group already does not have the entitlement",
zap.String("principal_id", principalID),
zap.String("principal_id", principalId),
zap.String("entitlement", entitlement.Slug),
)

Expand Down
54 changes: 54 additions & 0 deletions scripts/grant-revoke.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash

set -exo pipefail

if [ -z "$BATON_DATABRICKS" ]; then
echo "BATON_DATABRICKS not set. using baton-databricks"
BATON_DATABRICKS=baton-databricks
fi
if [ -z "$BATON" ]; then
echo "BATON not set. using baton"
BATON=baton
fi

# Error on unbound variables now that we've set BATON & BATON_DATABRICKS
set -u

# Sync
$BATON_DATABRICKS

$BATON resources

$BATON entitlements

$BATON grants

# Grant entitlement
$BATON_DATABRICKS --grant-entitlement="$CONNECTOR_ENTITLEMENT" --grant-principal="$CONNECTOR_PRINCIPAL" --grant-principal-type="$CONNECTOR_PRINCIPAL_TYPE"

# Check for grant before revoking
$BATON_DATABRICKS
$BATON grants --entitlement="$CONNECTOR_ENTITLEMENT" --output-format=json | jq --exit-status ".grants[] | select( .principal.id.resource == \"$CONNECTOR_PRINCIPAL\" )"

# Grant already-granted entitlement
$BATON_DATABRICKS --grant-entitlement="$CONNECTOR_ENTITLEMENT" --grant-principal="$CONNECTOR_PRINCIPAL" --grant-principal-type="$CONNECTOR_PRINCIPAL_TYPE"

# Get grant ID
CONNECTOR_GRANT=$($BATON grants --entitlement="$CONNECTOR_ENTITLEMENT" --output-format=json | jq --raw-output --exit-status ".grants[] | select( .principal.id.resource == \"$CONNECTOR_PRINCIPAL\" ).grant.id")

# Revoke grant
$BATON_DATABRICKS --revoke-grant="$CONNECTOR_GRANT"

# Revoke already-revoked grant
$BATON_DATABRICKS --revoke-grant="$CONNECTOR_GRANT"

# Check grant was revoked
$BATON_DATABRICKS
$BATON grants --entitlement="$CONNECTOR_ENTITLEMENT" --output-format=json | jq --exit-status "if .grants then [ .grants[] | select( .principal.id.resource == \"$CONNECTOR_PRINCIPAL\" ) ] | length == 0 else . end"

# Re-grant entitlement
$BATON_DATABRICKS --grant-entitlement="$CONNECTOR_ENTITLEMENT" --grant-principal="$CONNECTOR_PRINCIPAL" --grant-principal-type="$CONNECTOR_PRINCIPAL_TYPE"

# Check grant was re-granted
$BATON_DATABRICKS
$BATON grants --entitlement="$CONNECTOR_ENTITLEMENT" --output-format=json | jq --exit-status ".grants[] | select( .principal.id.resource == \"$CONNECTOR_PRINCIPAL\" )"
Loading