diff --git a/kms/addMemberToCryptoKeyPolicy.js b/kms/addMemberToCryptoKeyPolicy.js new file mode 100644 index 0000000000..1bc73f820b --- /dev/null +++ b/kms/addMemberToCryptoKeyPolicy.js @@ -0,0 +1,76 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_add_member_to_cryptokey_policy] +async function addMemberToCryptoKeyPolicy( + projectId = 'your-project-id', // Your GCP Project Id + keyRingId = 'my-key-ring', // Name of the crypto key's key ring + cryptoKeyId = 'my-key', // Name of the crypto key + member = 'user:dev@example.com', // Member to add to the crypto key + role = 'roles/viewer' // Role to give the member +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key's key ring + const locationId = 'global'; + + // Get the full path to the crypto key + const resource = client.cryptoKeyPath( + projectId, + locationId, + keyRingId, + cryptoKeyId + ); + + // Gets the IAM policy of a crypto key + const [result] = await client.getIamPolicy({resource}); + let policy = Object.assign({bindings: []}, result); + const index = policy.bindings.findIndex(binding => binding.role === role); + + // Add the role/member combo to the policy + const members = []; + const binding = Object.assign({role, members}, policy.bindings[index]); + if (index === -1) { + policy.bindings.push(binding); + } + if (!binding.members.includes(member)) { + binding.members.push(member); + } + + // Adds the member/role combo to the policy of the crypto key + [policy] = await client.setIamPolicy({resource, policy}); + console.log( + `${member}/${role} combo added to policy for crypto key ${cryptoKeyId}.` + ); + if (policy.bindings) { + policy.bindings.forEach(binding => { + if (binding.members && binding.members.length) { + console.log(`${binding.role}:`); + binding.members.forEach(member => { + console.log(` ${member}`); + }); + } + }); + } else { + console.log(`Policy for crypto key ${cryptoKeyId} is empty.`); + } +} +// [END kms_add_member_to_cryptokey_policy] + +const args = process.argv.slice(2); +addMemberToCryptoKeyPolicy(...args).catch(console.error); diff --git a/kms/addMemberToKeyRingPolicy.js b/kms/addMemberToKeyRingPolicy.js new file mode 100644 index 0000000000..4e32cdec85 --- /dev/null +++ b/kms/addMemberToKeyRingPolicy.js @@ -0,0 +1,72 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_add_member_to_keyring_policy] +async function addMemberToKeyRingPolicy( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring', // Name of the crypto key's key ring + member = 'user:dev@example.com', // Member to add to the crypto key + role = 'roles/viewer' // Role to give the member +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the key ring, e.g. "global" + const locationId = 'global'; + + // Get the full path to the keyring + const resource = client.keyRingPath(projectId, locationId, keyRingId); + + // Gets the IAM policy of a key ring + let [policy] = await client.getIamPolicy({resource}); + policy.bindings = policy.bindings || []; + + // find the index of the binding matching the requested role + const index = policy.bindings.findIndex(binding => binding.role === role); + + // Add the role/member combo to the policy + const members = []; + const binding = Object.assign({role}, {members}, policy.bindings[index]); + if (index === -1) { + policy.bindings.push(binding); + } + if (!binding.members.includes(member)) { + binding.members.push(member); + } + + // Adds the member/role combo to the policy of the key ring + [policy] = await client.setIamPolicy({resource, policy}); + console.log( + `${member}/${role} combo added to policy for key ring ${keyRingId}.` + ); + if (policy.bindings) { + policy.bindings.forEach(binding => { + if (binding.members && binding.members.length) { + console.log(`${binding.role}:`); + binding.members.forEach(member => { + console.log(` ${member}`); + }); + } + }); + } else { + console.log(`Policy for key ring ${keyRingId} is empty.`); + } +} +// [END kms_add_member_to_keyring_policy] + +const args = process.argv.slice(2); +addMemberToKeyRingPolicy(...args).catch(console.error); diff --git a/kms/createCryptoKey.js b/kms/createCryptoKey.js new file mode 100644 index 0000000000..18fe7d2791 --- /dev/null +++ b/kms/createCryptoKey.js @@ -0,0 +1,46 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_create_cryptokey] +async function createCryptoKey( + projectId = 'your-project-id', // Your GCP Project Id + keyRingId = 'my-key-ring', // Name of the crypto key's key ring + cryptoKeyId = 'my-key' // Name of the crypto key +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the new crypto key's key ring, e.g. "global" + const locationId = 'global'; + + const parent = client.keyRingPath(projectId, locationId, keyRingId); + + // Creates a new key ring + const [cryptoKey] = await client.createCryptoKey({ + parent, + cryptoKeyId, + cryptoKey: { + // This will allow the API access to the key for encryption and decryption + purpose: 'ENCRYPT_DECRYPT', + }, + }); + console.log(`Key ${cryptoKey.name} created.`); +} +// [END kms_create_cryptokey] + +const args = process.argv.slice(2); +createCryptoKey(...args).catch(console.error); diff --git a/kms/createCryptoKeyVersion.js b/kms/createCryptoKeyVersion.js new file mode 100644 index 0000000000..11369f0954 --- /dev/null +++ b/kms/createCryptoKeyVersion.js @@ -0,0 +1,45 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_create_cryptokey_version] +async function createCryptoKeyVersion( + projectId = 'YOUR_PROJECT_ID', // Your Google Cloud Platform project ID + keyRingId = 'my-key-ring', // Name of the crypto key version's key ring, e.g. "my-key-ring" + cryptoKeyId = 'my-key' // Name of the version's crypto key +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key versions's key ring, e.g. "global" + const locationId = 'global'; + + // Get the full path to the crypto key + const parent = client.cryptoKeyPath( + projectId, + locationId, + keyRingId, + cryptoKeyId + ); + + // Creates a new crypto key version + const [result] = await client.createCryptoKeyVersion({parent}); + console.log(`Crypto key version ${result.name} created.`); +} +// [END kms_create_cryptokey_version] + +const args = process.argv.slice(2); +createCryptoKeyVersion(...args).catch(console.error); diff --git a/kms/createKeyring.js b/kms/createKeyring.js new file mode 100644 index 0000000000..2b97aba3de --- /dev/null +++ b/kms/createKeyring.js @@ -0,0 +1,39 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_create_keyring] +async function createKeyRing( + projectId = 'YOUR_PROJECT_ID', // Your GCP projectId + keyRingId = 'my-new-key-ring' // Name of the new key ring +) { + // The location of the new key ring, e.g. "global" + const locationId = 'global'; + + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // Get the full path to the parent + const parent = client.locationPath(projectId, locationId); + + // Creates a new key ring + const [result] = await client.createKeyRing({parent, keyRingId}); + console.log(`Key ring ${result.name} created.`); +} +// [END kms_create_keyring] + +const args = process.argv.slice(2); +createKeyRing(...args).catch(console.error); diff --git a/kms/decrypt.js b/kms/decrypt.js new file mode 100644 index 0000000000..30a1eb905c --- /dev/null +++ b/kms/decrypt.js @@ -0,0 +1,59 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_decrypt] +async function decrypt( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring', // Name of the crypto key's key ring + cryptoKeyId = 'my-key', // Name of the crypto key, e.g. "my-key" + ciphertextFileName = './path/to/plaintext.txt.encrypted', + plaintextFileName = './path/to/plaintext.txt.decrypted' +) { + const fs = require('fs'); + const {promisify} = require('util'); + + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key's key ring, e.g. "global" + const locationId = 'global'; + + // Reads the file to be decrypted + const readFile = promisify(fs.readFile); + const contentsBuffer = await readFile(ciphertextFileName); + const name = client.cryptoKeyPath( + projectId, + locationId, + keyRingId, + cryptoKeyId + ); + const ciphertext = contentsBuffer.toString('base64'); + + // Dencrypts the file using the specified crypto key + const [result] = await client.decrypt({name, ciphertext}); + + // Writes the dencrypted file to disk + const writeFile = promisify(fs.writeFile); + await writeFile(plaintextFileName, Buffer.from(result.plaintext, 'base64')); + console.log( + `Decrypted ${ciphertextFileName}, result saved to ${plaintextFileName}.` + ); +} +// [END kms_decrypt] + +const args = process.argv.slice(2); +decrypt(...args).catch(console.error); diff --git a/kms/destroyCryptoKeyVersion.js b/kms/destroyCryptoKeyVersion.js new file mode 100644 index 0000000000..49078c6271 --- /dev/null +++ b/kms/destroyCryptoKeyVersion.js @@ -0,0 +1,47 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_destroy_cryptokey_version] +async function destroyCryptoKeyVersion( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring', // Name of the crypto key version's key ring + cryptoKeyId = 'my-key', // Name of the version's crypto key + version = 1234 // The version's id +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key versions's key ring, e.g. "global" + const locationId = 'global'; + + // Get the full path to the crypto key version + const name = client.cryptoKeyVersionPath( + projectId, + locationId, + keyRingId, + cryptoKeyId, + version + ); + + // destroys a crypto key version + const [result] = await client.destroyCryptoKeyVersion({name}); + console.log(`Crypto key version ${result.name} destroyed.`); +} +// [END kms_destroy_cryptokey_version] + +const args = process.argv.slice(2); +destroyCryptoKeyVersion(...args).catch(console.error); diff --git a/kms/disableCryptoKeyVersion.js b/kms/disableCryptoKeyVersion.js new file mode 100644 index 0000000000..8915ee1bae --- /dev/null +++ b/kms/disableCryptoKeyVersion.js @@ -0,0 +1,54 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_disable_cryptokey_version] +async function disableCryptoKeyVersion( + projectId = 'your-project-id', // Your GCP Project ID + keyRingId = 'my-key-ring', // Name of the crypto key version's key ring + cryptoKeyId = 'my-key', // Name of the version's crypto key + version = 1234 // The version's id +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key versions's key ring, e.g. "global" + const locationId = 'global'; + + // Get the full path to the crypto key + const name = client.cryptoKeyVersionPath( + projectId, + locationId, + keyRingId, + cryptoKeyId, + version + ); + + // Gets a crypto key version + const [cryptoKeyVersion] = await client.getCryptoKeyVersion({name}); + cryptoKeyVersion.state = 'DISABLED'; + + // Disables a crypto key version + const [result] = await client.updateCryptoKeyVersion({ + cryptoKeyVersion, + updateMask: ['state'], + }); + console.log(`Crypto key version ${result.name} disabled.`); +} +// [END kms_disable_cryptokey_version] + +const args = process.argv.slice(2); +disableCryptoKeyVersion(...args).catch(console.error); diff --git a/kms/enableCryptoKeyVersion.js b/kms/enableCryptoKeyVersion.js new file mode 100644 index 0000000000..9e935e5512 --- /dev/null +++ b/kms/enableCryptoKeyVersion.js @@ -0,0 +1,54 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_enable_cryptokey_version] +async function enableCryptoKeyVersion( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring', // Name of the crypto key version's key ring + cryptoKeyId = 'my-key', // Name of the version's crypto key + version = 1234 // The version's id +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key versions's key ring, e.g. "global" + const locationId = 'global'; + + // Get the full path to the crypto key + const name = client.cryptoKeyVersionPath( + projectId, + locationId, + keyRingId, + cryptoKeyId, + version + ); + + // Gets a crypto key version + const [cryptoKeyVersion] = await client.getCryptoKeyVersion({name}); + cryptoKeyVersion.state = 'ENABLED'; + + // enables a crypto key version + const [result] = await client.updateCryptoKeyVersion({ + cryptoKeyVersion, + updateMask: ['state'], + }); + console.log(`Crypto key version ${result.name} enabled.`); +} +// [END kms_enable_cryptokey_version] + +const args = process.argv.slice(2); +enableCryptoKeyVersion(...args).catch(console.error); diff --git a/kms/encrypt.js b/kms/encrypt.js new file mode 100644 index 0000000000..091c6a7407 --- /dev/null +++ b/kms/encrypt.js @@ -0,0 +1,56 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_encrypt] +async function encrypt( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring', // Name of the crypto key's key ring + cryptoKeyId = 'my-key', // Name of the crypto key, e.g. "my-key" + plaintextFileName = './path/to/plaintext.txt', + ciphertextFileName = './path/to/plaintext.txt.encrypted' +) { + const fs = require('fs'); + const {promisify} = require('util'); + + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key's key ring, e.g. "global" + const locationId = 'global'; + + // Reads the file to be encrypted + const readFile = promisify(fs.readFile); + const contentsBuffer = await readFile(plaintextFileName); + const plaintext = contentsBuffer.toString('base64'); + const name = client.cryptoKeyPath( + projectId, + locationId, + keyRingId, + cryptoKeyId + ); + + // Encrypts the file using the specified crypto key + const [result] = await client.encrypt({name, plaintext}); + const writeFile = promisify(fs.writeFile); + await writeFile(ciphertextFileName, Buffer.from(result.ciphertext, 'base64')); + console.log(`Encrypted ${plaintextFileName} using ${result.name}.`); + console.log(`Result saved to ${ciphertextFileName}.`); +} +// [END kms_encrypt] + +const args = process.argv.slice(2); +encrypt(...args).catch(console.error); diff --git a/kms/getCryptoKey.js b/kms/getCryptoKey.js new file mode 100644 index 0000000000..3731ab0da5 --- /dev/null +++ b/kms/getCryptoKey.js @@ -0,0 +1,49 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_get_cryptokey] +async function getCryptoKey( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring', // Name of the crypto key's key ring + cryptoKeyId = 'my-key' // Name of the crypto key, e.g. "my-key" +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key's key ring, e.g. "global" + const locationId = 'global'; + + const name = client.cryptoKeyPath( + projectId, + locationId, + keyRingId, + cryptoKeyId + ); + + // Gets a crypto key + const [cryptoKey] = await client.getCryptoKey({name}); + console.log(`Name: ${cryptoKey.name}:`); + console.log(`Created: ${new Date(cryptoKey.createTime)}`); + console.log(`Purpose: ${cryptoKey.purpose}`); + console.log(`Primary: ${cryptoKey.primary.name}`); + console.log(` State: ${cryptoKey.primary.state}`); + console.log(` Created: ${new Date(cryptoKey.primary.createTime)}`); +} +// [END kms_get_cryptokey] + +const args = process.argv.slice(2); +getCryptoKey(...args).catch(console.error); diff --git a/kms/getCryptoKeyIamPolicy.js b/kms/getCryptoKeyIamPolicy.js new file mode 100644 index 0000000000..83df614ec4 --- /dev/null +++ b/kms/getCryptoKeyIamPolicy.js @@ -0,0 +1,55 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_get_cryptokey_policy] +async function getCryptoKeyIamPolicy( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring', // Name of the crypto key's key ring + cryptoKeyId = 'my-key' // Name of the crypto key, e.g. "my-key" +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key's key ring, e.g. "global" + const locationId = 'global'; + + const resource = client.cryptoKeyPath( + projectId, + locationId, + keyRingId, + cryptoKeyId + ); + + // Gets the IAM policy of a crypto key + const [policy] = await client.getIamPolicy({resource}); + if (policy.bindings && policy.bindings.length > 0) { + policy.bindings.forEach(binding => { + if (binding.members && binding.members.length) { + console.log(`${binding.role}:`); + binding.members.forEach(member => { + console.log(` ${member}`); + }); + } + }); + } else { + console.log(`Policy for crypto key ${cryptoKeyId} is empty.`); + } +} +// [END kms_get_cryptokey_policy] + +const args = process.argv.slice(2); +getCryptoKeyIamPolicy(...args).catch(console.error); diff --git a/kms/getKeyring.js b/kms/getKeyring.js new file mode 100644 index 0000000000..3d04542492 --- /dev/null +++ b/kms/getKeyring.js @@ -0,0 +1,40 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_get_keyring] +async function getKeyRing( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring' // Name of the crypto key's key ring +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the key ring, e.g. "global" + const locationId = 'global'; + + // Get the full path to the keyring + const name = client.keyRingPath(projectId, locationId, keyRingId); + + // Get the keyring + const [keyRing] = await client.getKeyRing({name}); + console.log(`Name: ${keyRing.name}`); + console.log(`Created: ${new Date(keyRing.createTime.seconds * 1000)}`); +} +// [END kms_get_keyring] + +const args = process.argv.slice(2); +getKeyRing(...args).catch(console.error); diff --git a/kms/getKeyringIamPolicy.js b/kms/getKeyringIamPolicy.js new file mode 100644 index 0000000000..f89ebd75ab --- /dev/null +++ b/kms/getKeyringIamPolicy.js @@ -0,0 +1,50 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_get_keyring_policy] +async function getKeyRingIamPolicy( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring' // Name of the crypto key's key ring +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the key ring, e.g. "global" + const locationId = 'global'; + + // Get the full path to the keyring + const resource = client.keyRingPath(projectId, locationId, keyRingId); + + // Gets the IAM policy of a key ring + const [policy] = await client.getIamPolicy({resource}); + if (policy.bindings && policy.bindings.length > 0) { + policy.bindings.forEach(binding => { + if (binding.members && binding.members.length) { + console.log(`${binding.role}:`); + binding.members.forEach(member => { + console.log(` ${member}`); + }); + } + }); + } else { + console.log(`Policy for key ring ${keyRingId} is empty.`); + } +} +// [END kms_get_keyring_policy] + +const args = process.argv.slice(2); +getKeyRingIamPolicy(...args).catch(console.error); diff --git a/kms/listCryptoKeyVersions.js b/kms/listCryptoKeyVersions.js new file mode 100644 index 0000000000..09f2999a1b --- /dev/null +++ b/kms/listCryptoKeyVersions.js @@ -0,0 +1,53 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_list_cryptokey_versions] +async function listCryptoKeyVersions( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring', // name of the crypto key's key ring + cryptoKeyId = 'my-key-ring' // name of the crypto key from which to list versions +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key's key ring, e.g. "global" + const locationId = 'global'; + + // Get full path to crypto key + const parent = client.cryptoKeyPath( + projectId, + locationId, + keyRingId, + cryptoKeyId + ); + + // Creates a new key ring + const [versions] = await client.listCryptoKeyVersions({parent}); + if (versions.length) { + versions.forEach(version => { + console.log(`${version.name}:`); + console.log(` Created: ${new Date(version.createTime.seconds * 1000)}`); + console.log(` State: ${version.state}`); + }); + } else { + console.log('No crypto key versions found.'); + } +} +// [END kms_list_cryptokey_versions] + +const args = process.argv.slice(2); +listCryptoKeyVersions(...args).catch(console.error); diff --git a/kms/listCryptoKeys.js b/kms/listCryptoKeys.js new file mode 100644 index 0000000000..61d4f0b72f --- /dev/null +++ b/kms/listCryptoKeys.js @@ -0,0 +1,49 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_list_cryptokeys] +async function listCryptoKeys( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring' // Name of the crypto key's key ring +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the key ring from which to list crypto keys, e.g. "global" + const locationId = 'global'; + + const parent = client.keyRingPath(projectId, locationId, keyRingId); + + // Creates a new key ring + const [cryptoKeys] = await client.listCryptoKeys({parent}); + if (cryptoKeys.length) { + cryptoKeys.forEach(cryptoKey => { + console.log(`${cryptoKey.name}:`); + console.log(` Created: ${new Date(cryptoKey.createTime)}`); + console.log(` Purpose: ${cryptoKey.purpose}`); + console.log(` Primary: ${cryptoKey.primary.name}`); + console.log(` State: ${cryptoKey.primary.state}`); + console.log(` Created: ${new Date(cryptoKey.primary.createTime)}`); + }); + } else { + console.log('No crypto keys found.'); + } +} +// [END kms_list_cryptokeys] + +const args = process.argv.slice(2); +listCryptoKeys(...args).catch(console.error); diff --git a/kms/listKeyrings.js b/kms/listKeyrings.js new file mode 100644 index 0000000000..4c7e7a5d54 --- /dev/null +++ b/kms/listKeyrings.js @@ -0,0 +1,44 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_list_keyrings] +async function listKeyRings( + projectId = 'your-project-id' // Your GCP Project ID +) { + // The location from which to list key rings, e.g. "global" + const locationId = 'global'; + + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // Lists key rings + const parent = client.locationPath(projectId, locationId); + const [keyRings] = await client.listKeyRings({parent}); + + if (keyRings.length) { + keyRings.forEach(keyRing => { + console.log(`${keyRing.name}:`); + console.log(` Created: ${new Date(keyRing.createTime.seconds * 1000)}`); + }); + } else { + console.log('No key rings found.'); + } +} +// [END kms_list_keyrings] + +const args = process.argv.slice(2); +listKeyRings(...args).catch(console.error); diff --git a/kms/package.json b/kms/package.json index 3e4089a75b..5da6ce9785 100644 --- a/kms/package.json +++ b/kms/package.json @@ -1,22 +1,26 @@ { - "name": "@google-cloud/automl-samples", - "description": "Samples for the Cloud KMS Client Library for Node.js.", - "version": "0.0.1", + "name": "nodejs-kms-samples", + "private": true, "license": "Apache-2.0", "author": "Google Inc.", + "repository": "googleapis/nodejs-kms", + "files": [ + "*.js" + ], "engines": { "node": ">=8" }, - "repository": "googleapis/nodejs-kms", - "private": true, - "nyc": { - "exclude": [ - "**/*.test.js" - ] + "scripts": { + "test": "mocha system-test" }, - "scripts": {}, "dependencies": { "@google-cloud/kms": "^0.2.0" }, - "devDependencies": {} + "devDependencies": { + "chai": "^4.2.0", + "execa": "^1.0.0", + "mocha": "^5.2.0", + "uuid": "^3.2.1", + "yargs": "^12.0.5" + } } diff --git a/kms/quickstart.js b/kms/quickstart.js index e69de29bb2..540fb1ec27 100644 --- a/kms/quickstart.js +++ b/kms/quickstart.js @@ -0,0 +1,45 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_quickstart] +async function quickstart( + projectId = 'your-project-id' // Your GCP projectId +) { + // Imports the @google-cloud/kms client library + const kms = require('@google-cloud/kms'); + + // Instantiates an authorized client + const client = new kms.KeyManagementServiceClient(); + + // Lists keys in the "global" location. + const locationId = 'global'; + + // Lists key rings + const parent = client.locationPath(projectId, locationId); + const [keyRings] = await client.listKeyRings({parent}); + + // Display the results + if (keyRings.length) { + console.log('Key rings:'); + keyRings.forEach(keyRing => console.log(keyRing.name)); + } else { + console.log(`No key rings found.`); + } +} +// [END kms_quickstart] + +const args = process.argv.slice(2); +quickstart(...args).catch(console.error); diff --git a/kms/removeMemberCryptoKeyPolicy.js b/kms/removeMemberCryptoKeyPolicy.js new file mode 100644 index 0000000000..e7e26e98f2 --- /dev/null +++ b/kms/removeMemberCryptoKeyPolicy.js @@ -0,0 +1,80 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_remove_member_from_cryptokey_policy] +async function removeMemberFromCryptoKeyPolicy( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring', // Name of the crypto key's key ring + cryptoKeyId = 'my-key', // Name of the crypto key, e.g. "my-key" + member = 'user:dev@example.com', // Member to add to the crypto key + role = 'roles/viewer' // Role to give the member +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key's key ring, e.g. "global" + const locationId = 'global'; + + // Get the full path to the crypto key + const resource = client.cryptoKeyPath( + projectId, + locationId, + keyRingId, + cryptoKeyId + ); + + // Gets the IAM policy of a crypto key + const [result] = await client.getIamPolicy({resource}); + let policy = Object.assign({bindings: []}, result); + const index = policy.bindings.findIndex(binding => binding.role === role); + const members = []; + const binding = Object.assign({role, members}, policy.bindings[index]); + if (index === -1) { + return; + } + if (!binding.members.includes(member)) { + return; + } + + // Remove the role/member combo from the policy + binding.members.splice(binding.members.indexOf(member), 1); + + const request = {resource, policy}; + console.log(JSON.stringify(request, null, 2)); + + // Removes the member/role combo from the policy of the crypto key + [policy] = await client.setIamPolicy(request); + console.log( + `${member}/${role} combo removed from policy for crypto key ${cryptoKeyId}.` + ); + if (policy.bindings) { + policy.bindings.forEach(binding => { + if (binding.members && binding.members.length) { + console.log(`${binding.role}:`); + binding.members.forEach(member => { + console.log(` ${member}`); + }); + } + }); + } else { + console.log(`Policy for crypto key ${cryptoKeyId} is empty.`); + } +} +// [END kms_remove_member_from_cryptokey_policy] + +const args = process.argv.slice(2); +removeMemberFromCryptoKeyPolicy(...args).catch(console.error); diff --git a/kms/removeMemberFromKeyRingPolicy.js b/kms/removeMemberFromKeyRingPolicy.js new file mode 100644 index 0000000000..185f1e69da --- /dev/null +++ b/kms/removeMemberFromKeyRingPolicy.js @@ -0,0 +1,71 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_remove_member_from_keyring_policy] +async function removeMemberFromKeyRingPolicy( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring', // Name of the crypto key's key ring + member = 'user:dev@example.com', // Member to rm from the crypto key + role = 'roles/viewer' // Role to give the member +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the key ring, e.g. "global" + const locationId = 'global'; + + // Get the path to the key ring + const resource = client.keyRingPath(projectId, locationId, keyRingId); + + // Gets the IAM policy of a key ring + const [result] = await client.getIamPolicy({resource}); + let policy = Object.assign({bindings: []}, result); + const index = policy.bindings.findIndex(binding => binding.role === role); + const members = []; + const binding = Object.assign({role, members}, policy.bindings[index]); + if (index === -1) { + return; + } + if (!binding.members.includes(member)) { + return; + } + + // Remove the role/member combo from the policy + binding.members.splice(binding.members.indexOf(member), 1); + + // Removes the role/member combo from the policy of the key ring + [policy] = await client.setIamPolicy({resource, policy}); + console.log( + `${member}/${role} combo removed from policy for key ring ${keyRingId}.` + ); + if (policy.bindings) { + policy.bindings.forEach(binding => { + if (binding.members && binding.members.length) { + console.log(`${binding.role}:`); + binding.members.forEach(member => { + console.log(` ${member}`); + }); + } + }); + } else { + console.log(`Policy for key ring ${keyRingId} is empty.`); + } +} +// [END kms_remove_member_from_keyring_policy] + +const args = process.argv.slice(2); +removeMemberFromKeyRingPolicy(...args).catch(console.error); diff --git a/kms/resources/plaintext.txt b/kms/resources/plaintext.txt new file mode 100644 index 0000000000..2af8b3cee8 --- /dev/null +++ b/kms/resources/plaintext.txt @@ -0,0 +1,4 @@ +So if you're lost and on your own +You can never surrender +And if your path won't lead you home +You can never surrender \ No newline at end of file diff --git a/kms/restoreCryptoKeyVersion.js b/kms/restoreCryptoKeyVersion.js new file mode 100644 index 0000000000..45594114f5 --- /dev/null +++ b/kms/restoreCryptoKeyVersion.js @@ -0,0 +1,47 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_restore_cryptokey_version] +async function restoreCryptoKeyVersion( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring', // Name of the crypto key version's key ring + cryptoKeyId = 'my-key', // Name of the version's crypto key + version = 1234 // The version's id +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key versions's key ring, e.g. "global" + const locationId = 'global'; + + // Get the full path to the crypto key version + const name = client.cryptoKeyVersionPath( + projectId, + locationId, + keyRingId, + cryptoKeyId, + version + ); + + // restores a crypto key version + const [result] = await client.restoreCryptoKeyVersion({name}); + console.log(`Crypto key version ${result.name} restored.`); +} +// [END kms_restore_cryptokey_version] + +const args = process.argv.slice(2); +restoreCryptoKeyVersion(...args).catch(console.error); diff --git a/kms/setPrimaryCryptoKeyVersion.js b/kms/setPrimaryCryptoKeyVersion.js new file mode 100644 index 0000000000..a2f743d0df --- /dev/null +++ b/kms/setPrimaryCryptoKeyVersion.js @@ -0,0 +1,55 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START kms_set_cryptokey_primary_version] +async function setPrimaryCryptoKeyVersion( + projectId = 'your-project-id', // Your GCP projectId + keyRingId = 'my-key-ring', // Name of the crypto key version's key ring + cryptoKeyId = 'my-key', // Name of the version's crypto key + version = 1234 // The version's id +) { + // Import the library and create a client + const kms = require('@google-cloud/kms'); + const client = new kms.KeyManagementServiceClient(); + + // The location of the crypto key versions's key ring, e.g. "global" + const locationId = 'global'; + + const name = client.cryptoKeyPath( + projectId, + locationId, + keyRingId, + cryptoKeyId + ); + const cryptoKeyVersionId = version; + const request = {name, cryptoKeyVersionId}; + + // Sets a crypto key's primary version + const [cryptoKey] = await client.updateCryptoKeyPrimaryVersion(request); + console.log( + `Set ${version} as primary version for crypto key ${cryptoKeyId}.\n` + ); + console.log(`Name: ${cryptoKey.name}:`); + console.log(`Created: ${new Date(cryptoKey.createTime)}`); + console.log(`Purpose: ${cryptoKey.purpose}`); + console.log(`Primary: ${cryptoKey.primary.name}`); + console.log(` State: ${cryptoKey.primary.state}`); + console.log(` Created: ${new Date(cryptoKey.primary.createTime)}`); +} +// [END kms_set_cryptokey_primary_version] + +const args = process.argv.slice(2); +setPrimaryCryptoKeyVersion(...args).catch(console.error); diff --git a/kms/system-test/.eslintrc.yml b/kms/system-test/.eslintrc.yml new file mode 100644 index 0000000000..6db2a46c53 --- /dev/null +++ b/kms/system-test/.eslintrc.yml @@ -0,0 +1,3 @@ +--- +env: + mocha: true diff --git a/kms/system-test/kms.test.js b/kms/system-test/kms.test.js new file mode 100644 index 0000000000..548f4072f5 --- /dev/null +++ b/kms/system-test/kms.test.js @@ -0,0 +1,306 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const fs = require(`fs`); +const path = require(`path`); +const {assert} = require('chai'); +const execa = require('execa'); +const uuid = require(`uuid`); +const {promisify} = require('util'); +const unlink = promisify(fs.unlink); + +const cwd = path.join(__dirname, `..`); +const keyRingName = `test-ring-${uuid.v4()}`; +const keyNameOne = `test-key-${uuid.v4()}`; +const member = `allAuthenticatedUsers`; +const role = `roles/viewer`; +const projectId = process.env.GCLOUD_PROJECT; +const plaintext = path.join(__dirname, `../resources/plaintext.txt`); +const ciphertext = path.join(__dirname, `../resources/plaintext.txt.encrypted`); +const decrypted = path.join(__dirname, `../resources/plaintext.txt.decrypted`); + +const unspecifiedKeyRingName = `projects/${projectId}/locations/global/keyRings/`; +const formattedKeyRingName = `projects/${projectId}/locations/global/keyRings/${keyRingName}`; +const formattedKeyName = `${formattedKeyRingName}/cryptoKeys/${keyNameOne}`; + +const exec = async cmd => { + const result = await execa.shell(cmd, {cwd}); + if (result.stderr) { + throw new Error(result.stderr); + } + return result.stdout; +}; + +describe('kms sample tests', () => { + before(async () => { + try { + await unlink(ciphertext); + await unlink(decrypted); + } catch (e) { + // ignore exceptions + } + }); + + after(async () => { + try { + await unlink(ciphertext); + await unlink(decrypted); + } catch (e) { + // ignore exceptions + } + }); + + it('should list key rings', async () => { + const output = await exec(`node quickstart.js "${projectId}"`); + assert.match(output, /Key rings:/); + assert.match(output, /\/locations\/global\/keyRings\//); + }); + + it(`should create a key ring`, async () => { + const output = await exec( + `node createKeyring.js "${projectId}" "${keyRingName}"` + ); + if (!output.includes(`KeyRing ${formattedKeyRingName} already exists`)) { + assert.match( + output, + new RegExp(`Key ring ${formattedKeyRingName} created.`) + ); + } + }); + + it(`should list key rings`, async () => { + const output = await exec(`node listKeyrings.js ${projectId}`); + assert.match(output, new RegExp(unspecifiedKeyRingName)); + }); + + it(`should get a key ring`, async () => { + const output = await exec(`node getKeyring ${projectId} ${keyRingName}`); + assert.match(output, new RegExp(`Name: ${formattedKeyRingName}`)); + assert.ok(output.match(new RegExp(`Created: `))); + }); + + it(`should get a key ring's empty IAM policy`, async () => { + const output = await exec( + `node getKeyringIamPolicy.js ${projectId} ${keyRingName}` + ); + assert.match( + output, + new RegExp(`Policy for key ring ${keyRingName} is empty.`) + ); + }); + + it(`should grant access to a key ring`, async () => { + const output = await exec( + `node addMemberToKeyRingPolicy.js ${projectId} ${keyRingName} ${member} ${role}` + ); + assert.match( + output, + new RegExp( + `${member}/${role} combo added to policy for key ring ${keyRingName}.` + ) + ); + }); + + it(`should get a key ring's updated IAM policy`, async () => { + const output = await exec( + `node getKeyringIamPolicy.js ${projectId} ${keyRingName}` + ); + assert.match(output, new RegExp(`${role}:`)); + assert.match(output, new RegExp(` ${member}`)); + }); + + it(`should revoke access to a key ring`, async () => { + const output = await exec( + `node removeMemberFromKeyRingPolicy.js ${projectId} ${keyRingName} ${member} ${role}` + ); + assert.match( + output, + new RegExp( + `${member}/${role} combo removed from policy for key ring ${keyRingName}.` + ) + ); + }); + + it(`should create a key`, async () => { + const output = await exec( + `node createCryptoKey.js ${projectId} ${keyRingName} ${keyNameOne}` + ); + if (!output.includes(`CryptoKey ${formattedKeyName} already exists`)) { + assert.match(output, new RegExp(`Key ${formattedKeyName} created.`)); + } + }); + + it(`should list keys`, async () => { + const output = await exec( + `node listCryptoKeys.js ${projectId} ${keyRingName}` + ); + assert.match(output, new RegExp(formattedKeyName)); + }); + + it(`should get a key`, async () => { + const output = await exec( + `node getCryptoKey.js ${projectId} ${keyRingName} ${keyNameOne}` + ); + assert.match(output, new RegExp(`Name: ${formattedKeyName}`)); + assert.match(output, new RegExp(`Created: `)); + }); + + it(`should set a crypto key's primary version`, async () => { + const output = await exec( + `node setPrimaryCryptoKeyVersion.js ${projectId} ${keyRingName} ${keyNameOne} 1` + ); + assert.match( + output, + new RegExp(`Set 1 as primary version for crypto key ${keyNameOne}.\n`) + ); + }); + + it(`should encrypt a file`, async () => { + const output = await exec( + `node encrypt.js ${projectId} ${keyRingName} ${keyNameOne} "${plaintext}" "${ciphertext}"` + ); + assert.match( + output, + new RegExp( + `Encrypted ${plaintext} using ${formattedKeyName}/cryptoKeyVersions/1.` + ) + ); + assert.match(output, new RegExp(`Result saved to ${ciphertext}.`)); + }); + + it(`should decrypt a file`, async () => { + const output = await exec( + `node decrypt.js ${projectId} "${keyRingName}" "${keyNameOne}" "${ciphertext}" "${decrypted}"` + ); + assert.match( + output, + new RegExp(`Decrypted ${ciphertext}, result saved to ${decrypted}.`) + ); + + assert.strictEqual( + fs.readFileSync(plaintext, 'utf8'), + fs.readFileSync(decrypted, 'utf8') + ); + }); + + it(`should create a crypto key version`, async () => { + const output = await exec( + `node createCryptoKeyVersion ${projectId} "${keyRingName}" "${keyNameOne}"` + ); + assert.match( + output, + new RegExp(`Crypto key version ${formattedKeyName}/cryptoKeyVersions/`) + ); + assert.match(output, new RegExp(` created.`)); + }); + + it(`should list crypto key versions`, async () => { + const output = await exec( + `node listCryptoKeyVersions.js ${projectId} "${keyRingName}" "${keyNameOne}"` + ); + assert.match(output, new RegExp(`${formattedKeyName}/cryptoKeyVersions/1`)); + }); + + it(`should destroy a crypto key version`, async () => { + const output = await exec( + `node destroyCryptoKeyVersion ${projectId} "${keyRingName}" "${keyNameOne}" 2` + ); + assert.match( + output, + new RegExp( + `Crypto key version ${formattedKeyName}/cryptoKeyVersions/2 destroyed.` + ) + ); + }); + + it(`should restore a crypto key version`, async () => { + const output = await exec( + `node restoreCryptoKeyVersion ${projectId} "${keyRingName}" "${keyNameOne}" 2` + ); + assert.match( + output, + new RegExp( + `Crypto key version ${formattedKeyName}/cryptoKeyVersions/2 restored.` + ) + ); + }); + + it(`should enable a crypto key version`, async () => { + const output = await exec( + `node enableCryptoKeyVersion ${projectId} "${keyRingName}" "${keyNameOne}" 2` + ); + assert.match( + output, + new RegExp( + `Crypto key version ${formattedKeyName}/cryptoKeyVersions/2 enabled.` + ) + ); + }); + + it(`should disable a crypto key version`, async () => { + const output = await exec( + `node disableCryptoKeyVersion ${projectId} "${keyRingName}" "${keyNameOne}" 2` + ); + assert.match( + output, + new RegExp( + `Crypto key version ${formattedKeyName}/cryptoKeyVersions/2 disabled.` + ) + ); + }); + + it(`should get a crypto key's empty IAM policy`, async () => { + const output = await exec( + `node getCryptoKeyIamPolicy ${projectId} "${keyRingName}" "${keyNameOne}"` + ); + assert.match( + output, + new RegExp(`Policy for crypto key ${keyNameOne} is empty.`) + ); + }); + + it(`should grant access to a crypto key`, async () => { + const output = await exec( + `node addMemberToCryptoKeyPolicy ${projectId} "${keyRingName}" "${keyNameOne}" "${member}" "${role}"` + ); + assert.match( + output, + new RegExp( + `${member}/${role} combo added to policy for crypto key ${keyNameOne}.` + ) + ); + }); + + it(`should get a crypto key's updated IAM policy`, async () => { + const output = await exec( + `node getCryptoKeyIamPolicy ${projectId} "${keyRingName}" "${keyNameOne}"` + ); + assert.match(output, new RegExp(`${role}:`)); + assert.match(output, new RegExp(` ${member}`)); + }); + + it(`should revoke access to a crypto key`, async () => { + const output = await exec( + `node removeMemberCryptoKeyPolicy ${projectId} "${keyRingName}" "${keyNameOne}" ${member} ${role}` + ); + assert.match( + output, + new RegExp( + `${member}/${role} combo removed from policy for crypto key ${keyNameOne}.` + ) + ); + }); +});