scaffolder-backend: gitlab preparer uses integrations token
This commit is contained in:
@@ -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)
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user