Nenhuma descrição
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

secretManager.js 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.ensureServiceAgentRole = exports.setIamPolicy = exports.getIamPolicy = exports.addVersion = exports.deleteSecret = exports.patchSecret = exports.createSecret = exports.toSecretVersionResourceName = exports.parseSecretVersionResourceName = exports.parseSecretResourceName = exports.secretExists = exports.destroySecretVersion = exports.accessSecretVersion = exports.getSecretVersion = exports.listSecretVersions = exports.getSecretMetadata = exports.listSecrets = exports.getSecret = exports.secretManagerConsoleUri = void 0;
  4. const utils_1 = require("../utils");
  5. const error_1 = require("../error");
  6. const apiv2_1 = require("../apiv2");
  7. const api_1 = require("../api");
  8. const SECRET_NAME_REGEX = new RegExp("projects\\/" +
  9. "(?<project>(?:\\d+)|(?:[A-Za-z]+[A-Za-z\\d-]*[A-Za-z\\d]?))\\/" +
  10. "secrets\\/" +
  11. "(?<secret>[A-Za-z\\d\\-_]+)");
  12. const SECRET_VERSION_NAME_REGEX = new RegExp(SECRET_NAME_REGEX.source + "\\/versions\\/" + "(?<version>latest|[0-9]+)");
  13. const secretManagerConsoleUri = (projectId) => `https://console.cloud.google.com/security/secret-manager?project=${projectId}`;
  14. exports.secretManagerConsoleUri = secretManagerConsoleUri;
  15. const API_VERSION = "v1";
  16. const client = new apiv2_1.Client({ urlPrefix: api_1.secretManagerOrigin, apiVersion: API_VERSION });
  17. async function getSecret(projectId, name) {
  18. var _a;
  19. const getRes = await client.get(`projects/${projectId}/secrets/${name}`);
  20. const secret = parseSecretResourceName(getRes.body.name);
  21. secret.labels = (_a = getRes.body.labels) !== null && _a !== void 0 ? _a : {};
  22. return secret;
  23. }
  24. exports.getSecret = getSecret;
  25. async function listSecrets(projectId, filter) {
  26. var _a;
  27. const secrets = [];
  28. const path = `projects/${projectId}/secrets`;
  29. const baseOpts = filter ? { queryParams: { filter } } : {};
  30. let pageToken = "";
  31. while (true) {
  32. const opts = pageToken === ""
  33. ? baseOpts
  34. : Object.assign(Object.assign({}, baseOpts), { queryParams: Object.assign(Object.assign({}, baseOpts === null || baseOpts === void 0 ? void 0 : baseOpts.queryParams), { pageToken }) });
  35. const res = await client.get(path, opts);
  36. for (const s of res.body.secrets || []) {
  37. secrets.push(Object.assign(Object.assign({}, parseSecretResourceName(s.name)), { labels: (_a = s.labels) !== null && _a !== void 0 ? _a : {} }));
  38. }
  39. if (!res.body.nextPageToken) {
  40. break;
  41. }
  42. pageToken = res.body.nextPageToken;
  43. }
  44. return secrets;
  45. }
  46. exports.listSecrets = listSecrets;
  47. async function getSecretMetadata(projectId, secretName, version) {
  48. const secretInfo = {};
  49. try {
  50. secretInfo.secret = await getSecret(projectId, secretName);
  51. secretInfo.secretVersion = getSecretVersion(projectId, secretName, version);
  52. }
  53. catch (err) {
  54. if (err.status !== 404) {
  55. throw err;
  56. }
  57. }
  58. return secretInfo;
  59. }
  60. exports.getSecretMetadata = getSecretMetadata;
  61. async function listSecretVersions(projectId, name, filter) {
  62. const secrets = [];
  63. const path = `projects/${projectId}/secrets/${name}/versions`;
  64. const baseOpts = filter ? { queryParams: { filter } } : {};
  65. let pageToken = "";
  66. while (true) {
  67. const opts = pageToken === ""
  68. ? baseOpts
  69. : Object.assign(Object.assign({}, baseOpts), { queryParams: Object.assign(Object.assign({}, baseOpts === null || baseOpts === void 0 ? void 0 : baseOpts.queryParams), { pageToken }) });
  70. const res = await client.get(path, opts);
  71. for (const s of res.body.versions || []) {
  72. secrets.push(Object.assign(Object.assign({}, parseSecretVersionResourceName(s.name)), { state: s.state }));
  73. }
  74. if (!res.body.nextPageToken) {
  75. break;
  76. }
  77. pageToken = res.body.nextPageToken;
  78. }
  79. return secrets;
  80. }
  81. exports.listSecretVersions = listSecretVersions;
  82. async function getSecretVersion(projectId, name, version) {
  83. const getRes = await client.get(`projects/${projectId}/secrets/${name}/versions/${version}`);
  84. return Object.assign(Object.assign({}, parseSecretVersionResourceName(getRes.body.name)), { state: getRes.body.state });
  85. }
  86. exports.getSecretVersion = getSecretVersion;
  87. async function accessSecretVersion(projectId, name, version) {
  88. const res = await client.get(`projects/${projectId}/secrets/${name}/versions/${version}:access`);
  89. return Buffer.from(res.body.payload.data, "base64").toString();
  90. }
  91. exports.accessSecretVersion = accessSecretVersion;
  92. async function destroySecretVersion(projectId, name, version) {
  93. if (version === "latest") {
  94. const sv = await getSecretVersion(projectId, name, "latest");
  95. version = sv.versionId;
  96. }
  97. await client.post(`projects/${projectId}/secrets/${name}/versions/${version}:destroy`);
  98. }
  99. exports.destroySecretVersion = destroySecretVersion;
  100. async function secretExists(projectId, name) {
  101. try {
  102. await getSecret(projectId, name);
  103. return true;
  104. }
  105. catch (err) {
  106. if (err.status === 404) {
  107. return false;
  108. }
  109. throw err;
  110. }
  111. }
  112. exports.secretExists = secretExists;
  113. function parseSecretResourceName(resourceName) {
  114. const match = SECRET_NAME_REGEX.exec(resourceName);
  115. if (!(match === null || match === void 0 ? void 0 : match.groups)) {
  116. throw new error_1.FirebaseError(`Invalid secret resource name [${resourceName}].`);
  117. }
  118. return {
  119. projectId: match.groups.project,
  120. name: match.groups.secret,
  121. };
  122. }
  123. exports.parseSecretResourceName = parseSecretResourceName;
  124. function parseSecretVersionResourceName(resourceName) {
  125. const match = resourceName.match(SECRET_VERSION_NAME_REGEX);
  126. if (!(match === null || match === void 0 ? void 0 : match.groups)) {
  127. throw new error_1.FirebaseError(`Invalid secret version resource name [${resourceName}].`);
  128. }
  129. return {
  130. secret: {
  131. projectId: match.groups.project,
  132. name: match.groups.secret,
  133. },
  134. versionId: match.groups.version,
  135. };
  136. }
  137. exports.parseSecretVersionResourceName = parseSecretVersionResourceName;
  138. function toSecretVersionResourceName(secretVersion) {
  139. return `projects/${secretVersion.secret.projectId}/secrets/${secretVersion.secret.name}/versions/${secretVersion.versionId}`;
  140. }
  141. exports.toSecretVersionResourceName = toSecretVersionResourceName;
  142. async function createSecret(projectId, name, labels) {
  143. const createRes = await client.post(`projects/${projectId}/secrets`, {
  144. name,
  145. replication: {
  146. automatic: {},
  147. },
  148. labels,
  149. }, { queryParams: { secretId: name } });
  150. return Object.assign(Object.assign({}, parseSecretResourceName(createRes.body.name)), { labels });
  151. }
  152. exports.createSecret = createSecret;
  153. async function patchSecret(projectId, name, labels) {
  154. const fullName = `projects/${projectId}/secrets/${name}`;
  155. const res = await client.patch(fullName, { name: fullName, labels }, { queryParams: { updateMask: "labels" } });
  156. return parseSecretResourceName(res.body.name);
  157. }
  158. exports.patchSecret = patchSecret;
  159. async function deleteSecret(projectId, name) {
  160. const path = `projects/${projectId}/secrets/${name}`;
  161. await client.delete(path);
  162. }
  163. exports.deleteSecret = deleteSecret;
  164. async function addVersion(projectId, name, payloadData) {
  165. const res = await client.post(`projects/${projectId}/secrets/${name}:addVersion`, {
  166. payload: {
  167. data: Buffer.from(payloadData).toString("base64"),
  168. },
  169. });
  170. return Object.assign(Object.assign({}, parseSecretVersionResourceName(res.body.name)), { state: res.body.state });
  171. }
  172. exports.addVersion = addVersion;
  173. async function getIamPolicy(secret) {
  174. const res = await client.get(`projects/${secret.projectId}/secrets/${secret.name}:getIamPolicy`);
  175. return res.body;
  176. }
  177. exports.getIamPolicy = getIamPolicy;
  178. async function setIamPolicy(secret, bindings) {
  179. await client.post(`projects/${secret.projectId}/secrets/${secret.name}:setIamPolicy`, {
  180. policy: {
  181. bindings,
  182. },
  183. updateMask: "bindings",
  184. });
  185. }
  186. exports.setIamPolicy = setIamPolicy;
  187. async function ensureServiceAgentRole(secret, serviceAccountEmails, role) {
  188. const policy = await module.exports.getIamPolicy(secret);
  189. const bindings = policy.bindings || [];
  190. let binding = bindings.find((b) => b.role === role);
  191. if (!binding) {
  192. binding = { role, members: [] };
  193. bindings.push(binding);
  194. }
  195. let shouldShortCircuit = true;
  196. for (const serviceAccount of serviceAccountEmails) {
  197. if (!binding.members.find((m) => m === `serviceAccount:${serviceAccount}`)) {
  198. binding.members.push(`serviceAccount:${serviceAccount}`);
  199. shouldShortCircuit = false;
  200. }
  201. }
  202. if (shouldShortCircuit)
  203. return;
  204. await module.exports.setIamPolicy(secret, bindings);
  205. (0, utils_1.logLabeledSuccess)("secretmanager", `Granted ${role} on projects/${secret.projectId}/secrets/${secret.name} to ${serviceAccountEmails.join(", ")}`);
  206. }
  207. exports.ensureServiceAgentRole = ensureServiceAgentRole;