Как получить ВСЕ папки GCP от организации с помощью `gcloud`?

Мне было интересно, есть ли у вас способ найти все проекты / папки в организации. В настоящее время gcloud позволяет получать как папки, так и проекты, предоставленные родительскому объекту, делегируя рекурсивное действие КЛИЕНТУ.

Это не похоже, что это способ поиска с помощью диспетчера ресурсов API - интерфейсов, хотя, к сожалению, там нет gcloudэквивалентная команда. Это действительно работает:

$ alias curl-oauth='curl -H "Authorization: Bearer $(gcloud auth print-access-token)"'
$ curl-oauth -X POST https://cloudresourcemanager.googleapis.com/v2/folders:search '{}'

Спасибо за любую помощь или указатель на существующий код для реализации этой клиентской стороны или через gcloud.

5 ответов

Обновлено

Хорошо, вот (все еще) грубый (но теперь работающий) сценарий (спасибо @riccardo за доступ к тестовой организации):

#!/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]}

Передо мной стоит задача сделать это более эффективно в Bash; Мне интересно узнать, есть ли предложения у более опытных пользователей Bash.

Скрипт использует проекцию gcloud для кодирования base64 displayNameзначения. Это хакерский способ избежать непреднамеренного анализа этих строк (они могут содержать пробелы), и в противном случае я не смог найти способ избежать их.

Уровни по-прежнему не отступают

Предыдущий

Очень грубо... и, к сожалению, без доступа ни к Организации, ни к Папкам, так что в основном догадываюсь...

#!/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)")

Различные очевидные проблемы (и, вероятно, многие другие)

  1. Нет управления ошибками
  2. Непонятно, какой формат возвращается и как его взять folderId
  3. Без отступов уровней; Я подозреваю, что вам нужно добавить аргумент для этого
  4. Может потребоваться преобразовать возвращаемые значения в массивы bash

Если вы можете предоставить схему для gcloud resource-manager folders list ... --format=yaml, можете попробовать обратиться к №2

Вы просили gcloud но лучше сделать это, например, Python

Спасибо @DazWilkin за ваш сценарий. Я использовал это и добавил к нему, так как мне тоже нужны были проекты в папках. Надеюсь, этот код поможет кому-то другому.

      #!/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]}

Наконец-то я смог получить рекурсивную рубиновую версию (спасибо Daz за подсказку!).

Я скоро перенесу код в github, но все же хочу дать вам код на случай, если вы захотите поиграть с ним.

  • он заполняет всю организацию (вы можете использовать maxlevel).
  • IT создает точку graphviz и рисует ее (круто!)

Просто не забудьте создать каталог out / перед запуском.

Я прикрепляю результат своей организации к maxlevel=2 (что выглядит как 3 - нужно исправить).

Код Ruby на github: https://github.com/palladius/org-folder-projects-graph/blob/master/recurse_folders.rb

Используйте инвентаризацию активов в GCP, чтобы извлечь все папки из организации.

      gcloud asset search-all-resources \
  --scope='organizations/<Organization_ID>' \
  --asset-types='cloudresourcemanager.googleapis.com/Folder' \
  --order-by='createTime' \
  --query='state:ACTIVE'

К сожалению, для этого нет прямой команды.

Вот сценарий Bash, который может получить все папки (до трех уровней) и проекты в организации.

for FOL in $(for F0 in $(gcloud resource-manager folders list --organization=<ORGANIZATION_ID> --format='table(ID)' | sed -n '1!p');
  do echo $F0 ;
  for F1 in $(gcloud resource-manager folders list --folder=$F0 --format='table(ID)'| sed -n '1!p');
    do echo $F1;
    for F2 in $(gcloud resource-manager folders list --folder=$F1 --format='table(ID)'| sed -n '1!p');
      do echo $F2;
      gcloud resource-manager folders list --folder=$F2 --format='table(ID)';
      done;
    done;
  done);
  do  gcloud resource-manager folders describe $FOL;
  gcloud projects list --filter=parent.id:$FOL
  done

если вы знаете, что у вас больше уровней, вы можете добавить больше итераций уровней, вложив больше форов в первую часть, заменив gcloud resource-manager folders list --folder=$F2 --format='table(ID)'; с полным для этого:

for F3 in $(gcloud resource-manager folders list --folder=$F2 --format='table(ID)'| sed -n '1!p');
      do echo $F3;
      gcloud resource-manager folders list --folder=$F3 --format='table(ID)';
      done;

Я уже тестировал и работает нормально.

Другие вопросы по тегам