Toolkit: implement plugin signing in grafana-toolkit (#27907)

* implement plugin signing in grafana-toolkit
This commit is contained in:
Dan Cech
2020-10-05 11:27:43 -04:00
committed by GitHub
parent ad0f071159
commit 4629c44d49
6 changed files with 171 additions and 8 deletions
+19 -2
View File
@@ -18,6 +18,7 @@ import { pluginUpdateTask } from './tasks/plugin.update';
import { ciBuildPluginDocsTask, ciBuildPluginTask, ciPackagePluginTask, ciPluginReportTask } from './tasks/plugin.ci';
import { buildPackageTask } from './tasks/package.build';
import { pluginCreateTask } from './tasks/plugin.create';
import { pluginSignTask } from './tasks/plugin.sign';
import { bundleManagedTask } from './tasks/plugin/bundle.managed';
import { componentCreateTask } from './tasks/component.create';
@@ -179,6 +180,19 @@ export const run = (includeInternalScripts = false) => {
});
});
program
.command('plugin:sign')
.option('--signatureType <type>', 'Signature Type')
.option('--rootUrls <urls...>', 'Root URLs')
.description('Create a plugin signature')
.action(async cmd => {
await execTask(pluginSignTask)({
signatureType: cmd.signatureType,
rootUrls: cmd.rootUrls,
silent: true,
});
});
program
.command('plugin:ci-build')
.option('--finish', 'move all results to the jobs folder', false)
@@ -200,11 +214,14 @@ export const run = (includeInternalScripts = false) => {
program
.command('plugin:ci-package')
.option('--signing-admin', 'Use the admin API endpoint for signing the manifest.', false)
.option('--signatureType <type>', 'Signature Type')
.option('--rootUrls <urls...>', 'Root URLs')
.option('--signing-admin', 'Use the admin API endpoint for signing the manifest. (deprecated)', false)
.description('Create a zip packages for the plugin')
.action(async cmd => {
await execTask(ciPackagePluginTask)({
signingAdmin: cmd.signingAdmin,
signatureType: cmd.signatureType,
rootUrls: cmd.rootUrls,
});
});
@@ -8,6 +8,7 @@ import execa = require('execa');
import path = require('path');
import fs from 'fs-extra';
import { getPackageDetails, getGrafanaVersions, readGitLog } from '../../plugins/utils';
import { buildManifest, signManifest, saveManifest } from '../../plugins/manifest';
import {
getJobFolder,
writeJobStats,
@@ -25,7 +26,8 @@ const rimraf = promisify(rimrafCallback);
export interface PluginCIOptions {
finish?: boolean;
upload?: boolean;
signingAdmin?: boolean;
signatureType?: string;
rootUrls?: string[];
maxJestWorkers?: string;
}
@@ -107,7 +109,7 @@ export const ciBuildPluginDocsTask = new Task<PluginCIOptions>('Build Plugin Doc
* 2. zip it into packages in `~/ci/packages`
* 3. prepare grafana environment in: `~/ci/grafana-test-env`
*/
const packagePluginRunner: TaskRunner<PluginCIOptions> = async ({ signingAdmin }) => {
const packagePluginRunner: TaskRunner<PluginCIOptions> = async ({ signatureType, rootUrls }) => {
const start = Date.now();
const ciDir = getCiFolder();
const packagesDir = path.resolve(ciDir, 'packages');
@@ -163,11 +165,16 @@ const packagePluginRunner: TaskRunner<PluginCIOptions> = async ({ signingAdmin }
});
// Write a MANIFEST.txt file in the dist folder
// By using the --signing-admin flag the plugin doesn't need to be in the plugins database to be signed,
// however it requires an Admin API key.
try {
const grabplCommandFlags = signingAdmin ? ['build-plugin-manifest', '--signing-admin'] : ['build-plugin-manifest'];
await execa('grabpl', [...grabplCommandFlags, distContentDir]);
const manifest = await buildManifest(distContentDir);
if (signatureType) {
manifest.signatureType = signatureType;
}
if (rootUrls) {
manifest.rootUrls = rootUrls;
}
const signedManifest = await signManifest(manifest);
await saveManifest(distContentDir, signedManifest);
} catch (err) {
console.warn(`Error signing manifest: ${distContentDir}`, err);
}
@@ -0,0 +1,38 @@
import path from 'path';
import { buildManifest, signManifest, saveManifest } from '../../plugins/manifest';
import { Task, TaskRunner } from './task';
interface PluginSignOptions {
signatureType?: string;
rootUrls?: string[];
}
const pluginSignRunner: TaskRunner<PluginSignOptions> = async ({ signatureType, rootUrls }) => {
const distContentDir = path.resolve('dist');
try {
console.log('Building manifest...');
const manifest = await buildManifest(distContentDir);
// console.log(manifest);
console.log('Signing manifest...');
if (signatureType) {
manifest.signatureType = signatureType;
}
if (rootUrls) {
manifest.rootUrls = rootUrls;
}
const signedManifest = await signManifest(manifest);
// console.log(signedManifest);
console.log('Saving signed manifest...');
await saveManifest(distContentDir, signedManifest);
console.log('Signed successfully');
} catch (err) {
console.warn(err);
}
};
export const pluginSignTask = new Task<PluginSignOptions>('plugin:sign task', pluginSignRunner);