feat(secretmanager): Add Cloud SQL managed-rotation samples - #2335
suvidha-malaviya wants to merge 2 commits into
Conversation
|
Here is the summary of changes. You are about to add 7 region tags.
This comment is generated by snippet-bot.
|
There was a problem hiding this comment.
Code Review
This pull request introduces new PHP samples and integration tests for Secret Manager regional and global secret types, specifically focusing on Cloud SQL managed rotation. It also adds a comprehensive testing guide in TESTING_cloudsql_managed_rotation.md and updates composer.json dependencies. The feedback highlights opportunities to improve test robustness and prevent resource leaks. Specifically, it is recommended to use PHPUnit's @Depends annotations to explicitly declare execution order for tests that rely on shared state, and to move the grantCloudSqlRole calls inside the try blocks so that the finally blocks are guaranteed to clean up and delete secrets even if the IAM grant fails.
| } | ||
| } | ||
|
|
||
| public function testGetRegionalSecretType() |
There was a problem hiding this comment.
The test testGetRegionalSecretType implicitly depends on testCreateSecretWithCloudSqlCredentials having already run to create the secret self::$testSecretCloudSqlToCreateName. Relying on the declaration order of tests can lead to flaky or failing tests if PHPUnit is configured to run tests in a different order (e.g., using --order-by or in parallel). Adding a @depends annotation explicitly declares this dependency, ensuring correct execution order and skipping the dependent test if the parent test fails.
/**
* @depends testCreateSecretWithCloudSqlCredentials
*/
public function testGetRegionalSecretType()| $this->assertSame(SecretType::ACCESS_KEY, $secret->getSecretType()); | ||
| } | ||
|
|
||
| public function testGetSecretType() |
There was a problem hiding this comment.
The test testGetSecretType implicitly depends on testCreateSecretWithType having already run to create the secret self::$testSecretWithTypeToCreateName. Relying on the declaration order of tests can lead to flaky or failing tests if PHPUnit is configured to run tests in a different order. Adding a @depends annotation explicitly declares this dependency, ensuring correct execution order and skipping the dependent test if the parent test fails.
/**
* @depends testCreateSecretWithType
*/
public function testGetSecretType()| $secret = self::createCloudSqlCredentialsSecret(); | ||
| $member = $secret->getPolicyMember()->getIamPolicyUidPrincipal(); | ||
| self::grantCloudSqlRole($member); | ||
|
|
||
| try { | ||
| $name = self::$client->parseName($secret->getName()); |
There was a problem hiding this comment.
If self::grantCloudSqlRole($member) throws an exception (for example, due to API rate limits, network issues, or transient IAM errors), the execution will halt before entering the try block. As a result, the newly created secret $secret will never be deleted, leading to orphaned resources in the GCP project. To prevent resource leaks, grantCloudSqlRole should be moved inside the try block so that the finally block is guaranteed to run and clean up the secret.
$secret = self::createCloudSqlCredentialsSecret();
$member = $secret->getPolicyMember()->getIamPolicyUidPrincipal();
try {
self::grantCloudSqlRole($member);
$name = self::$client->parseName($secret->getName());| $secret = self::createCloudSqlCredentialsSecret(); | ||
| $member = $secret->getPolicyMember()->getIamPolicyUidPrincipal(); | ||
| self::grantCloudSqlRole($member); | ||
|
|
||
| try { | ||
| $name = self::$client->parseName($secret->getName()); |
There was a problem hiding this comment.
If self::grantCloudSqlRole($member) throws an exception, the execution will halt before entering the try block, leaking the newly created secret. Moving grantCloudSqlRole inside the try block ensures that the finally block always runs to clean up the secret.
$secret = self::createCloudSqlCredentialsSecret();
$member = $secret->getPolicyMember()->getIamPolicyUidPrincipal();
try {
self::grantCloudSqlRole($member);
$name = self::$client->parseName($secret->getName());| $secret = self::createCloudSqlCredentialsSecret(); | ||
| $member = $secret->getPolicyMember()->getIamPolicyUidPrincipal(); | ||
| self::grantCloudSqlRole($member); | ||
|
|
||
| try { | ||
| $name = self::$client->parseName($secret->getName()); |
There was a problem hiding this comment.
If self::grantCloudSqlRole($member) throws an exception, the execution will halt before entering the try block, leaking the newly created secret. Moving grantCloudSqlRole inside the try block ensures that the finally block always runs to clean up the secret.
$secret = self::createCloudSqlCredentialsSecret();
$member = $secret->getPolicyMember()->getIamPolicyUidPrincipal();
try {
self::grantCloudSqlRole($member);
$name = self::$client->parseName($secret->getName());…amples Adds Cloud SQL managed-rotation samples for regional secrets (create/enable/rotate/schedule/get-type) plus secret-type samples for global secrets (create-with-type/get-type), ported from the completed Python reference implementation. Bumps google/cloud-secret-manager to ^2.4.0, the minimum version with Cloud SQL managed-rotation support.
9e79149 to
d655ae6
Compare
- Add @Depends annotations so testGetRegionalSecretType/testGetSecretType explicitly declare their dependency on the test that creates their secret, instead of relying on declaration order. - Move grantCloudSqlRole() inside the try block in the three Cloud SQL rotation tests so the secret is still cleaned up in finally if the grant itself throws.
Regional (Cloud SQL managed rotation):
create_regional_secret_with_cloud_sql_credentials— creates a secret restricted to theCLOUD_SQL_DB_CREDENTIALStypeenable_regional_secret_managed_rotation— links the secret to a Cloud SQL instance/user, creates version 1rotate_regional_secret— triggers an on-demand rotationupdate_regional_secret_with_managed_rotation_schedule— reconfigures the recurring rotation schedule on a secret that already has managed rotation enabledget_regional_secret_type— reads back a regional secret's secret typeGlobal (secret-type restriction, not specific to Cloud SQL):
create_secret_with_type— creates a secret restricted to a given secret type (e.g.ACCESS_KEY,CERTIFICATE,OTHER_DB_CREDENTIALS,OTHER;CLOUD_SQL_DB_CREDENTIALSis reserved for regional secrets going through managed rotation)get_secret_type— reads back a secret's secret typeTest coverage added for all seven samples in
regionalsecretmanagerTest.phpandsecretmanagerTest.php. The Cloud SQL fixtures (testEnableRegionalSecretManagedRotation,testRotateRegionalSecret,testUpdateRegionalSecretWithManagedRotationSchedule) each grantroles/cloudsql.adminto their own freshly-created secret's principal before running, and revoke it again in teardown, since this grant is per-secret with no wildcard mechanism.Bumps
google/cloud-secret-managerto^2.4.0, the minimum version with Cloud SQL managed-rotation support.Additional test-project requirements:
sqladmin.googleapis.com)CLOUD_SQL_INSTANCE/CLOUD_SQL_USERenv varsresourcemanager.projects.getIamPolicy/setIamPolicyon the test project (e.g.roles/resourcemanager.projectIamAdmin), in addition to Secret Manager and Cloud SQL permissions already required