From 3d001a3bcf088de347c5da045bca7c07b2f514d2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 3 May 2022 15:58:26 +0200 Subject: [PATCH] scaffolder-backend-module-rails: add allowedImageNames option Signed-off-by: Patrik Oldsberg --- .changeset/fluffy-poems-sell.md | 5 ++++ .../scaffolder-backend-module-rails/README.md | 13 ++++++++ .../api-report.md | 1 + .../src/actions/fetch/rails/index.test.ts | 30 +++++++++++++++++++ .../src/actions/fetch/rails/index.ts | 12 ++++---- .../src/actions/fetch/rails/railsNewRunner.ts | 3 ++ 6 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 .changeset/fluffy-poems-sell.md diff --git a/.changeset/fluffy-poems-sell.md b/.changeset/fluffy-poems-sell.md new file mode 100644 index 0000000000..07588225c9 --- /dev/null +++ b/.changeset/fluffy-poems-sell.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-rails': minor +--- + +**BREAKING**: Added a new `allowedImageNames` option, which needs to list any image name for it to be allowed as `imageName` input. diff --git a/plugins/scaffolder-backend-module-rails/README.md b/plugins/scaffolder-backend-module-rails/README.md index 182f741845..9d1316473d 100644 --- a/plugins/scaffolder-backend-module-rails/README.md +++ b/plugins/scaffolder-backend-module-rails/README.md @@ -246,3 +246,16 @@ steps: system: ${{ parameters.system }} railsArguments: ${{ parameters.railsArguments }} ``` + +You also need to configure the list of allowed images as part of the creating the action for the scaffolder backend: + +```typescript +const actions = [ + createFetchRailsAction({ + integrations, + reader: env.reader, + containerRunner, + allowedImageNames: ['repository/rails:tag'], + }), +]; +``` diff --git a/plugins/scaffolder-backend-module-rails/api-report.md b/plugins/scaffolder-backend-module-rails/api-report.md index aa631c5333..551da91314 100644 --- a/plugins/scaffolder-backend-module-rails/api-report.md +++ b/plugins/scaffolder-backend-module-rails/api-report.md @@ -14,6 +14,7 @@ export function createFetchRailsAction(options: { reader: UrlReader; integrations: ScmIntegrations; containerRunner: ContainerRunner; + allowedImageNames?: string[]; }): TemplateAction<{ url: string; targetPath?: string | undefined; diff --git a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.test.ts b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.test.ts index 0a6a996aa8..597847130a 100644 --- a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.test.ts +++ b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.test.ts @@ -86,6 +86,7 @@ describe('fetch:rails', () => { integrations, reader: mockReader, containerRunner, + allowedImageNames: ['foo/rails-custom-image'], }); beforeEach(() => { @@ -138,6 +139,35 @@ describe('fetch:rails', () => { }); }); + it('should not allow unknown images', async () => { + await expect( + action.handler({ + ...mockContext, + input: { + ...mockContext.input, + imageName: 'foo/bar', + }, + }), + ).rejects.toThrow('Image foo/bar is not allowed'); + }); + + it('should not allow any images', async () => { + const action2 = createFetchRailsAction({ + integrations, + reader: mockReader, + containerRunner, + }); + await expect( + action2.handler({ + ...mockContext, + input: { + ...mockContext.input, + imageName: 'foo/rails-custom-image', + }, + }), + ).rejects.toThrow('Image foo/rails-custom-image is not allowed'); + }); + it('should throw if the target directory is outside of the workspace path', async () => { await expect( action.handler({ diff --git a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts index 132929ee1c..d1a9ed7650 100644 --- a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts +++ b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts @@ -41,6 +41,8 @@ export function createFetchRailsAction(options: { reader: UrlReader; integrations: ScmIntegrations; containerRunner: ContainerRunner; + /** A list of image names that are allowed to be passed as imageName input */ + allowedImageNames?: string[]; }) { const { reader, integrations, containerRunner } = options; @@ -177,16 +179,16 @@ export function createFetchRailsAction(options: { const templateRunner = new RailsNewRunner({ containerRunner }); - const values = { - ...ctx.input.values, - imageName: ctx.input.imageName, - }; + const { imageName } = ctx.input; + if (imageName && !options.allowedImageNames?.includes(imageName)) { + throw new Error(`Image ${imageName} is not allowed`); + } // Will execute the template in ./template and put the result in ./result await templateRunner.run({ workspacePath: workDir, logStream: ctx.logStream, - values, + values: { ...ctx.input.values, imageName }, }); // Finally move the template result into the task workspace diff --git a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/railsNewRunner.ts b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/railsNewRunner.ts index 4a4672795a..0ed02e293c 100644 --- a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/railsNewRunner.ts +++ b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/railsNewRunner.ts @@ -74,6 +74,9 @@ export class RailsNewRunner { logStream, }); } else { + if (!imageName) { + throw new Error('No imageName provided'); + } const arrayExtraArguments = railsArgumentResolver( '/input', railsArguments as RailsRunOptions,