谷歌云:如何列出GCP中所有项目的所有服务帐户

3

我有一个需求,需要获取Google Cloud服务账户的所有属性。是否可以列出所有属性,类似于Select *。

否则我需要以下信息:

  • SA帐户名称
  • 电子邮件地址
  • 分配的IAM角色
  • 用户管理的密钥(如果有)
  • 帐户创建日期
  • 最近使用/身份验证时间。
  • 项目名称
  • 帐户状态(启用/禁用)

我可以获取所有项目,然后获取其中的所有服务账户,但我不知道如何获取所有其他值。

foreach ($project in gcloud projects list --format="value(projectId)")
{
  Write-Host "ProjectId: $project"
  foreach ($robot in  gcloud iam service-accounts list --project $project --format="value(email)")
  {
     Write-Host "    -> Robot $robot"
   
  }
}

1
gcloud iam service-accounts describegcloud iam service-accounts keys list 将会给你一些细节信息。像 最后使用时间 这样的信息需要解析 Cloud Logging。日志保留默认为30天,因此您需要延长保留时间以便能够扫描超过30天的日志。 - John Hanley
那个命令只提供了7个属性,我注意到如果我运行另一个gcloud iam service-accounts get-iam-policy,它会提供成员和角色...有没有可用的脚本可以列出服务帐户的所有属性。 - Waqas Sarwar MVP
你通过 API 调用找到了所有需要的信息吗?有些似乎无法获取(上次使用的??)。你将不得不执行多个请求来获取每一个单独的信息。 - guillaume blaquiere
我没有 API 调用经验,所以不知道。看起来我必须运行所有可用的服务账户 gcloud 命令以获取最大信息量。你是正确的,上次使用过的几乎不可能得到。 - Waqas Sarwar MVP
您可以使用list方法来获取每个项目的服务账户信息。但是响应中可能并不包含您正在寻找的某些字段。 - Farid Shumbar
2个回答

6

正如评论者所指出的那样,这并不是一个微不足道的问题。

但是,我总是喜欢一些gcloud-bash ;-)

您的代码示例表明您希望在PowerShell中获得答案,而我没有,希望您不介意在bash中使用pointers(以下是不完整的):

包括:

  • 项目ID
  • 账户名称
  • 启用|禁用
  • 电子邮件
  • 密钥
  • 创建时间戳

不包括:

  • 角色分配
  • 最后使用时间(审计日志?)
PROJECTS=$(gcloud projects list --format="value(projectId)")

for PROJECT in ${PROJECTS}
do
  echo "Project: ${PROJECT}"
  # Extracts ACCOUNT_ID, EMAIL (==ACCOUNT_ID@...), DISABLED
  ROBOTS=$(\
    gcloud iam service-accounts list \
    --project=${PROJECT} \
    --format="csv[no-heading](displayName.encode(\"base64\"),email,email.split(\"@\").slice(0),disabled)")
  for ROBOT in ${ROBOTS}
  do
    # Parse results
    IFS=, read ENCODED_NAME EMAIL ACCOUNT_ID DISABLED <<< ${ROBOT}
    NAME=$(echo -e ${ENCODED_NAME} | base64 --decode)
    echo "  Service Account: ${NAME}"
    echo "    Disabled: ${DISABLED}"
    echo "    Email: ${EMAIL}"
    # Keys
    KEYS=$(\
        gcloud iam service-accounts keys list \
        --iam-account=${EMAIL} \
        --project=${PROJECT} \
        --format="value(name.scope(keys))")
    for KEY in ${KEYS}
    do
      echo "    Key: ${KEY}"
    done
    # Creation (Only searches back 30-days!)
    FILTER=""\
"logName=\"projects/${PROJECT}/logs/cloudaudit.googleapis.com%2Factivity\" "\
"resource.type=\"service_account\" "\
"protoPayload.methodName=\"google.iam.admin.v1.CreateServiceAccount\" "\
"protoPayload.request.account_id=\"${ACCOUNT_ID}\" "

    LOG=$(\
        gcloud logging read "${FILTER}" \
        --project=${PROJECT} \
        --format=json \
        --freshness=30d \
        --format="value(timestamp)")
    echo "    Created: ${LOG}"
  done
done

注意事项

  • Service Account的创建时间只能通过审计日志 (CreateServiceAccount[Key]) 获得。其中一个挑战是需要搜索整个项目(全部历史记录)来查找这些信息。
  • 只有用户创建的Service Account才会在项目的生命周期内创建。Google维护的账户,如App Engine,将无法找到。
  • 脚本会为每个帐户搜索日志。这样效率不高,最好一次性搜索所有帐户的日志,然后合并结果。
  • 由于继承的存在,角色分配很困难。一个天真的解决方案是获取每个项目的IAM策略,但这是不充分的,因为它没有涵盖组织|文件夹权限,也不包括特定资源的绑定。
  • 我实际上不知道如何在日志中搜索最后的身份验证时间,并假设这可以通过审计日志获得。
  • 对于帐户的displayName采用了粗糙的base64编码方式,以避免过于急切地解析(大部分)包含空格的名称。可能有更好的方法。

你现在是云脚本大师 - John Hanley
谢谢@DazWilkin,我会尝试并在这里更新...再次感谢您的努力。 - Waqas Sarwar MVP
不错!可以使用--format="csvno-heading"来提取创建和过期时间,假设它们是同一件事。但这会破坏$KEYS的格式。 - intotecho

0
借鉴了@DazWilin的优秀脚本,并进行了一些修改,它可以生成一个包含所有服务账户、包括描述和密钥的服务账户注册表或CSV文件。去除日志抓取可以加快速度。
#! /bin/bash
# Requires permission to list projects, list service accounts, view keys
if [ $# -lt 1 ]
then
  echo "usage:  $0 csv_output_file"
  exit
fi

gcloud projects list --format="value(projectId)" --sort-by=projectId
OUTFILE=$1
FILTER='prefix'
PROJECTS=$(gcloud projects list --format="value(projectId)" --filter="${FILTER}")

echo "Project,ServiceAccountName,Account Name,Email,Description,key_id,key_created_at,key_expires_at" > $OUTFILE

for PROJECT in ${PROJECTS}
do
  echo "Project: ${PROJECT}"
  # Extracts ACCOUNT_ID, EMAIL (==ACCOUNT_ID@...), DISABLED, DESCRIPTION
  ROBOTS=$(\
    gcloud iam service-accounts list \
    --project=${PROJECT} \
     --format="csv[no-heading](displayName.encode(\"base64\"),email,email.split(\"@\").slice(0),disabled,description.encode(\"base64\"))")

  #echo $ROBOTS
  for ROBOT in ${ROBOTS}
  do
    # Parse results
    IFS=, read ENCODED_NAME EMAIL ACCOUNT_ID DISABLED ENCODED_DESCR<<< ${ROBOT}
    NAME=$(echo -e ${ENCODED_NAME} | base64 --decode)
    DESCR=$(echo -e ${ENCODED_DESCR} | base64 --decode)
    echo "  Service Account: ${NAME}"
    echo "    Disabled: ${DISABLED}"
    echo "    Email: ${EMAIL}"
    echo "    Descr: ${DESCR}"
    RESPONSE=$(\
        gcloud iam service-accounts keys list \
        --iam-account=${EMAIL} \
        --project=${PROJECT} \
        --format="csv[no-heading](name.scope(keys),validAfterTime,validBeforeTime)" \
        )
    IFS=$'\n' rows=($RESPONSE)
    for row in "${rows[@]}"
    do
        echo "$PROJECT,$NAME, $ACCOUNT_ID,$EMAIL,$DESCR,$row" >> $OUTFILE
        # IFS=$',' args=($row)
        # keyname=args[0]
        # created=args[1]
        # expires=args[2]
    done
  done
done


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接