Add support to the new backend system, including customization
Signed-off-by: ivgo <ivgo@spreadgroup.com>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
---
|
||||
'@backstage/plugin-vault-backend': minor
|
||||
---
|
||||
|
||||
Added support for the [new backend system](https://backstage.io/docs/backend-system/).
|
||||
|
||||
In your `packages/backend/src/index.ts` make the following changes:
|
||||
|
||||
```diff
|
||||
import { createBackend } from '@backstage/backend-defaults';
|
||||
const backend = createBackend();
|
||||
// ... other feature additions
|
||||
+ backend.add(import('@backstage/plugin-vault-backend');
|
||||
backend.start();
|
||||
```
|
||||
|
||||
If you use the new backend system, the token renewal task can be defined via configuration file:
|
||||
|
||||
```diff
|
||||
vault:
|
||||
baseUrl: <BASE_URL>
|
||||
token: <TOKEN>
|
||||
schedule:
|
||||
+ frequency: ...
|
||||
+ timeout: ...
|
||||
+ # Other schedule options, such as scope or initialDelay
|
||||
```
|
||||
|
||||
If the `schedule` is omitted or set to `false` no token renewal task will be scheduled.
|
||||
If the value of `schedule` is set to `true` the renew will be scheduled hourly (the default).
|
||||
In other cases (like in the diff above), the defined schedule will be used.
|
||||
|
||||
**DEPRECATIONS**: The interface `VaultApi` and the type `VaultSecret` are now deprecated. Import them from `@backstage/plugin-vault-node`.
|
||||
@@ -68,6 +68,9 @@ To get started, first you need a running instance of Vault. You can follow [this
|
||||
token: <VAULT_TOKEN>
|
||||
secretEngine: 'customSecretEngine' # Optional. By default it uses 'secrets'. Can be overwritten by the annotation of the entity
|
||||
kvVersion: <kv-version> # Optional. The K/V version that your instance is using. The available options are '1' or '2'
|
||||
schedule: # Optional. If the token renewal is enabled this schedule will be used instead of the hourly one
|
||||
frequency: { hours: 1 }
|
||||
timeout: { hours: 1 }
|
||||
```
|
||||
|
||||
4. Get a `VAULT_TOKEN` with **LIST** permissions, as it's enough for the plugin. You can check [this tutorial](https://learn.hashicorp.com/tutorials/vault/tokens) for more info.
|
||||
@@ -80,6 +83,24 @@ To get started, first you need a running instance of Vault. You can follow [this
|
||||
}
|
||||
```
|
||||
|
||||
## New Backend System
|
||||
|
||||
The Vault backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up:
|
||||
|
||||
In your `packages/backend/src/index.ts` make the following changes:
|
||||
|
||||
```diff
|
||||
import { createBackend } from '@backstage/backend-defaults';
|
||||
const backend = createBackend();
|
||||
// ... other feature additions
|
||||
+ backend.add(import('@backstage/plugin-vault-backend');
|
||||
backend.start();
|
||||
```
|
||||
|
||||
The token renewal is enabled automatically in the new backend system depending on the `app-config.yaml`. If the `schedule` is not defined there, no
|
||||
task will be executed. If you want to use the default renewal scheduler (which runs hourly), set `schedule: true`. In case you want a custom schedule
|
||||
just use a configuration like the one set above.
|
||||
|
||||
## Integration with the Catalog
|
||||
|
||||
The plugin can be integrated into each Component in the catalog. To allow listing the available secrets a new annotation must be added to the `catalog-info.yaml`:
|
||||
@@ -122,7 +143,7 @@ That will overwrite the default secret engine from the configuration.
|
||||
|
||||
## Renew token
|
||||
|
||||
In a secure Vault instance, it's usual that the tokens are refreshed after some time. In order to always have a valid token to fetch the secrets, it might be necessary to execute a renew action after some time. By default this is deactivated, but it can be easily activated and configured to be executed periodically (hourly by default, but customizable by the user). In order to do that, modify your `src/plugins/vault.ts` file to look like this one:
|
||||
In a secure Vault instance, it's usual that the tokens are refreshed after some time. In order to always have a valid token to fetch the secrets, it might be necessary to execute a renew action after some time. By default this is deactivated, but it can be easily activated and configured to be executed periodically (hourly by default, but customizable by the user within the app-config.yaml file). In order to do that, modify your `src/plugins/vault.ts` file to look like this one:
|
||||
|
||||
```typescript
|
||||
import { VaultBuilder } from '@backstage/plugin-vault-backend';
|
||||
@@ -149,6 +170,8 @@ export default async function createPlugin(
|
||||
}
|
||||
```
|
||||
|
||||
If the `taskRunner` is not set when calling the `enableTokenRenew`, the plugin will automatically check what is set in the `app-config.yaml` file. Refer to [the new backend system setup](#new-backend-system) for more information about it.
|
||||
|
||||
## Features
|
||||
|
||||
- List the secrets present in a certain path
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { Config } from '@backstage/config';
|
||||
import express from 'express';
|
||||
import { Logger } from 'winston';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { PluginTaskScheduler } from '@backstage/backend-tasks';
|
||||
import { TaskRunner } from '@backstage/backend-tasks';
|
||||
|
||||
@@ -22,7 +24,7 @@ export interface RouterOptions {
|
||||
scheduler: PluginTaskScheduler;
|
||||
}
|
||||
|
||||
// @public
|
||||
// @public @deprecated
|
||||
export interface VaultApi {
|
||||
getFrontendSecretsUrl(): string;
|
||||
listSecrets(
|
||||
@@ -69,12 +71,16 @@ export interface VaultEnvironment {
|
||||
// (undocumented)
|
||||
config: Config;
|
||||
// (undocumented)
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
// (undocumented)
|
||||
scheduler: PluginTaskScheduler;
|
||||
}
|
||||
|
||||
// @public
|
||||
const vaultPlugin: () => BackendFeature;
|
||||
export default vaultPlugin;
|
||||
|
||||
// @public @deprecated
|
||||
export type VaultSecret = {
|
||||
name: string;
|
||||
path: string;
|
||||
|
||||
Vendored
+7
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { TaskScheduleDefinitionConfig } from '@backstage/backend-tasks';
|
||||
|
||||
/** Configuration for the Vault plugin */
|
||||
export interface Config {
|
||||
@@ -44,5 +45,11 @@ export interface Config {
|
||||
* The version of the K/V API. Defaults to `2`.
|
||||
*/
|
||||
kvVersion?: 1 | 2;
|
||||
|
||||
/**
|
||||
* If set to true, the default schedule (hourly) will be used. If a
|
||||
* different schedule is set, this will be used instead.
|
||||
* */
|
||||
schedule?: TaskScheduleDefinitionConfig | boolean;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -34,9 +34,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "workspace:^",
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/backend-tasks": "workspace:^",
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/errors": "workspace:^",
|
||||
"@backstage/plugin-vault-node": "workspace:^",
|
||||
"@types/express": "*",
|
||||
"compression": "^1.7.4",
|
||||
"cors": "^2.8.5",
|
||||
|
||||
@@ -17,3 +17,4 @@
|
||||
export * from './service/router';
|
||||
export * from './service/VaultBuilder';
|
||||
export * from './service/vaultApi';
|
||||
export { vaultPlugin as default } from './service/plugin';
|
||||
|
||||
@@ -16,11 +16,17 @@
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
import { InputError } from '@backstage/errors';
|
||||
import { Logger } from 'winston';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import express from 'express';
|
||||
import Router from 'express-promise-router';
|
||||
import { VaultApi, VaultClient } from './vaultApi';
|
||||
import { TaskRunner, PluginTaskScheduler } from '@backstage/backend-tasks';
|
||||
import {
|
||||
PluginTaskScheduler,
|
||||
TaskRunner,
|
||||
TaskScheduleDefinition,
|
||||
TaskScheduleDefinitionConfig,
|
||||
readTaskScheduleDefinitionFromConfig,
|
||||
} from '@backstage/backend-tasks';
|
||||
import { errorHandler } from '@backstage/backend-common';
|
||||
|
||||
/**
|
||||
@@ -28,7 +34,7 @@ import { errorHandler } from '@backstage/backend-common';
|
||||
* @public
|
||||
*/
|
||||
export interface VaultEnvironment {
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
config: Config;
|
||||
scheduler: PluginTaskScheduler;
|
||||
}
|
||||
@@ -101,18 +107,16 @@ export class VaultBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the token renewal for Vault.
|
||||
* Enables the token renewal for Vault. The schedule if configured in the app-config.yaml file.
|
||||
* If not set, the renewal is executed hourly
|
||||
*
|
||||
* @param schedule - The TaskRunner used to schedule the renewal, if not set, renewing hourly
|
||||
* @returns
|
||||
*/
|
||||
public async enableTokenRenew(schedule?: TaskRunner) {
|
||||
const taskRunner = schedule
|
||||
? schedule
|
||||
: this.env.scheduler.createScheduledTaskRunner({
|
||||
frequency: { hours: 1 },
|
||||
timeout: { hours: 1 },
|
||||
});
|
||||
: this.env.scheduler.createScheduledTaskRunner(this.getConfigSchedule());
|
||||
|
||||
await taskRunner.run({
|
||||
id: 'refresh-vault-token',
|
||||
fn: async () => {
|
||||
@@ -124,6 +128,24 @@ export class VaultBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
private getConfigSchedule(): TaskScheduleDefinition {
|
||||
const schedule = this.env.config.getOptional<
|
||||
TaskScheduleDefinitionConfig | boolean
|
||||
>('vault.schedule');
|
||||
|
||||
const scheduleCfg =
|
||||
schedule !== undefined && schedule !== false
|
||||
? {
|
||||
frequency: { hours: 1 },
|
||||
timeout: { hours: 1 },
|
||||
}
|
||||
: readTaskScheduleDefinitionFromConfig(
|
||||
this.env.config.getConfig('vault.schedule'),
|
||||
);
|
||||
|
||||
return scheduleCfg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the backend routes for Vault.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2021 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.
|
||||
*/
|
||||
import { vaultPlugin } from './plugin';
|
||||
|
||||
describe('vault', () => {
|
||||
it('should export the vault plugin', () => {
|
||||
expect(vaultPlugin).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
import {
|
||||
coreServices,
|
||||
createBackendPlugin,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { VaultApi, vaultExtensionPoint } from '@backstage/plugin-vault-node';
|
||||
import { VaultBuilder } from './VaultBuilder';
|
||||
import { TaskScheduleDefinitionConfig } from '@backstage/backend-tasks';
|
||||
|
||||
/**
|
||||
* Vault backend plugin
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const vaultPlugin = createBackendPlugin({
|
||||
pluginId: 'vault',
|
||||
register(env) {
|
||||
let client: VaultApi | undefined;
|
||||
|
||||
env.registerExtensionPoint(vaultExtensionPoint, {
|
||||
setClient(vaultClient) {
|
||||
if (client) {
|
||||
throw new Error('The vault client has been already set');
|
||||
}
|
||||
client = vaultClient;
|
||||
},
|
||||
});
|
||||
|
||||
env.registerInit({
|
||||
deps: {
|
||||
logger: coreServices.logger,
|
||||
config: coreServices.rootConfig,
|
||||
scheduler: coreServices.scheduler,
|
||||
httpRouter: coreServices.httpRouter,
|
||||
},
|
||||
async init({ logger, config, scheduler, httpRouter }) {
|
||||
let builder = VaultBuilder.createBuilder({
|
||||
logger,
|
||||
config,
|
||||
scheduler,
|
||||
});
|
||||
|
||||
if (client) {
|
||||
builder = builder.setVaultClient(client);
|
||||
}
|
||||
|
||||
const scheduleCfg = config.getOptional<
|
||||
boolean | TaskScheduleDefinitionConfig
|
||||
>('vault.schedule');
|
||||
if (scheduleCfg !== undefined && scheduleCfg !== false) {
|
||||
builder = await builder.enableTokenRenew();
|
||||
}
|
||||
|
||||
const { router } = builder.build();
|
||||
httpRouter.use(router);
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -33,6 +33,7 @@ export type VaultSecretList = {
|
||||
/**
|
||||
* Object containing the secret name and some links
|
||||
* @public
|
||||
* @deprecated Use the interface from `@backstage/plugin-vault-node`
|
||||
*/
|
||||
export type VaultSecret = {
|
||||
name: string;
|
||||
@@ -53,6 +54,7 @@ type RenewTokenResponse = {
|
||||
/**
|
||||
* Interface for the Vault API
|
||||
* @public
|
||||
* @deprecated Use the interface from `@backstage/plugin-vault-node`
|
||||
*/
|
||||
export interface VaultApi {
|
||||
/**
|
||||
|
||||
@@ -9904,6 +9904,7 @@ __metadata:
|
||||
resolution: "@backstage/plugin-vault-backend@workspace:plugins/vault-backend"
|
||||
dependencies:
|
||||
"@backstage/backend-common": "workspace:^"
|
||||
"@backstage/backend-plugin-api": "workspace:^"
|
||||
"@backstage/backend-tasks": "workspace:^"
|
||||
"@backstage/backend-test-utils": "workspace:^"
|
||||
"@backstage/cli": "workspace:^"
|
||||
|
||||
Reference in New Issue
Block a user