Как использовать API Google Cloud (напрямую или с помощью клиентского SDK GCP PHP) для программного списка, добавления и удаления пользователей из проекта GCP?

Краткое резюме: у меня есть веб-приложение PHP, которое использует SDK клиента Google Cloud PHP для интеграции с Dialogflow. Это работает без проблем. Теперь у меня есть необходимость предоставить моим пользователям прямой доступ к панели инструментов GCP Dialogflow, и отчасти это означает, что они должны иметь возможность добавлять / удалять разрешения Dialogflow для пользователей из моего приложения. (По очевидным причинам я не хочу предоставлять им полные права доступа и разрешения IAM для проекта).

Судя по всему, разрешения обрабатываются отдельной клиентской библиотекой API Google для PHP.

Похоже, это API для перечисления существующих политик пользователей проекта: https://cloud.google.com/resource-manager/reference/rest/v1/projects/listOrgPolicies

Я считаю, что это API для добавления / удаления пользователей, но это не так очевидно: https://cloud.google.com/resource-manager/reference/rest/v1/projects/setIamPolicy

===

Эта проблема:

Однако, когда я запускаю пример кода, представленный в упомянутом выше API listOrgPolicies, я получаю следующую ошибку:

PHP Fatal error:  Uncaught Error: Class 'Google_Service_CloudResourceManager_ListOrgPoliciesRequest' not found

Я пробовал и composer require google/apiclient-services, и composer require google/apiclient-services:dev-master. И получил тот же результат.

===

Мои вопросы:

Это даже подходящие API для задачи?

Где найти библиотеки SDK для этих действий? (или, альтернативно, если у кого-то есть предложения о том, как выполнять эти задачи непосредственно в API, используя PHP cURL без SDK)

Я бы предпочел, чтобы все действия происходили на PHP, но если у вас есть рабочее решение, использующее какой-либо другой метод, язык или командную строку консоли, если оно может быть выполнено моим приложением, я могу работать с этим.

Заранее спасибо!


person Jambu Atchison    schedule 07.01.2021    source источник
comment
Установили ли вы эту библиотеку также, как указано в разделе комментариев в примере?   -  person Emil Gi    schedule 11.01.2021
comment
@EmilGi правильно   -  person Jambu Atchison    schedule 18.01.2021


Ответы (1)


Прежде чем перейти к ответу, убедитесь, что Resource Manager API включен. Это необходимо для подхода REST и программного.

Чтобы изменить привязки IAM для пользователя в данном проекте, необходимо вызвать две конечные точки, которые задокументированы здесь. Это будут:

  1. Чтобы получить текущую конфигурацию IAM: https://cloud.google.com/resource-manager/reference/rest/v1/projects/getIamPolicy.
  2. Чтобы установить новую политику IAM: https://cloud.google.com/resource-manager/reference/rest/v1/projects/setIamPolicy.

Между шагами 1 и 2 потребуется изменить json, возвращаемый первой конечной точкой, либо добавив пользователя с ролью по вашему выбору, либо удалив запись пользователя из него. Чтобы узнать, какая структура json требуется для добавления / удаления пользователей, я бы предложил изучить приведенную выше ссылку, а также изучить полезную нагрузку, возвращаемую первой командой.

Хотя вы можете напрямую вызвать REST api, вы также можете использовать интерфейс командной строки gcloud для выполнения таких операций. Поскольку кажется, что пользователи будут добавляться / удаляться один за другим, командная строка будет простым выбором, и она требует меньше настроек. Команды для обоих действий будут такими:

/ To add user role
gcloud projects add-iam-policy-binding PROJECT_ID --member=user:[email protected] --role=roles/viewer

/ To remove user role
gcloud projects remove-iam-policy-binding PROJECT_ID --member=user:[email protected] --role=roles/viewer

Третий вариант - сделать это программно. Хотя я хотел бы предоставить образец PHP, у меня недостаточно опыта работы с языком, тем не менее, ниже приведен сценарий Python, который позволяет добавлять / удалять роли. Он был загружен из Quickstart с небольшими изменениями и тесты, которые я провел, должны работать нормально.

# TODO: Install required libraries
# pip3 install --upgrade google-api-python-client google-auth google-auth-httplib2

import os

from google.oauth2 import service_account
import googleapiclient.discovery

def get_policy(crm_service, project_id, version=3):
    """Gets IAM policy for a project."""
    policy = (
        crm_service.projects()
        .getIamPolicy(
            resource=project_id,
            body={"options": {"requestedPolicyVersion": version}},
        )
        .execute()
    )
    print(policy)
    return policy


def set_policy(crm_service, project_id, policy):
    """Sets IAM policy for a project."""
    policy = (
        crm_service.projects()
        .setIamPolicy(resource=project_id, body={"policy": policy})
        .execute()
    )
    return policy


def initialize_service():
    """
    Initializes a Cloud Resource Manager service.
    The Environemnt variable GOOGLE_APPLICATION_CREDENTIALS must point to the service account key.json file
    """
    
    credentials = service_account.Credentials.from_service_account_file(
        filename=os.environ["GOOGLE_APPLICATION_CREDENTIALS"],
        scopes=["https://www.googleapis.com/auth/cloud-platform"],
    )
    
    crm_service = googleapiclient.discovery.build(
        "cloudresourcemanager", "v1", credentials=credentials
    )
    return crm_service


def modify_policy_add_role(crm_service, project_id, role, member):
    """Adds a new role binding to a policy."""

    policy = get_policy(crm_service, project_id)

    binding = None
    for b in policy["bindings"]:
        if b["role"] == role:
            binding = b
            break
    if binding is not None and member not in binding["members"]:
        binding["members"].append(member)
    else:
        binding = {"role": role, "members": [member]}
        policy["bindings"].append(binding)

    policy = set_policy(crm_service, project_id, policy)


def modify_policy_remove_member(crm_service, project_id, role, member):
    """Removes a  member from a role binding."""

    policy = get_policy(crm_service, project_id)

    # The try-except below handles the case where the role isn't in the IAM policy
    try:
        binding = next(b for b in policy["bindings"] if b["role"] == role)
    except StopIteration:
        print("The role is not included in the IAM policy. Can't remove user")
        raise KeyError

    if "members" in binding and member in binding["members"]:
        binding["members"].remove(member)

    set_policy(crm_service, project_id, policy)


if __name__ == '__main__':

    # TODO: Replace with your project ID
    project_id = "projectID"
    # TODO: Replace with the ID of your member in the form 'user:[email protected]'.
    member = "user:[email protected]"
    # TODO: Replace the role with the role you want to grant/remove
    role = "roles/logging.logWriter"

    # Initializes the client.
    crm_service = initialize_service()

    # Call modify_policy_add_role or modify_policy_remove_member as required
    modify_policy_add_role(crm_service, project_id, role, member)
    modify_policy_remove_member(crm_service, project_id, role, member)

person Happy-Monad    schedule 26.01.2021
comment
Спасибо! Теперь он работает. Я надеялся использовать JSON-ключ учетной записи службы проекта, но оказалось, что это невозможно для API политики IAM, они должны быть аутентифицированы с помощью OAuth конечным пользователем. - person Jambu Atchison; 28.01.2021