diff --git a/storage/src/delete_ip_filtering_rules.php b/storage/src/delete_ip_filtering_rules.php new file mode 100644 index 000000000..fd8136750 --- /dev/null +++ b/storage/src/delete_ip_filtering_rules.php @@ -0,0 +1,63 @@ +bucket($bucketName); + + $info = $bucket->info(); + if (!isset($info['ipFilter'])) { + printf('No IP Filter configuration found for bucket %s.' . PHP_EOL, $bucketName); + return; + } + + $ipFilter = $info['ipFilter']; + if (isset($ipFilter['publicNetworkSource']['allowedIpCidrRanges'])) { + $ranges = $ipFilter['publicNetworkSource']['allowedIpCidrRanges']; + $ranges = array_filter($ranges, function ($range) { + return $range !== '1.2.3.0/24'; + }); + $ipFilter['publicNetworkSource']['allowedIpCidrRanges'] = array_values($ranges); + } + + $bucket->update(['ipFilter' => $ipFilter]); + + printf('Specific IP filtering rules deleted for bucket %s' . PHP_EOL, $bucketName); +} +# [END storage_delete_ip_filtering_rules] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/storage/src/disable_ip_filtering.php b/storage/src/disable_ip_filtering.php new file mode 100644 index 000000000..7c7104395 --- /dev/null +++ b/storage/src/disable_ip_filtering.php @@ -0,0 +1,52 @@ +bucket($bucketName); + + $bucket->update([ + 'ipFilter' => [ + 'mode' => 'Disabled' + ] + ]); + + printf('Disabled IP filtering Rules for bucket %s' . PHP_EOL, $bucketName); +} +# [END storage_disable_ip_filtering] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/storage/src/enable_ip_filtering.php b/storage/src/enable_ip_filtering.php new file mode 100644 index 000000000..fc139b45c --- /dev/null +++ b/storage/src/enable_ip_filtering.php @@ -0,0 +1,67 @@ +bucket($bucketName); + + $ipFilter = [ + 'mode' => 'Enabled', + 'allowAllServiceAgentAccess' => true, + 'publicNetworkSource' => [ + 'allowedIpCidrRanges' => ['1.2.3.0/24'] + ], + 'vpcNetworkSources' => [ + [ + 'network' => sprintf('projects/%s/global/networks/default', $projectId), + 'allowedIpCidrRanges' => ['10.0.0.0/24'] + ] + ] + ]; + + $info = $bucket->update(['ipFilter' => $ipFilter]); + + printf( + 'Enabled IP filtering Rules for the Bucket: %s' . PHP_EOL, + $bucketName + ); +} +# [END storage_enable_ip_filtering] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/storage/src/get_ip_filtering.php b/storage/src/get_ip_filtering.php new file mode 100644 index 000000000..6ab75a631 --- /dev/null +++ b/storage/src/get_ip_filtering.php @@ -0,0 +1,77 @@ +bucket($bucketName); + + $info = $bucket->info(); + + if (!isset($info['ipFilter'])) { + printf('Bucket %s has no IP Filter configured.' . PHP_EOL, $bucketName); + return; + } + + $ipFilter = $info['ipFilter']; + + printf('IP Filter Configuration for the Bucket %s:' . PHP_EOL, $bucketName); + printf('Mode: %s' . PHP_EOL, $ipFilter['mode']); + + printf('Allow All Service Agent Access: %s' . PHP_EOL, var_export($ipFilter['allowAllServiceAgentAccess'], true)); + + if (isset($ipFilter['publicNetworkSource']['allowedIpCidrRanges'])) { + printf('Allowed Public CIDR Ranges:' . PHP_EOL); + foreach ($ipFilter['publicNetworkSource']['allowedIpCidrRanges'] as $range) { + printf('- %s' . PHP_EOL, $range); + } + } + + printf('Allow Cross Organization VPCs Access: %s' . PHP_EOL, var_export($ipFilter['allowCrossOrgVpcs'], true)); + + if (isset($ipFilter['vpcNetworkSources'])) { + printf('Allowed VPC Network:' . PHP_EOL); + foreach ($ipFilter['vpcNetworkSources'] as $vpcNetwork) { + printf('- Network: %s' . PHP_EOL, $vpcNetwork['network']); + if (isset($vpcNetwork['allowedIpCidrRanges'])) { + printf('Allowed VPC CIDR Ranges: %s' . PHP_EOL, implode(', ', $vpcNetwork['allowedIpCidrRanges'])); + } + } + } +} +# [END storage_get_ip_filtering] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/storage/src/list_buckets_ip_filtering.php b/storage/src/list_buckets_ip_filtering.php new file mode 100644 index 000000000..6c734472c --- /dev/null +++ b/storage/src/list_buckets_ip_filtering.php @@ -0,0 +1,53 @@ + $projectId + ]); + + printf('Buckets:' . PHP_EOL); + foreach ($storage->buckets() as $bucket) { + $info = $bucket->info(); + $mode = $info['ipFilter']['mode'] ?? 'Not Configured'; + + printf('Bucket Name: %s, IP Filtering Mode: %s' . PHP_EOL, $bucket->name(), $mode); + } +} +# [END storage_list_buckets_ip_filtering] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/storage/test/storageTest.php b/storage/test/storageTest.php index 93ff1aa04..800883998 100644 --- a/storage/test/storageTest.php +++ b/storage/test/storageTest.php @@ -1271,6 +1271,98 @@ public function testSetClientEndpoint() $this->assertStringContainsString('Storage Client initialized.', $output); } + public function testIpFilteringLifecycle() + { + $bucket = self::$storage->createBucket(uniqid('php-ip-filter-')); + $bucketName = $bucket->name(); + + $projectId = self::$projectId; + $ipAddress = '1.2.3.0/24'; + $vpcNetwork = 'default'; + + // test enable + $output = self::runFunctionSnippet('enable_ip_filtering', [ + $projectId, + $bucketName + ]); + + $this->assertStringContainsString( + sprintf('Enabled IP filtering Rules for the Bucket: %s', $bucketName), + $output + ); + + try { + $bucket->reload(); + $info = $bucket->info(); + $this->assertEquals('Enabled', $info['ipFilter']['mode']); + $this->assertEquals([$ipAddress], $info['ipFilter']['publicNetworkSource']['allowedIpCidrRanges']); + + // test get + $output = self::runFunctionSnippet('get_ip_filtering', [ + $bucketName, + ]); + + $this->assertStringContainsString('Mode: Enabled', $output); + $this->assertStringContainsString('- ' . $ipAddress, $output); + $this->assertStringContainsString('- Network: projects/' . $projectId . '/global/networks/' . $vpcNetwork, $output); + + // test disable + $output = self::runFunctionSnippet('disable_ip_filtering', [ + $bucketName, + ]); + + $this->assertStringContainsString( + sprintf('Disabled IP filtering Rules for bucket %s', $bucketName), + $output + ); + + $bucket->reload(); + $this->assertEquals('Disabled', $bucket->info()['ipFilter']['mode']); + + // test list_buckets_ip_filtering + $output = self::runFunctionSnippet('list_buckets_ip_filtering', [ + $projectId + ]); + + $this->assertStringContainsString( + sprintf('Bucket Name: %s', $bucketName), + $output + ); + $this->assertStringContainsString( + 'IP Filtering Mode: Disabled', + $output + ); + + // test delete + $output = self::runFunctionSnippet('delete_ip_filtering_rules', [ + $bucketName, + ]); + + $this->assertStringContainsString( + sprintf('Specific IP filtering rules deleted for bucket %s', $bucketName), + $output + ); + + $bucket->reload(); + $info = $bucket->info(); + $this->assertArrayNotHasKey('allowedIpCidrRanges', $info['ipFilter']['publicNetworkSource'] ?? []); + } catch (\Google\Cloud\Core\Exception\ServiceException $e) { + // If the runner gets locked out by the 'Enabled' mode, we gracefully catch the 403 + // so we can still clean up the bucket. + if ($e->getCode() !== 403) { + throw $e; + } + } finally { + // Note: If locked out, this bucket->delete() might also fail. + // In a real testing environment, cleanup would need to happen via an admin account. + try { + $bucket->delete(); + } catch (\Exception $e) { + // Ignore cleanup failures if locked out + } + } + } + private function keyName() { return sprintf(