backend-app-api: add signing keys migration
Signed-off-by: Vincenzo Scamporlino <vincenzos@spotify.com>
This commit is contained in:
@@ -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');
|
||||
};
|
||||
@@ -100,6 +100,7 @@
|
||||
"files": [
|
||||
"dist",
|
||||
"config.d.ts",
|
||||
"alpha"
|
||||
"alpha",
|
||||
"migrations/**/*.{js,d.ts}"
|
||||
]
|
||||
}
|
||||
|
||||
+25
-2
@@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user