使用 CLI 预配 API Hub

本页面适用于 ApigeeApigee Hybrid

本部分介绍如何使用命令行预配 API Hub。

步骤摘要

预配步骤如下:

  1. 验证您是否满足 API Hub 前提条件
  2. 第 1 步:启用 API。Apigee 要求您启用多个 Google Cloud API。
  3. 第 2 步:定义环境变量。环境变量有助于确保在运行命令时保持一致性。
  4. 第 3 步:创建服务账号和 CMEK服务账号Google Cloud 客户端库用来向 Google Cloud API 进行身份验证。由于内部 API 的相关信息可能被视为敏感信息,因此 Apigee 要求使用 CMEK 来加密和解密(保护)静态数据。CMEK 必须与实例位置位于同一区域。
  5. 第 4 步:创建实例。实例是存储您的项目和相关服务的位置。
  6. 检查实例状态(可选)。由于创建实例可能需要一些时间,因此请使用此命令检查状态。
  7. 删除实例(可选)。如果您需要移除实例,请使用此命令。
  8. 检查操作状态(可选)。使用此命令检查长时间运行的操作的状态。

第 1 步:启用 API

如需使用 API Hub,您必须为项目启用以下 API:

  • Apigee Registry API:API Hub 与 API Registry 交互,用于查看和管理贵组织的 API。
  • Cloud Key Management Service (KMS) API:允许客户管理加密密钥并使用这些密钥执行加密操作。
  • Service Usage API:在 Google Cloud Platform 上启用服务使用者希望使用的服务,列出可用或已启用的服务,或停用服务使用者不再使用的服务。

您可以使用 Google Cloud 控制台界面或 CLI 来启用 API。

控制台

要使用界面启用 API,请在 Google Cloud 控制台中执行以下步骤:

  1. 启用 Apigee Registry API

    转到“启用 Apigee Registry API”

    点击启用

    Google Cloud 会为您的 Google Cloud 项目启用该 API。

  2. 启用 Cloud Key Management Service (KMS) API

    转到“启用 Cloud KMS API”

    点击启用

    Google Cloud 会为您的 Google Cloud 项目启用该 API。

  3. 启用 Service Usage API

    转到“启用 Service Usage API”

    点击启用

    Google Cloud 会为您的 Google Cloud 项目启用该 API。

  4. 要确认您已启用 API,请执行以下操作:

    转到“已启用的 API 和服务”

    您刚添加的 API 会显示在已启用 API 列表中:

    • Apigee Registry API
    • Cloud Key Management Service (KMS) API
    • Service Usage API

gcloud

  1. 执行以下命令:

    gcloud services enable \
        apigeeregistry.googleapis.com \
        cloudkms.googleapis.com \
        serviceusage.googleapis.com --project=PROJECT_ID
    

    其中,PROJECT_ID 是您的 Google Cloud 控制台项目的名称。

  2. (可选)如需查看您的工作,请使用 services list 命令显示所有已启用的 API:

    gcloud services list
    

    该响应会显示所有已启用的服务,包括您刚刚启用的 API。

第 2 步:定义环境变量

使用环境变量可确保一致性,并且可让您在后续步骤中更轻松地按照文档执行操作。

  1. 定义以下环境变量,并将动态变量替换为实际值:
    export TOKEN=$(gcloud auth print-access-token)
    
    # ----- Set key_ring_name and key_name to values that will help you identify the API hub encryption key in future. -----
    export KEY_RING_NAME=YOUR_KEY_RING_NAME
    export KEY_NAME=YOUR_KEY_NAME
    
    export PROJECT_ID=YOUR_PROJECT_ID
    export RUNTIME_LOCATION=YOUR_RUNTIME_LOCATION
    
    # -----If you already have a CMEK, define this environment variable-----
    export CMEK_KEY_ID=YOUR_CMEK_KEY_ID
    

    其中:

    • TOKEN 是指对 Apigee Registry API 调用进行身份验证和授权的令牌。该变量应该以不记名令牌的形式在身份验证标头中传递。请注意,令牌会在一段时间后过期,并且在令牌过期后,您只需使用同一命令即可重新生成令牌。如需了解详情,请参阅 print-access-token 命令的参考页面。
    • KEY_RING_NAME 是用于标识加密密钥环的密钥环名称。
    • KEY_NAME 是用于标识 API Hub 加密密钥的密钥名称。
    • PROJECT_ID 是您在前提条件中创建的 Cloud 项目 ID。
    • RUNTIME_LOCATION 是您稍后创建的 Apigee 实例所在的物理位置。CMEK 密钥需要与运行时位置位于同一区域。

    • CMEK_KEY_ID 是客户管理的加密密钥的密钥 ID。目前不支持密钥轮替。

      密钥 ID 的语法如下所示(类似于文件路径):

      projects/PROJECT_ID/locations/RUNTIME_LOCATION/keyRings/KEY_RING_NAME/cryptoKeys/KEY_NAME
      
  2. (可选)通过回送您刚刚设置的值来检查您的工作。请注意,如需在命令中使用变量,请在变量名称前面加上美元符号 ($)。
    echo $TOKEN
    echo $KEY_RING_NAME
    echo $KEY_NAME
    echo $PROJECT_ID
    echo $RUNTIME_LOCATION
    
    # -----If you already have a CMEK-----
    echo $CMEK_KEY_ID
    
    

第 3 步:创建服务账号和 CMEK

本部分介绍了如何创建服务账号以及加密密钥密钥环和密钥。

  1. 为您的项目创建 Apigee Registry 每个产品、每个项目的服务账号:

    gcloud beta services identity create --service=apigeeregistry.googleapis.com --project=$PROJECT_ID
    

    返回的服务账号如下所示:

    service-755582297973@gcp-sa-apigeeregistry.iam.gserviceaccount.com
    
  2. 将创建的服务账号放在变量中:

    export SERVICE_ACCOUNT=YOUR_SERVICE_ACCOUNT
    
  3. 按照以下步骤使用 KMS 创建 CMEK,或使用现有 KMS 密钥。CMEK 密钥需要与运行时位置位于同一区域。

    1. 创建密钥环:

      gcloud kms keyrings create $KEY_RING_NAME \
        --location $RUNTIME_LOCATION \
        --project $PROJECT_ID
      
    2. 创建密钥:

      gcloud kms keys create $KEY_NAME \
        --keyring $KEY_RING_NAME \
        --location $RUNTIME_LOCATION \
        --purpose "encryption" \
        --project $PROJECT_ID
      
    3. 验证密钥已创建。创建密钥可能需要几分钟时间。如果此命令返回空列表,请重试。密钥出现后,您可以继续下一步:

      gcloud kms keys list \
        --keyring $KEY_RING_NAME \
        --location $RUNTIME_LOCATION \
        --project $PROJECT_ID
      

      返回的密钥如下所示:

      projects/my-project/locations/us-west1/keyRings/my-key-ring-name/cryptoKeys/my-key-name
      
    4. 将创建的密钥放在变量中:

      export CMEK_KEY_ID=projects/PROJECT_ID/locations/RUNTIME_LOCATION/keyRings/KEY_RING_NAME/cryptoKeys/KEY_NAME
      
  4. 向 CMEK 上的服务账号授予权限:

    gcloud kms keys add-iam-policy-binding $KEY_NAME \
      --location $RUNTIME_LOCATION \
      --keyring $KEY_RING_NAME \
      --member serviceAccount:$SERVICE_ACCOUNT \
      --role roles/cloudkms.cryptoKeyEncrypterDecrypter \
      --project $PROJECT_ID
    
    
  5. 验证您的服务账号是否具有对 CMEK 的 roles/cloudkms.cryptoKeyEncrypterDecrypter 权限。

    gcloud kms keys get-iam-policy $CMEK_KEY_ID
    

第 4 步:创建实例

在本部分中,您将创建一个 API Hub 实例。 每个项目只能有一个实例。

示例请求

curl https://apigeeregistry.googleapis.com/v1/projects/$PROJECT_ID/locations/$RUNTIME_LOCATION/instances?instance_id=default \
  -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  --data-raw '{
    "config": {
      "cmek_key_name": "'"$CMEK_KEY_ID"'"
  }
}'

示例响应

{
  "name": "projects/my-project/locations/us-central1/operations/operation-1646987534895-5d9ed2af7889a-b4d376e8-14964abc",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.apigeeregistry.v1.OperationMetadata",
    "createTime": "2022-03-11T08:32:14.950522187Z",
    "target": "projects/my-project/locations/us-central1/instances/default",
    "verb": "create",
    "requestedCancellation": false,
    "apiVersion": "v1"
  },
  "done": false
}

常见错误 - 输入数据错误

HTTP 状态代码: 400 Bad Request
错误消息: Instance is a singleton, and instance_id must be set to "default".
可能的原因: instance_id 设置为 default 以外的任何值。
解决方案: default 用作 instance_id
HTTP 状态代码: 400 Bad Request
错误消息: global is not a supported location to create Instance.
可能的原因: global 设置为位置。
解决方案: 使用上面列出的一个受支持的运行时位置。
HTTP 状态代码: 401 Unauthorized
错误消息: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential.
可能的原因: 身份验证令牌无效。
解决方案: 请求令牌格式可能有误或已过期。通过运行 token="$(gcloud auth print-access-token)" 并将 Authorization: Bearer ${token} 作为标头传递来重新生成身份验证令牌。
HTTP 状态代码: 403 PERMISSION_DENIED
错误消息: Location RUNTIME_LOCATION is not found or access is unauthorized.
可能的原因: 将位置设置为不受支持的位置。
解决方案: 使用上面列出的一个受支持的运行时位置。
HTTP 状态代码: 400 Bad Request
错误消息: Instance.config.cmek_key_name must be provided to create Instance.
可能的原因: 数据中未提供 cmek_key_name
解决方案: 提供 CMEK 名称。如需了解详细说明,请参阅创建服务账号和 CMEK
HTTP 状态代码: 400 Bad Request
错误消息: Invalid key format: a valid key should be in the form of projects/PROJECT/locations/us-central1/keyRings/KEYRING/cryptoKeys/CRYPTOKEY.
可能的原因: cmek_key_name 格式有误。
解决方案: 更正密钥格式。
HTTP 状态代码: 400 Bad Request
错误消息: CMEK key location needs to match the location of instance creation.
可能的原因: CMEK 位于其他位置。
解决方案: 更正 CMEK 的位置。
HTTP 状态代码: 400 Bad Request
错误消息: Apigee Registry service account must have roles/cloudkms.cryptoKeyEncrypterDecrypter permission on the CMEK key.
可能的原因: Apigee 服务账号缺少对 CMEK 的权限。请注意,我们只知道该服务账号没有必要的权限。密钥可能根本不存在,但我们无法确定。
解决方案: 验证密钥是否存在,以及 Apigee Registry 服务账号是否具有对密钥的所需权限

常见错误 - 状态错误

HTTP 状态代码: 400 Bad Request
错误消息:

如果实例处于活跃状态:

Instance is ACTIVE at SOME_LOCATION. It cannot be created again.

如果实例不处于活跃状态:

Instance has state STATE at SOME_LOCATION. It cannot be created.

可能的原因: 当实例已存在或正在某个位置创建时,调用此 API。
解决方案: 如果此 API 是被意外触发的,请忽略该错误。如果它是合法调用,而您确实想要在此位置创建实例,请先在当前实例位置调用 DeleteInstance

获取实例

本部分介绍了如何获取与项目关联的 API Hub 运行时实例的详细信息(区域、状态等)。

示例请求

curl https://apigeeregistry.googleapis.com/v1/projects/$PROJECT_ID/locations/$RUNTIME_LOCATION/instances/default \
  -X GET \
  -H "Authorization: Bearer $TOKEN"

示例响应 - 实例创建正在进行

{
  "name": "projects/my-project/locations/us-central1/instances/default",
  "createTime": "2022-03-11T08:32:14.944703257Z",
  "updateTime": "2022-03-11T08:32:14.944703257Z",
  "state": "CREATING",
  "stateMessage": "Creating instance...\nDetails: projects/PROJECT_ID/locations/RUNTIME_LOCATION/operations/operation-1646987534895-5d9ed2af7889a-b4d376e8-14964abc",
  "config": {
    "location": "us-central1",
    "cmekKeyName": "projects/PROJECT/locations/RUNTIME_LOCATION/keyRings/KEYRING/cryptoKeys/KEY""
  }
}

示例响应 - 实例创建已完成

{
  "name": "projects/myproject/locations/us-central1/instances/default",
  "createTime": "2022-03-11T08:32:14.944703257Z",
  "updateTime": "2022-03-11T08:56:31.087709218Z",
  "config": {
    "location": "us-central1",
    "cmekKeyName": "projects/my-project/locations/us-central1/keyRings/apihub-key-ring/cryptoKeys/apihub-key"
  },
  "state": "ACTIVE",
  "stateMessage": "Instance is active and ready to use."
}

常见错误

HTTP 状态代码: 404 Not Found
错误消息: Resource was not found.
可能的原因: 在实例不存在于的位置调用此 API。
解决方案: 先调用 CreateInstance API,然后再在要创建实例的位置调用 GetInstance API。如果实例已创建,但您不知道位置,请在任意位置调用 CreateInstance API,该操作会失败并显示消息,提供有关实例位置的提示。

删除实例

本部分介绍了如何删除实例。

示例请求

curl https://apigeeregistry.googleapis.com/v1/projects/$PROJECT_ID/locations/$RUNTIME_LOCATION/instances/default \
  -X DELETE \
  -H "Authorization: Bearer $TOKEN"

示例响应

{
  "name": "projects/my-project/locations/us-central1/operations/operation-1646987534895-5d9ed2af7889a-b4d376e8-14964abc",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.apigeeregistry.v1.OperationMetadata",
    "createTime": "2022-03-11T08:32:14.950522187Z",
    "target": "projects/my-project/locations/us-central1/instances/default",
    "verb": "delete",
    "apiVersion": "v1"
  },
  "done": false
}

常见错误

HTTP 状态代码: 404 Not Found
错误消息: Resource was not found.
可能的原因: 在实例不存在于的位置调用此 API。
解决方案: 仅在实例为 ACTIVEFAILED 的位置调用 DeleteInstance
HTTP 状态代码: 400 Bad Request
错误消息: Instance must be ACTIVE or FAILED to be deleted. Current state: STATE.
可能的原因: 在实例状态不是 ACTIVEFAILED 的位置调用此 API。
解决方案: 仅在实例为 ACTIVEFAILED 的位置调用 DeleteInstance

获取操作

本部分介绍了如何检查操作状态。当操作需要很长时间才能完成 (LRO) 时,API 会返回操作 ID。使用操作 ID 调用 GetOperation 会返回操作状态。

示例请求

curl https://apigeeregistry.googleapis.com/v1/projects/$PROJECT_ID/locations/$RUNTIME_LOCATION/operations/OPERATION_ID \
  -X GET \
  -H "Authorization: Bearer $TOKEN"

其中 OPERATION_ID 是 LRO 返回的值(如创建实例中所述),格式为 operation-1650479361714-5dd1a2c1068bf-464fac6b-18eeb734

示例响应 - 实例创建正在进行

{
  "name": "projects/my-project/locations/us-central1/operations/operation-1646987534895-5d9ed2af7889a-b4d376e8-14964abc",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.apigeeregistry.v1.OperationMetadata",
    "createTime": "2022-03-11T08:32:14.950522187Z",
    "target": "projects/my-project/locations/us-central1/instances/default",
    "verb": "create",
    "requestedCancellation": false,
    "apiVersion": "v1"
  },
  "done": false
}

示例响应 - 实例创建已完成

{
  "name": "projects/my-project/locations/us-central1/operations/operation-1646987534895-5d9ed2af7889a-b4d376e8-14964abc",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.apigeeregistry.v1.OperationMetadata",
    "createTime": "2022-03-11T08:32:14.950522187Z",
    "endTime": "2022-03-11T08:56:31.069701960Z",
    "target": "projects/my-project/locations/us-central1/instances/default",
    "verb": "create",
    "requestedCancellation": false,
    "apiVersion": "v1"
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.cloud.apigeeregistry.v1.Instance",
    "name": "projects/my-project/locations/us-central1/instances/default",
    "createTime": "2022-03-11T08:32:14.944703257Z",
    "updateTime": "2022-03-11T08:56:31.069701960Z",
    "config": {
      "location": "us-central1",
      "cmekKeyName": ""projects/PROJECT/locations/RUNTIME_LOCATION/keyRings/KEYRING/cryptoKeys/KEY""
    },
    "state": "ACTIVE",
    "stateMessage": "Instance is active and ready to use."
  }
}

示例响应 - 实例删除已完成

{
  "name": "projects/my-project/locations/us-east1/operations/operation-1647669637561-5da8bfb743b86-4af586a4-83c04472",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.apigeeregistry.v1.OperationMetadata",
    "createTime": "2022-03-19T06:00:38.046462309Z",
    "endTime": "2022-03-19T06:01:01.382751041Z",
    "target": "projects/my-project/locations/us-east1/instances/default",
    "verb": "delete",
    "apiVersion": "v1"
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.protobuf.Empty"
  }
}

后续步骤

如需了解有关如何开始使用 API Hub 的一些提示,请参阅后续步骤