@@ -117,23 +117,28 @@ echo ""
117117databricks bundle run " $APP_NAME " --profile " $profile "
118118
119119# ── Get app metadata ─────────────────────────────────────────────────
120- app_json=$( databricks apps get " $DEPLOYED_APP_NAME " --profile " $profile " -o json 2> /dev/null || echo " {}" )
120+ echo " "
121+ echo " Fetching app metadata..."
122+ app_json=$( databricks apps get " $DEPLOYED_APP_NAME " --profile " $profile " -o json 2>&1 ) || { echo " Warning: Could not fetch app metadata." ; app_json=" {}" ; }
121123integration_id=$( echo " $app_json " | python3 -c " import sys,json; print(json.load(sys.stdin).get('oauth2_app_integration_id',''))" 2> /dev/null)
122124sp_id=$( echo " $app_json " | python3 -c " import sys,json; print(json.load(sys.stdin).get('service_principal_id',''))" 2> /dev/null)
125+ sp_name=$( echo " $app_json " | python3 -c " import sys,json; print(json.load(sys.stdin).get('service_principal_name',''))" 2> /dev/null)
126+ echo " App integration ID: ${integration_id:- not found} "
127+ echo " Service Principal: ${sp_name:- unknown} (ID: ${sp_id:- not found} )"
123128
124- # ── Upload app thumbnail ─────────────────────────────────────────────
125- if [[ -f " $SCREENSHOT " ]]; then
126- echo " "
127- echo " Uploading app thumbnail..."
128- _token=$( databricks auth token --profile " $profile " 2> /dev/null \
129- | python3 -c " import sys,json; print(json.load(sys.stdin).get('access_token',''))" 2> /dev/null)
130- _ws_host=$( echo " $app_json " | python3 -c " import sys,json; d=json.load(sys.stdin); u=d.get('url',''); print(u.split('.')[0].replace('https://','').rsplit('-',1)[0] if u else '')" 2> /dev/null)
131- # Derive workspace host from the profile
132- _ws_host=$( python3 -c "
129+ # ── Get auth token + workspace host for API calls ────────────────────
130+ _token=$( databricks auth token --profile " $profile " 2> /dev/null \
131+ | python3 -c " import sys,json; print(json.load(sys.stdin).get('access_token',''))" 2> /dev/null)
132+ _ws_host=$( python3 -c "
133133from databricks.sdk.core import Config
134134c = Config(profile='${profile} ')
135135print((c.host or '').rstrip('/'))
136136" 2> /dev/null)
137+
138+ # ── Upload app thumbnail ─────────────────────────────────────────────
139+ if [[ -f " $SCREENSHOT " ]]; then
140+ echo " "
141+ echo " Uploading app thumbnail..."
137142 if [[ -n " $_token " && -n " $_ws_host " ]]; then
138143 _b64=$( base64 -i " $SCREENSHOT " )
139144 _resp=$( curl -s -X POST " ${_ws_host} /api/2.0/apps/${DEPLOYED_APP_NAME} /thumbnail" \
@@ -144,6 +149,9 @@ print((c.host or '').rstrip('/'))
144149 else
145150 echo " Warning: Could not upload thumbnail (missing token or host)."
146151 fi
152+ else
153+ echo " "
154+ echo " Skipping thumbnail upload (${SCREENSHOT} not found)."
147155fi
148156
149157# ── Configure OBO scopes (requires an account-level profile) ──────────
173181 echo " OBO scopes not configured. Add them in the Databricks Apps UI → Configure → Add scope."
174182 else
175183 echo " Using account profile: ${account_profile} "
176- echo " Integration ID: ${integration_id} "
184+ echo " Updating integration ${integration_id} with all-apis scope... "
177185
178186 redirect_urls=$( databricks account custom-app-integration get " $integration_id " \
179187 --profile " $account_profile " -o json 2> /dev/null \
@@ -182,40 +190,67 @@ else
182190 databricks account custom-app-integration update " $integration_id " \
183191 --profile " $account_profile " \
184192 --json " {\" scopes\" : ${OBO_SCOPES} , \" redirect_urls\" : ${redirect_urls:- " []" } }" 2> /dev/null \
185- && echo " OBO scopes configured successfully: all-apis enabled ." \
193+ && echo " OBO scopes configured successfully." \
186194 || echo " Warning: Could not update OBO scopes. Configure them manually in the Databricks Apps UI."
187195 fi
188196fi
189197
190198# ── Add Service Principal to admins group ─────────────────────────────
191- if [[ -n " $sp_id " ]]; then
192- # Check if the SP is already in the admins group
193- admins_json=$( databricks groups get admins --profile " $profile " -o json 2> /dev/null || echo " {}" )
194- sp_in_admins=$( echo " $admins_json " | python3 -c "
199+ echo " "
200+ echo " Checking Service Principal admin group membership..."
201+
202+ if [[ -z " $sp_id " ]]; then
203+ echo " Warning: No Service Principal ID found — skipping admins group check."
204+ elif [[ -z " $_token " || -z " $_ws_host " ]]; then
205+ echo " Warning: No auth token or host — skipping admins group check."
206+ else
207+ # Use SCIM API to find the admins group and check membership
208+ admins_scim=$( curl -s " ${_ws_host} /api/2.0/preview/scim/v2/Groups?filter=displayName+eq+%22admins%22" \
209+ -H " Authorization: Bearer ${_token} " 2>&1 )
210+
211+ admins_group_id=$( echo " $admins_scim " | python3 -c "
195212import sys, json
196- data = json.load(sys.stdin)
197- members = data.get('members', [])
213+ d = json.load(sys.stdin)
214+ groups = d.get('Resources', [])
215+ print(groups[0]['id'] if groups else '')
216+ " 2> /dev/null)
217+
218+ if [[ -z " $admins_group_id " ]]; then
219+ echo " Warning: Could not find admins group via SCIM API."
220+ else
221+ sp_in_admins=$( echo " $admins_scim " | python3 -c "
222+ import sys, json
223+ d = json.load(sys.stdin)
224+ members = d.get('Resources', [{}])[0].get('members', [])
198225sp_id = '${sp_id} '
199226print('yes' if any(str(m.get('value')) == sp_id for m in members) else 'no')
200227" 2> /dev/null)
201228
202- if [[ " $sp_in_admins " == " yes" ]]; then
203- echo " "
204- echo " App Service Principal (ID: ${sp_id} ) is already in the admins group."
205- else
206- echo " "
207- echo " The app's Service Principal (ID: ${sp_id} ) is NOT in the admins group."
208- echo " Adding it to admins allows the SP to access all workspace objects."
209- printf " Add Service Principal to admins group? [y/N] "
210- read -r add_to_admins
211-
212- if [[ " $add_to_admins " =~ ^[Yy]$ ]]; then
213- databricks groups patch admins --profile " $profile " \
214- --json " {\" Operations\" : [{\" op\" : \" add\" , \" value\" : {\" members\" : [{\" value\" : \" ${sp_id} \" }]}}], \" schemas\" : [\" urn:ietf:params:scim:api:messages:2.0:PatchOp\" ]}" 2> /dev/null \
215- && echo " Service Principal added to admins group." \
216- || echo " Warning: Could not add SP to admins group. Add it manually via Settings → Identity and access → Groups → admins."
229+ if [[ " $sp_in_admins " == " yes" ]]; then
230+ echo " ${sp_name} (ID: ${sp_id} ) is already in the admins group."
217231 else
218- echo " Skipped. The SP may not be able to access all workspace objects."
232+ echo " ${sp_name} (ID: ${sp_id} ) is NOT in the admins group."
233+ echo " Adding it to admins allows the SP to access all workspace objects."
234+ printf " Add Service Principal to admins group? [y/N] "
235+ read -r add_to_admins
236+
237+ if [[ " $add_to_admins " =~ ^[Yy]$ ]]; then
238+ echo " Adding SP to admins group (SCIM group ID: ${admins_group_id} )..."
239+ _patch_resp=$( curl -s -X PATCH " ${_ws_host} /api/2.0/preview/scim/v2/Groups/${admins_group_id} " \
240+ -H " Authorization: Bearer ${_token} " \
241+ -H " Content-Type: application/scim+json" \
242+ -d " {\" Operations\" : [{\" op\" : \" add\" , \" path\" : \" members\" , \" value\" : [{\" value\" : \" ${sp_id} \" }]}], \" schemas\" : [\" urn:ietf:params:scim:api:messages:2.0:PatchOp\" ]}" 2>&1 )
243+ # Check for error
244+ _err=$( echo " $_patch_resp " | python3 -c " import sys,json; d=json.load(sys.stdin); print(d.get('detail',''))" 2> /dev/null)
245+ if [[ -z " $_err " ]]; then
246+ echo " Service Principal added to admins group."
247+ else
248+ echo " Warning: Could not add SP to admins group: ${_err} "
249+ echo " Add it manually via Settings → Identity and access → Groups → admins."
250+ fi
251+ else
252+ echo " Skipped. The SP may not be able to access all workspace objects."
253+ fi
219254 fi
220255 fi
221256fi
0 commit comments