0

I'm trying to write a function that adds a new Google Secret Manager version, and then destroys the previous old version.

I can add a new version easily, but to destroy the old version I need it's version number.

As per these docs I have tried to get the new secret version number via const [version] = await secrets.addSecretVersion() and then minus 1 from that.

But TypeScript is complaining that version is not a number:

The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.ts(2362)

Here is my code for adding a new version and deleteing the old version:

const addSecretVersion = async (secretName: string, value: string) => {
  const parent = `projects/my-project/secrets/${secretName}`;
  const payload = Buffer.from(value, 'utf8');
  // Add the new secret
  const [version] = await secrets.addSecretVersion({
    parent: parent,
    payload: {
      data: payload,
    },
  });
  const oldVersionNumber = version - 1; //<--- TypeScript error here
  // Destroy the old secret (to avoid billing)
  const oldSecret = `projects/my-project/secrets/${secretName}/versions/${oldVersionNumber}`;
  await secrets.destroySecretVersion({
    name: oldSecret,
  });
};
TinyTiger
  • 1,801
  • 7
  • 47
  • 92

3 Answers3

0

Figured it out.

version is an object that looks like this:

{
   "destroyTime":null,
   "state":"ENABLED",
   "etag":"\"9999999999\"",
   "createTime":{
      "seconds":"9999999999",
      "nanos":9999999999
   },
   "clientSpecifiedPayloadChecksum":false,
   "name":"projects/9999999999/secrets/secret-name/versions/109",
   "replicationStatus":{
      "automatic":{
         "customerManagedEncryption":null
      },
      "replicationStatus":"automatic"
   }
}

So I used this to access the new version number and thus create the old version number:

const newVersionNumber = Number(newVersion.name?.split('/').pop());
const oldVersionNumber = newVersionNumber - 1;

Here is the full code:

const addSecretVersion = async (secretName: string, value: string) => {
  const parent = `projects/my-projects/secrets/${secretName}`;
  const payload = Buffer.from(value, 'utf8');
  // Add the new secret
  const [newVersion] = await secrets.addSecretVersion({
    parent: parent,
    payload: {
      data: payload,
    },
  });
  const newVersionNumber = Number(newVersionName.name?.split('/').pop());
  const oldVersionNumber = newVersionNumber - 1;
  // Destroy the old secret (to avoid billing)
  const oldSecret = `projects/my-projects/secrets/${secretName}/versions/${oldVersionNumber}`;
  await secrets.destroySecretVersion({
    name: oldSecret,
  });
};
TinyTiger
  • 1,801
  • 7
  • 47
  • 92
0

Simple use this endpoint by passing your resource path like below:

In go, return fmt.Sprintf("%s/versions/latest", g.appSecretPath(name))

The disadvantage of your approach is that it does not check for the version state, which means if there are 3 versions, you add a new version, say 4, and 3rd version is already in DISABLED state, your code breaks, so, you need to handle that case as well. Just make sure you are disabling the old ENABLED version of the secret. Although feel free to go ahead if that is sufficient for you.

ashwa
  • 1
  • 1
-1

name": string, "createTime": string, "destroyTime": string, "CA": enum (CA), "replicationStatus": { object (ReplicationStatus) }, "etag": string, "clientSpecifiedPayloadChecksum":

  • 1
    As it’s currently written, your answer is unclear and you did not use proper formatting for the "code" portion of the answer. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the [help] center. – George 2.0 Hope Jul 09 '22 at 02:04