Skip to content

Commit 9757aaa

Browse files
authored
feat(spanner): add CMEK samples (GoogleCloudPlatform#1319)
1 parent 3342e4e commit 9757aaa

File tree

5 files changed

+295
-3
lines changed

5 files changed

+295
-3
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
2+
/**
3+
* Copyright 2021 Google Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* For instructions on how to run the full sample:
20+
*
21+
* @see https://github.com/GoogleCloudPlatform/php-docs-samples/tree/master/spanner/README.md
22+
*/
23+
24+
namespace Google\Cloud\Samples\Spanner;
25+
26+
// [START spanner_create_backup_with_encryption_key]
27+
use Google\Cloud\Spanner\Admin\Database\V1\CreateBackupEncryptionConfig;
28+
use Google\Cloud\Spanner\Backup;
29+
use Google\Cloud\Spanner\SpannerClient;
30+
31+
/**
32+
* Create an encrypted backup.
33+
* Example:
34+
* ```
35+
* create_backup_with_encryption_key($instanceId, $databaseId, $backupId, $kmsKeyName);
36+
* ```
37+
*
38+
* @param string $instanceId The Spanner instance ID.
39+
* @param string $databaseId The Spanner database ID.
40+
* @param string $backupId The Spanner backup ID.
41+
* @param string $kmsKeyName The KMS key used for encryption.
42+
*/
43+
function create_backup_with_encryption_key($instanceId, $databaseId, $backupId, $kmsKeyName)
44+
{
45+
$spanner = new SpannerClient();
46+
$instance = $spanner->instance($instanceId);
47+
$database = $instance->database($databaseId);
48+
49+
$expireTime = new \DateTime('+14 days');
50+
$backup = $instance->backup($backupId);
51+
$operation = $backup->create($database->name(), $expireTime, [
52+
'encryptionConfig' => [
53+
'kmsKeyName' => $kmsKeyName,
54+
'encryptionType' => CreateBackupEncryptionConfig\EncryptionType::CUSTOMER_MANAGED_ENCRYPTION
55+
]
56+
]);
57+
58+
print('Waiting for operation to complete...' . PHP_EOL);
59+
$operation->pollUntilComplete();
60+
61+
$backup->reload();
62+
$ready = ($backup->state() == Backup::STATE_READY);
63+
64+
if ($ready) {
65+
print('Backup is ready!' . PHP_EOL);
66+
$info = $backup->info();
67+
printf(
68+
'Backup %s of size %d bytes was created at %s using encryption key %s' . PHP_EOL,
69+
basename($info['name']), $info['sizeBytes'], $info['createTime'], $kmsKeyName);
70+
} else {
71+
print('Backup is not ready!' . PHP_EOL);
72+
}
73+
}
74+
// [END spanner_create_backup_with_encryption_key]
75+
76+
require_once __DIR__ . '/../../testing/sample_helpers.php';
77+
\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv);
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
2+
/**
3+
* Copyright 2021 Google Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* For instructions on how to run the full sample:
20+
*
21+
* @see https://github.com/GoogleCloudPlatform/php-docs-samples/tree/master/spanner/README.md
22+
*/
23+
24+
namespace Google\Cloud\Samples\Spanner;
25+
26+
// [START spanner_create_database_with_encryption_key]
27+
use Google\Cloud\Spanner\SpannerClient;
28+
29+
/**
30+
* Creates an encrypted database with tables for sample data.
31+
* Example:
32+
* ```
33+
* create_database_with_encryption_key($instanceId, $databaseId, $kmsKeyName);
34+
* ```
35+
*
36+
* @param string $instanceId The Spanner instance ID.
37+
* @param string $databaseId The Spanner database ID.
38+
* @param string $kmsKeyName The KMS key used for encryption.
39+
*/
40+
function create_database_with_encryption_key($instanceId, $databaseId, $kmsKeyName)
41+
{
42+
$spanner = new SpannerClient();
43+
$instance = $spanner->instance($instanceId);
44+
45+
if (!$instance->exists()) {
46+
throw new \LogicException("Instance $instanceId does not exist");
47+
}
48+
49+
$operation = $instance->createDatabase($databaseId, [
50+
'statements' => [
51+
"CREATE TABLE Singers (
52+
SingerId INT64 NOT NULL,
53+
FirstName STRING(1024),
54+
LastName STRING(1024),
55+
SingerInfo BYTES(MAX)
56+
) PRIMARY KEY (SingerId)",
57+
"CREATE TABLE Albums (
58+
SingerId INT64 NOT NULL,
59+
AlbumId INT64 NOT NULL,
60+
AlbumTitle STRING(MAX)
61+
) PRIMARY KEY (SingerId, AlbumId),
62+
INTERLEAVE IN PARENT Singers ON DELETE CASCADE"
63+
],
64+
'encryptionConfig' => ['kmsKeyName' => $kmsKeyName]
65+
]);
66+
67+
print('Waiting for operation to complete...' . PHP_EOL);
68+
$operation->pollUntilComplete();
69+
70+
$database = $instance->database($databaseId);
71+
printf(
72+
'Created database %s on instance %s with encryption key %s' . PHP_EOL,
73+
$databaseId,
74+
$instanceId,
75+
$database->info()['encryptionConfig']['kmsKeyName']
76+
);
77+
}
78+
// [END spanner_create_database_with_encryption_key]
79+
80+
require_once __DIR__ . '/../../testing/sample_helpers.php';
81+
\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv);
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
2+
/**
3+
* Copyright 2021 Google Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* For instructions on how to run the full sample:
20+
*
21+
* @see https://github.com/GoogleCloudPlatform/php-docs-samples/tree/master/spanner/README.md
22+
*/
23+
24+
namespace Google\Cloud\Samples\Spanner;
25+
26+
// [START spanner_restore_backup_with_encryption_key]
27+
use Google\Cloud\Spanner\Admin\Database\V1\RestoreDatabaseEncryptionConfig;
28+
use Google\Cloud\Spanner\SpannerClient;
29+
30+
/**
31+
* Restore a database from a backup.
32+
* Example:
33+
* ```
34+
* restore_backup_with_encryption_key($instanceId, $databaseId, $backupId, $kmsKeyName);
35+
* ```
36+
* @param string $instanceId The Spanner instance ID.
37+
* @param string $databaseId The Spanner database ID.
38+
* @param string $backupId The Spanner backup ID.
39+
* @param string $kmsKeyName The KMS key used for encryption.
40+
*/
41+
function restore_backup_with_encryption_key($instanceId, $databaseId, $backupId, $kmsKeyName)
42+
{
43+
$spanner = new SpannerClient();
44+
$instance = $spanner->instance($instanceId);
45+
$database = $instance->database($databaseId);
46+
$backup = $instance->backup($backupId);
47+
48+
$operation = $database->restore($backup->name(), [
49+
'encryptionConfig' => [
50+
'kmsKeyName' => $kmsKeyName,
51+
'encryptionType' => RestoreDatabaseEncryptionConfig\EncryptionType::CUSTOMER_MANAGED_ENCRYPTION
52+
]
53+
]);
54+
// Wait for restore operation to complete.
55+
$operation->pollUntilComplete();
56+
57+
// Newly created database has restore information.
58+
$database->reload();
59+
$restoreInfo = $database->info()['restoreInfo'];
60+
$sourceDatabase = $restoreInfo['backupInfo']['sourceDatabase'];
61+
$sourceBackup = $restoreInfo['backupInfo']['backup'];
62+
$encryptionConfig = $database->info()['encryptionConfig'];
63+
64+
printf(
65+
"Database %s restored from backup %s using encryption key %s" . PHP_EOL,
66+
$sourceDatabase, $sourceBackup, $encryptionConfig['kmsKeyName']);
67+
}
68+
// [END spanner_restore_backup_with_encryption_key]
69+
70+
require_once __DIR__ . '/../../testing/sample_helpers.php';
71+
\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv);

spanner/test/spannerBackupTest.php

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class spannerBackupTest extends TestCase
4444
/** @var string backupId */
4545
protected static $backupId;
4646

47+
/** @var string encryptedBackupId */
48+
protected static $encryptedBackupId;
49+
4750
/** @var string databaseId */
4851
protected static $databaseId;
4952

@@ -53,9 +56,15 @@ class spannerBackupTest extends TestCase
5356
/** @var string restoredDatabaseId */
5457
protected static $restoredDatabaseId;
5558

59+
/** @var string encryptedRestoredDatabaseId */
60+
protected static $encryptedRestoredDatabaseId;
61+
5662
/** @var $instance Instance */
5763
protected static $instance;
5864

65+
/** @var string kmsKeyName */
66+
protected static $kmsKeyName;
67+
5968
public static function setUpBeforeClass(): void
6069
{
6170
self::checkProjectEnvVars();
@@ -72,8 +81,13 @@ public static function setUpBeforeClass(): void
7281
self::$retentionPeriod = '7d';
7382
self::$databaseId = 'test-' . time() . rand();
7483
self::$backupId = 'backup-' . self::$databaseId;
75-
self::$restoredDatabaseId = self::$databaseId . '-res';
84+
self::$encryptedBackupId = 'en-backup-' . self::$databaseId;
85+
self::$restoredDatabaseId = self::$databaseId . '-r';
86+
self::$encryptedRestoredDatabaseId = self::$databaseId . '-en-r';
7687
self::$instance = $spanner->instance(self::$instanceId);
88+
89+
self::$kmsKeyName =
90+
"projects/" . self::$projectId . "/locations/us-central1/keyRings/spanner-test-keyring/cryptoKeys/spanner-test-cmek";
7791
}
7892

7993
public function testCreateDatabaseWithVersionRetentionPeriod()
@@ -86,6 +100,18 @@ public function testCreateDatabaseWithVersionRetentionPeriod()
86100
$this->assertStringContainsString(self::$retentionPeriod, $output);
87101
}
88102

103+
public function testCreateBackupWithEncryptionKey()
104+
{
105+
$database = self::$instance->database(self::$databaseId);
106+
107+
$output = $this->runFunctionSnippet('create_backup_with_encryption_key', [
108+
self::$databaseId,
109+
self::$encryptedBackupId,
110+
self::$kmsKeyName,
111+
]);
112+
$this->assertStringContainsString(self::$backupId, $output);
113+
}
114+
89115
/**
90116
* @depends testCreateDatabaseWithVersionRetentionPeriod
91117
*/
@@ -168,14 +194,28 @@ public function testRestoreBackup()
168194
$this->assertStringContainsString(self::$databaseId, $output);
169195
}
170196

197+
/**
198+
* @depends testCreateBackupWithEncryptionKey
199+
*/
200+
public function testRestoreBackupWithEncryptionKey()
201+
{
202+
$output = $this->runFunctionSnippet('restore_backup_with_encryption_key', [
203+
self::$encryptedRestoredDatabaseId,
204+
self::$encryptedBackupId,
205+
self::$kmsKeyName,
206+
]);
207+
$this->assertStringContainsString(self::$backupId, $output);
208+
$this->assertStringContainsString(self::$databaseId, $output);
209+
}
210+
171211

172212
/**
173-
* @depends testRestoreBackup
213+
* @depends testRestoreBackupWithEncryptionKey
174214
*/
175215
public function testListDatabaseOperations()
176216
{
177217
$output = $this->runFunctionSnippet('list_database_operations');
178-
$this->assertStringContainsString(self::$restoredDatabaseId, $output);
218+
$this->assertStringContainsString(self::$encryptedRestoredDatabaseId, $output);
179219
}
180220

181221
/**

spanner/test/spannerTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,18 @@ class spannerTest extends TestCase
4242
/** @var string databaseId */
4343
protected static $databaseId;
4444

45+
/** @var string encryptedDatabaseId */
46+
protected static $encryptedDatabaseId;
47+
4548
/** @var string backupId */
4649
protected static $backupId;
4750

4851
/** @var $instance Instance */
4952
protected static $instance;
5053

54+
/** @var string kmsKeyName */
55+
protected static $kmsKeyName;
56+
5157
/**
5258
* Low cost instance with less than 1000 processing units.
5359
*
@@ -73,8 +79,11 @@ public static function setUpBeforeClass(): void
7379
self::$instanceId = 'test-' . time() . rand();
7480
self::$lowCostInstanceId = 'test-' . time() . rand();
7581
self::$databaseId = 'test-' . time() . rand();
82+
self::$encryptedDatabaseId = 'en-test-' . time() . rand();
7683
self::$backupId = 'backup-' . self::$databaseId;
7784
self::$instance = $spanner->instance(self::$instanceId);
85+
self::$kmsKeyName =
86+
"projects/" . self::$projectId . "/locations/us-central1/keyRings/spanner-test-keyring/cryptoKeys/spanner-test-cmek";
7887
self::$lowCostInstance = $spanner->instance(self::$lowCostInstanceId);
7988
}
8089

@@ -106,6 +115,20 @@ public function testCreateDatabase()
106115
$this->assertStringContainsString('Created database test-', $output);
107116
}
108117

118+
/**
119+
* @depends testCreateInstance
120+
*/
121+
public function testCreateDatabaseWithEncryptionKey()
122+
{
123+
$output = $this->runFunctionSnippet('create_database_with_encryption_key', [
124+
self::$instanceId,
125+
self::$encryptedDatabaseId,
126+
self::$kmsKeyName,
127+
]);
128+
$this->assertStringContainsString('Waiting for operation to complete...', $output);
129+
$this->assertStringContainsString('Created database en-test-', $output);
130+
}
131+
109132
/**
110133
* @depends testCreateDatabase
111134
*/

0 commit comments

Comments
 (0)