Reputation: 1247
I was wondering if you have a way to find all projects/folders in an organization. Currently gcloud allows to get both folders and projects given the parent, delegating the recursive action to the CLIENT.
It looks like there is a way to Search via Resource Manager APIs, although unfortunately there's no gcloud
equivalent command. This does work:
$ alias curl-oauth='curl -H "Authorization: Bearer $(gcloud auth print-access-token)"'
$ curl-oauth -X POST https://cloudresourcemanager.googleapis.com/v2/folders:search '{}'
Thanks for any help or pointer to existing code to implement this client side or via gcloud
.
Upvotes: 3
Views: 6930
Reputation: 1247
I was finally able to get a recursive ruby version (thanks Daz for the Hint!).
It's on github
maxlevel
).I'm attaching the result of my org with maxlevel=2
(which looks like 3 - need to fix it).
Ruby code on github: https://github.com/palladius/org-folder-projects-graph/
Sample output:
🌲 824879804362 # 'palladi.us'
├─ 🍕 xpn-main (398198244705)
├─ 🍕 orgnode-palladi-us (704861684515)
├─ 📁 993609995477 (customers)
├─ 📁 571390668780 (dirimpettai di EURF)
├─ 📁 885056483479 (dev and test)
├─ 🍕 prova-123-dentro-palladi-us (237925736669)
├─ 🍕 palladius-eu (177178925177)
├─ 🍕 prova123-160016 (262470358174)
├─ 🍕 folder-test-prod (1025012666423)
├─ 🍕 folder-test-dev (351173986048)
├─ 📁 128544652663 (folderillo)
├─ 📁 887288965373 (prod stuff - for real)
├─ 🍕 gbanana-prod (626662139195)
├─ 📁 510416893777 (TFR Terraformed by Ricc)
├─ 📁 93350088776 (TF DEV)
├─ 📁 723110142384 (TF0b - titius)
├─ 📁 1026736501110 (TF1b - caius)
├─ 📁 802144187596 (TF2b - sempronius)
├─ 📁 99919748229 (TF PROD)
Upvotes: 2
Reputation: 322
Use Asset Inventory in GCP to pull all the Folders from Organization.
gcloud asset search-all-resources \
--scope='organizations/<Organization_ID>' \
--asset-types='cloudresourcemanager.googleapis.com/Folder' \
--order-by='createTime' \
--query='state:ACTIVE'
Upvotes: 1
Reputation: 31
Thank you @DazWilkin for your script. I used this and added to it, as I needed projects within the folders too. Hopefully this code can help someone else.
#!/usr/bin/env bash
: "${ORGANIZATION:?Need to export ORGANIZATION and it must be non-empty}"
# gcloud format
FORMAT="csv[no-heading](name,displayName.encode(base64))"
FORMAT_PRJ="table[box,title='Folder ${NAME} Project List'] \
(createTime:sort=1,name,projectNumber,projectId:label=ProjectID,parent.id:label=Parent)"
# Enumerates Folders recursively
folders()
# project()
{
LINES=("$@")
for LINE in ${LINES[@]}
do
# Parses lines of the form folder,name
VALUES=(${LINE//,/ })
FOLDER=${VALUES[0]}
# Decodes the encoded name
NAME=$(echo ${VALUES[1]} | base64 --decode)
printf "Folder: ${FOLDER} (${NAME})\n\n"
printf "Project: Project info: \n\n"
project=$(gcloud projects list \
--filter parent.id:${FOLDER} \
--format="${FORMAT_PRJ}")
if [ -z "$project" ]
then
printf "Folder: ${FOLDER} - ${NAME} has no sub-projects\n\n"
else
printf "Parent FolderID: ${FOLDER}\t Parent Name(s): ${NAME}\n${project} \n\n"
fi
folders $(gcloud resource-manager folders list \
--folder=${FOLDER} \
--format="${FORMAT}")
done
}
# Start at the Org
printf "Org: ${ORGANIZATION}\n\n"
LINES=$(gcloud resource-manager folders list \
--organization=${ORGANIZATION} \
--format="${FORMAT}")
# Descend
folders ${LINES[0]}
Upvotes: 3
Reputation: 40306
OK, here's a (still) rough (but now working) script (thanks @riccardo for the access to a test Org):
#!/usr/bin/env bash
: "${ORGANIZATION:?Need to export ORGANIZATION and it must be non-empty}"
# gcloud format
FORMAT="csv[no-heading](name,displayName.encode(base64))"
# Enumerates Folders recursively
folders()
{
LINES=("$@")
for LINE in ${LINES[@]}
do
# Parses lines of the form folder,name
VALUES=(${LINE//,/ })
FOLDER=${VALUES[0]}
# Decodes the encoded name
NAME=$(echo ${VALUES[1]} | base64 --decode)
echo "Folder: ${FOLDER} (${NAME})"
folders $(gcloud resource-manager folders list \
--folder=${FOLDER} \
--format="${FORMAT}")
done
}
# Start at the Org
echo "Org: ${ORGANIZATION}"
LINES=$(gcloud resource-manager folders list \
--organization=${ORGANIZATION} \
--format="${FORMAT}")
# Descend
folders ${LINES[0]}
I'm challenged to do this more effectively in Bash; I'm interested to see whether more experienced Bash users have suggestions.
The script uses a gcloud projection to base64 encode displayName
values. This is a hacky way to avoid inadvertent parsing of these strings (they may contain spaces) and I was unable to find a way to escape these otherwise.
Still doesn't indent levels 😞
Super rough... and regrettably without access to either an Org or Folders so, mostly guessing...
#!/usr/bin/env bash
ORGANIZATION="..."
folders()
{
for FOLDER in ${1}
do
echo ${FOLDER}
# Use the `--folder` variant for children
folders $(gcloud resource-manager folders list \
--folder=${FOLDER} \
--format="value(name)")
done
}
# Start at the Org
echo "Org: ${ORGANIZATION}"
folders $(\
gcloud resource-manager folders list \
--organization=${ORGANIZATION} \
--format="value(name)")
Various obvious issues (and likely many others)
folderId
If you can provide the schema for gcloud resource-manager folders list ... --format=yaml
, can try to address #2
You asked for gcloud
but this may better done using e.g. Python
Upvotes: 3