glamstack / google-cloud-sdk
Google Cloud SDK for Laravel
Requires
- php: ^8.0
- glamstack/google-auth-sdk: 2.5.25
- guzzlehttp/guzzle: ^7.4
- laravel/framework: ^9.13
- spatie/laravel-package-tools: ^1.9
- symfony/options-resolver: ^6.0
Requires (Dev)
- nunomaduro/collision: ^6.0
- nunomaduro/larastan: ^2.0.1
- orchestra/testbench: ^7.0
- pestphp/pest: ^1.21
- pestphp/pest-plugin-laravel: ^1.1
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
- phpunit/phpunit: ^9.5
- spatie/laravel-ray: ^1.26
This package is auto-updated.
Last update: 2024-09-05 00:51:53 UTC
README
概览
Google Cloud SDK 是一个由 GitLab IT Engineering 创建的开源 Composer 包,用于 GitLab Access Manager Laravel 应用程序,以连接到 Google Cloud API 端点。
免责声明:这不是由 Google 或 GitLab 产品和开发团队维护的官方包。这是一个我们作为公司价值观的一部分开源的 GitLab IT 部门内部工具。
请自行承担风险,并在遇到任何错误时创建问题。
我们不会维护社区功能请求路线图,但我们邀请您贡献,并且我们将乐意审查您的合并请求。
依赖项
注意:此包需要 glamstack/google-auth-sdk 包才能运行。这已在 composer.json 文件中配置为必需包,并在安装此包时自动加载。
维护者
名称 | GitLab 处理 |
---|---|
Dillon Wheeler | @dillonwheeler |
Jeff Martin | @jeffersonmartin |
工作原理
此包的目的不是提供 Google Cloud API 中每个端点的功能。
我们采取了更简单的方法,提供了一个通用的 ApiClient,它可以对您在 Google API 文档中找到的任何端点执行 GET
、POST
、PUT
、PATCH
和 DELETE
请求,并为您处理 API 响应、错误处理和分页。
这基于由 Guzzle HTTP 客户端提供的 Laravel HTTP 客户端的简洁性,为 Google API 响应提供“最后几行代码解析”,以改善开发人员体验。
我们对 GitLab Access Manager 经常使用的端点有额外的类和方法,我们将随着时间的推移对这些进行迭代。
安装
要求
要求 | 版本 |
---|---|
PHP | >=8.0 |
添加 Composer 包
此包使用 日历版本控制。
我们建议始终在您的 composer.json
文件中使用特定版本,并在假设最新版本适合您的项目之前,查看每个版本的 变更日志 中的破坏性更改。
composer require glamstack/google-cloud-sdk:2.5.25
如果您正在为此包做出贡献,请参阅 CONTRIBUTING 以获取配置带有符号链接的本地 composer 包的说明。
发布配置文件
php artisan vendor:publish --tag=glamstack-google-cloud
版本升级
如果您已升级到该软件包的新版本,您应该备份现有的配置文件,以避免您的自定义配置被覆盖。
cp config/glamstack-google-cloud.php config/glamstack-google-cloud.php.bak
php artisan vendor:publish --tag=glamstack-google-cloud
日历版本控制
GitLab IT 工程团队使用修改版的 日历版本控制(CalVer) 而不是 语义版本控制(SemVer)。CalVer 有 YY(例如,2021 => 21),但我们感觉版本 21.xx
不太直观。由于我们团队从 2021 年开始使用,我们决定只使用年份的最后一位整数(2021 => 1.x,2022 => 2.x,等等)。
版本号表示发布日期,格式为 vY.M.D
。
我们不使用语义版本控制的原因
- 我们持续向
main
/master
/production
发布,并在大多数版本中做出破坏性更改,因此对于语义向后兼容的版本号,对我们来说不太直观。 - 我们不希望讨论如何称呼我们的发布/里程碑,以及它是否是主要版本、次要版本还是修补程序版本。我们只是编写代码,编写变更日志,并在完成的那天发布。变更日志的发布日期成为标记的版本号(例如,
2022-02-01
是v2.2.1
)。我们可能对更大的版本号(例如,v2.2
)进行参考,但这仅用于每月里程碑规划和规范目的。所有代码标签都包含发布日期(例如,v2.2.1
)。 - 这使我们能够使用 GitLab CI/CD 自动化版本标记过程,基于管道作业运行的日期。
- 在计划更改窗口期间,我们无需担心与“保持最新版本”相关的差异和/或破坏性更改,即可更新使用此软件包的每个项目的
composer.json
文件到特定或新版本号。我们不维护任何分支或分歧分支。 - 我们的软件包使用您现有 Laravel 应用程序中的底层软件包,因此保持您的 Laravel 应用程序版本更新可以解决大多数安全问题。
初始化 SDK
API 客户端的初始化可以通过传递(字符串)连接密钥或传递(数组)连接配置来完成。
Google API 认证
该软件包使用 glamstack/google-auth-sdk 软件包来创建用于通过 Google JWT Web Token 认证与 Google Cloud API 端点。
有关 glamstack/google-auth-sdk 的更多信息,请参阅 Google Auth SDK README.md。
连接密钥
我们使用 连接密钥 的概念,它引用 config/glamstack-google-cloud.php
中的配置数组,允许您预先配置一个或多个 API 连接。
每个连接密钥都与 GCP 服务帐户 JSON 密钥相关联。这可以用来配置不同的认证范围连接和权限到您的 GCP 组织或不同的 GCP 项目(根据您使用的 API 调用)。这允许针对特定 API 调用进行最小权限,并且您还可以配置多个与同一 GCP 项目和具有不同权限级别的不同 API 令牌的连接。
示例连接密钥初始化
// Initialize the SDK using the `test` configuration from `glamstack-google-cloud.php`
$client = new Glamstack\GoogleCloud\ApiClient('test');
示例连接密钥配置
return [
'connections' => [
'test' => [
'project_id' => env('GOOGLE_CLOUD_TEST_PROJECT_ID'),
'api_scopes' => [
'https://www.googleapis.com/auth/ndev.clouddns.readwrite'
],
'json_key_file' => storage_path('keys/glamstack-google-cloud/test.json'),
'log_channels' => ['single']
]
]
]
动态连接配置数组
如果您不想预先配置连接,而是希望动态使用存储在数据库中的连接变量,您可以通过传递一个数组来传入所需的配置(参见示例连接配置数组初始化),在ApiClient
构造方法的第二个参数中使用connection_config
数组。
所需参数
键 | 类型 | 描述 |
---|---|---|
api_scopes | 数组 | API所需使用的API作用域数组 |
project_id | 字符串 | 在运行API调用的Google项目ID |
json_key_file_path | 字符串 | 选项1 - 提供一个指向.json 密钥文件的路径 |
json_key | 字符串 | 选项2 - 提供存储在数据库中的JSON密钥内容 |
在文件系统中使用JSON密钥文件
$client = new Glamstack\GoogleCloud\ApiClient(null, [
'api_scopes' => ['https://www.googleapis.com/auth/ndev.clouddns.readwrite'],
'json_key_file_path' => storage('keys/glamstack-google-cloud/gcp_project_1.json'),
'project_id' => 'example-project-123'
]);
在数据库中使用JSON密钥字符串
安全警告:您永远不应该将服务帐户密钥(JSON内容)作为变量提交到源代码中,以避免泄露您的GCP组织或项目的凭据。
建议在加密之前将JSON密钥转换为base 64编码的字符串,因为这是GCP服务帐户API用于privateKeyData
字段的格式。
// Get service account from your model (`GoogleServiceAccount` is an example)
$service_account = \App\Models\GoogleServiceAccount::where('id', '123456')->firstOrFail();
// Get JSON key string from database column that has an encrypted value
$json_key_string = decrypt(json_decode($service_account->json_key));
$client = new \Glamstack\GoogleCloud\ApiClient(null, [
'api_scopes' => ['https://www.googleapis.com/auth/ndev.clouddns.readwrite'],
'json_key' => $json_key_string,
'project_id' => 'example-project-123'
]);
以下示例显示了存储在数据库中的JSON密钥值。
// Get service account from your model (`GoogleServiceAccount` is an example)
$service_account = \App\Models\GoogleServiceAccount::where('id', '123456')->firstOrFail();
dd(decrypt(json_decode($service_account->json_key));
// {
// "type": "service_account",
// "project_id": "project_id",
// "private_key_id": "key_id",
// "private_key": "key_data",
// "client_email": "xxxxx@xxxxx.iam.gserviceaccount.com",
// "client_id": "123455667897654",
// "auth_uri": "https://#/o/oauth2/auth",
// "token_uri": "https://oauth2.googleapis.com/token",
// "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
// "client_x509_cert_url": "some stuff"
// }
端点
通用 REST 调用
您需要为每个使用的端点初始化API客户端并设置项目ID。
$project_id
变量用于文档和教育目的。您还可以在URL中嵌入项目ID,而不是定义变量。
$client = new Glamstack\GoogleCloud\ApiClient('test');
$project_id = config('glamstack-google-cloud.connections.test.project_id');
GET 请求
示例:[https://cloud.google.com/compute/docs/reference/rest/v1/addresses/list](https://cloud.google.com/compute/docs/reference/rest/v1/addresses/list)
$response = $client->rest()->get('https://compute.googleapis.com/compute/v1/projects/' . $project_id . '/regions/us-central1/addresses', []);
示例:[https://cloud.google.com/compute/docs/reference/rest/v1/addresses/get](https://cloud.google.com/compute/docs/reference/rest/v1/addresses/get)
$resource_id = 'string';
$response = $client->rest()->get('https://compute.googleapis.com/compute/v1/projects/' . $project_id . '/regions/us-central1/addresses/' . $resource_id, []);
POST 请求
示例:[https://cloud.google.com/compute/docs/reference/rest/v1/addresses/insert](https://cloud.google.com/compute/docs/reference/rest/v1/addresses/insert)
$request_data = [
'name' => 'string',
'description' => 'string',
'networkTier' => 'enum',
'ipVersion' => 'enum',
'addressType' => 'enum',
'subnetwork' => 'string',
'network' => 'string'
];
$response = $client->rest()->post('https://compute.googleapis.com/compute/v1/projects/' . $project_id . '/regions/us-central1/addresses', $request_data);
PATCH和PUT请求
某些PATCH请求使用字段掩码来提供要更新的字段列表。这可能需要根据API端点文档添加到
$request_data
数组中。
$resource_id = 'string';
// This is a different style of using variables that may be helpful for some
// resources that have a full URI returned with the `POST` method
$resource_uri = 'projects/' . $project_id . '/path/to/endpoint/' . $resource_id;
$request_data = [
'description' => 'string',
];
$response = $client->rest()->patch('https://compute.googleapis.com/compute/v1/' . $resource_uri, $request_data);
$response = $client->rest()->put('https://compute.googleapis.com/compute/v1/' . $resource_uri, $request_data);
DELETE 请求
示例:[https://cloud.google.com/compute/docs/reference/rest/v1/addresses/delete](https://cloud.google.com/compute/docs/reference/rest/v1/addresses/delete)
$response = $client->rest()->delete('https://compute.googleapis.com/compute/v1/projects/' . config('glamstack-google-cloud.connections.test.project_id') . '/regions/us-central1/addresses/{resourceId}');
云DNS - 管理区域
查看API文档以了解更多信息。
$client = new Glamstack\GoogleCloud\ApiClient('test');
获取区域列表
$response = $client->dns()->managedZone()->list();
获取特定区域
$response = $client->dns()->managedZone()->get('testing-zone');
创建区域
$response = $client->dns()->managedZone()->create([
'name' => 'testing-zone-3',
'dns_name' => 'testing-zone-3.example.com.',
'visibility' => 'private',
'dnssec_config_state' => 'off',
'description' => 'Testing zone 3 by SDK',
]);
删除区域
$response = $client->dns()->managedZone()->delete('testing-zone-3');
云DNS - 记录集
查看API文档以了解更多信息。
$client = new Glamstack\GoogleCloud\ApiClient('test');
获取记录列表
$response = $client->dns()->recordSet()->list('testing-zone');
获取特定记录
$response = $client->dns()->recordSet()->get(
'testing-zone',
'testingmail.testingzone.example.com.',
'CNAME'
);
创建记录
$response = $client->dns()->recordSet()->create('testing-zone', [
'name' => 'testingmail.testingzone.example.com.',
'type' => 'CNAME',
'ttl' => 300,
'rrdatas' => ['mail.testingzone.example.com.']
]
);
删除记录
$response = $client->dns()->RecordSet()->delete(
'testing-zone',
'testingmail.testingzone.example.com.',
'CNAME'
);
日志配置
默认情况下,我们使用在您的应用程序的config/logging.php
文件中配置的single
通道发送所有日志。这会将所有Google Cloud日志消息发送到storage/logs/laravel.log
文件。
如果您希望将Google Cloud日志显示在单独的日志文件中,以便更容易地分类而不包含无关日志消息,您可以创建一个自定义日志通道。例如,我们建议使用glamstack-google-cloud
的值,但您可以选择任何您喜欢的名称。
将自定义日志通道添加到config/logging.php
。
创建日志通道
'channels' => [
// Add anywhere in the `channels` array
'glamstack-google-cloud' => [
'name' => 'glamstack-google-cloud',
'driver' => 'single',
'level' => 'debug',
'path' => storage_path('logs/glamstack-google-cloud.log'),
],
],
更新channels.stack.channels
数组以包括自定义通道的数组键(例如glamstack-google-cloud
)。请确保将glamstack-google-cloud
添加到现有数组值中,而不是替换现有值。
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single','slack','glamstack-google-cloud'],
'ignore_exceptions' => false,
],
],
安全最佳实践
Google API作用域
与软件包一起加载的默认配置文件展示了API作用域配置的示例。请务必遵循最小权限原则。所有Google作用域都可以在这里找到:这里。
您可以通过参考特定REST端点的Google API Explorer文档来了解更多关于所需授权作用域的信息。
JSON密钥存储
请不要将JSON密钥文件存储在未包含在.gitignore
文件中的任何位置。这是为了避免将您的凭证提交到您的存储库(秘密泄露)
建议将每个JSON API密钥的副本存储在您首选的密码管理器(例如1Password,LastPass等)和/或秘密库(例如HashiCorp Vault,Ansible等)中。
日志输出
有效
[2022-05-10 15:44:58] testing.INFO: Glamstack\GoogleCloud\Resources\BaseClient::GETREQUEST 200 https://dns.googleapis.com/dns/v1/projects/example-project/managedZones/testing-zone/rrsets/testingexample.testingzone.example.com./CNAME {"api_endpoint":"https://dns.googleapis.com/dns/v1/projects/example-project/managedZones/testing-zone/rrsets/testingexample.testingzone.example.com./CNAME","api_method":"GLAMSTACK\\GOOGLECLOUD\\RESOURCES\\BASECLIENT::GETREQUEST","class":"Glamstack\\GoogleCloud\\Resources\\BaseClient","event_type":"google-cloud-api-response-info","message":"Glamstack\\GoogleCloud\\Resources\\BaseClient::GETREQUEST 200 https://dns.googleapis.com/dns/v1/projects/example-project/managedZones/testing-zone/rrsets/testingexample.testingzone.example.com./CNAME","status_code":200}
认证失败
[2022-05-09 16:45:07] testing.INFO: Google OAuth2 Authentication Failed {"calling_method":"__CONSTRUCT","class":"Glamstack\\GoogleCloud\\Resources\\BaseClient","event_type":"google-auth-api-response-info","message":"Google OAuth2 Authentication Failed"}
测试套件
此SDK使用Pest框架编写的功能和单元测试。
运行测试
您可以从项目目录中运行SDK中的所有测试。
cd ~/Sites/google-cloud-sdk
./vendor/bin/pest
或者,您可以使用内置的composer命令来运行测试。
composer test
您还可以使用覆盖率报告来运行测试。
composer test-coverage
问题跟踪和错误报告
请访问我们的问题跟踪器并创建一个问题或对现有问题进行评论。
贡献
有关如何贡献的更多信息,请参阅CONTRIBUTING.md。