backend-app-api: add signing keys migration

Signed-off-by: Vincenzo Scamporlino <vincenzos@spotify.com>
This commit is contained in:
Vincenzo Scamporlino
2024-03-27 11:59:02 +01:00
parent eca60af9f7
commit f1a0569506
3 changed files with 70 additions and 3 deletions
@@ -0,0 +1,43 @@
/*
* Copyright 2024 The Backstage Authors
*
* 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
*
* http://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.
*/
// @ts-check
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = async function up(knex) {
await knex.schema.createTable('signing_keys', table => {
table
.string('id')
.primary()
.notNullable()
.comment('The unique ID of a public key');
table.text('keys').notNullable().comment('JSON serialized public key');
table.timestamp('expires_at').notNullable();
});
};
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = async function down(knex) {
return knex.schema.dropTable('signing_keys');
};
+2 -1
View File
@@ -100,6 +100,7 @@
"files": [
"dist",
"config.d.ts",
"alpha"
"alpha",
"migrations/**/*.{js,d.ts}"
]
}
@@ -15,6 +15,7 @@
*/
import {
DatabaseService,
PublicKeyStoreService,
coreServices,
createServiceFactory,
@@ -22,6 +23,7 @@ import {
import { DateTime } from 'luxon';
import { Knex } from 'knex';
import { JsonObject } from '@backstage/types';
import { resolvePackagePath } from '@backstage/backend-common';
const TABLE = 'signing_keys';
@@ -33,7 +35,17 @@ type Row = {
/** @internal */
export class DatabaseKeyStore implements PublicKeyStoreService {
constructor(private readonly client: Knex) {}
private constructor(private readonly client: Knex) {}
static async create(options: { database: DatabaseService }) {
const { database } = options;
const client = await database.getClient();
if (!database.migrations?.skip) {
await applyDatabaseMigrations(client);
}
return new DatabaseKeyStore(client);
}
async addKey(options: {
id: string;
@@ -72,7 +84,7 @@ export const publicKeyStoreServiceFactory = createServiceFactory({
database: coreServices.database,
},
async factory({ database }) {
return new DatabaseKeyStore(await database.getClient());
return DatabaseKeyStore.create({ database });
},
});
@@ -90,3 +102,14 @@ function parseDate(date: string | Date) {
return parsedDate.toJSDate();
}
export function applyDatabaseMigrations(knex: Knex): Promise<void> {
const migrationsDir = resolvePackagePath(
'@backstage/backend-app-api',
'migrations',
);
return knex.migrate.latest({
directory: migrationsDir,
});
}