scaffolder-backend: gitlab preparer uses integrations token

This commit is contained in:
Fredrik Adelöw
2020-12-18 15:56:17 +01:00
parent 04ac603cd1
commit 33a82a7137
4 changed files with 66 additions and 20 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
GitLab preparer uses the right token (primarily the same one as the publisher, falling back to the integrations token)
+1
View File
@@ -32,6 +32,7 @@
"@backstage/backend-common": "^0.4.1",
"@backstage/catalog-model": "^0.6.0",
"@backstage/config": "^0.1.2",
"@backstage/integration": "^0.1.4",
"@gitbeaker/core": "^25.2.0",
"@gitbeaker/node": "^25.2.0",
"@octokit/rest": "^18.0.0",
@@ -42,7 +42,7 @@ const mockEntityWithProtocol = (protocol: string): TemplateEntityV1alpha1 => ({
name: 'graphql-starter',
title: 'GraphQL Service',
description:
'A GraphQL starter template for backstage to get you up and running\nthe best pracices with GraphQL\n',
'A GraphQL starter template for backstage to get you up and running\nthe best practices with GraphQL\n',
uid: '9cf16bad-16e0-4213-b314-c4eec773c50b',
etag: 'ZTkxMjUxMjUtYWY3Yi00MjU2LWFkYWMtZTZjNjU5ZjJhOWM2',
generation: 1,
@@ -89,16 +89,41 @@ describe('GitLabPreparer', () => {
);
});
it(`calls the clone command with the correct arguments if an access token is provided for a repository using the ${protocol} protocol`, async () => {
it(`calls the clone command with the correct arguments if an access token is provided in integrations for a repository using the ${protocol} protocol`, async () => {
const preparer = new GitlabPreparer(
new ConfigReader({
catalog: {
processors: {
gitlabApi: {
privateToken: 'fake-token',
integrations: {
gitlab: [
{
host: 'gitlab.com',
token: 'fake-token',
},
],
},
}),
);
mockEntity = mockEntityWithProtocol(protocol);
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
expect(mocks.Clone.clone).toHaveBeenNthCalledWith(
1,
'https://gitlab.com/benjdlambert/backstage-graphql-template',
expect.any(String),
{
fetchOpts: {
callbacks: {
credentials: expect.anything(),
},
},
},
);
});
it(`calls the clone command with the correct arguments if an access token is provided in scaffolder for a repository using the ${protocol} protocol`, async () => {
const preparer = new GitlabPreparer(
new ConfigReader({
scaffolder: {
gitlab: { api: { token: 'fake-token' } },
},
}),
);
mockEntity = mockEntityWithProtocol(protocol);
@@ -13,24 +13,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import os from 'os';
import fs from 'fs-extra';
import path from 'path';
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
import { parseLocationAnnotation } from '../helpers';
import { InputError } from '@backstage/backend-common';
import { PreparerBase, PreparerOptions } from './types';
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import {
GitLabIntegrationConfig,
readGitLabIntegrationConfigs,
} from '@backstage/integration';
import fs from 'fs-extra';
import GitUriParser from 'git-url-parse';
import { Clone, Cred } from 'nodegit';
import { Config } from '@backstage/config';
import os from 'os';
import path from 'path';
import { parseLocationAnnotation } from '../helpers';
import { PreparerBase, PreparerOptions } from './types';
export class GitlabPreparer implements PreparerBase {
private readonly privateToken: string;
private readonly integrations: GitLabIntegrationConfig[];
private readonly scaffolderToken: string | undefined;
constructor(config: Config) {
this.privateToken =
config.getOptionalString('catalog.processors.gitlabApi.privateToken') ??
'';
this.integrations = readGitLabIntegrationConfigs(
config.getOptionalConfigArray('integrations.gitlab') ?? [],
);
this.scaffolderToken = config.getOptionalString(
'scaffolder.gitlab.api.token',
);
}
async prepare(
@@ -58,12 +66,12 @@ export class GitlabPreparer implements PreparerBase {
template.spec.path ?? '.',
);
const options = this.privateToken
const token = this.getToken(parsedGitLocation.resource);
const options = token
? {
fetchOpts: {
callbacks: {
credentials: () =>
Cred.userpassPlaintextNew('oauth2', this.privateToken),
credentials: () => Cred.userpassPlaintextNew('oauth2', token),
},
},
}
@@ -73,4 +81,11 @@ export class GitlabPreparer implements PreparerBase {
return path.resolve(tempDir, templateDirectory);
}
private getToken(host: string): string | undefined {
return (
this.scaffolderToken ||
this.integrations.find(c => c.host === host)?.token
);
}
}