Refactor azure publisher to use integrations

Co-authored-by: blam<ben@blam.sh>
This commit is contained in:
Johan Haals
2021-01-15 16:08:10 +01:00
parent 8ef84c67a3
commit fd876c3615
2 changed files with 72 additions and 24 deletions
@@ -15,22 +15,48 @@
*/
import { PublisherBase, PublisherOptions, PublisherResult } from './types';
import { GitApi } from 'azure-devops-node-api/GitApi';
import { IGitApi } from 'azure-devops-node-api/GitApi';
import { GitRepositoryCreateOptions } from 'azure-devops-node-api/interfaces/GitInterfaces';
import { JsonValue, Config } from '@backstage/config';
import { RequiredTemplateValues } from '../templater';
import { initRepoAndPush } from './helpers';
import { Config } from '@backstage/config';
import { initRepoAndPush } from './helpers';
import { Logger } from 'winston';
import {
AzureIntegrationConfig,
readAzureIntegrationConfigs,
} from '@backstage/integration';
import gitUrlParse from 'git-url-parse';
import { getPersonalAccessTokenHandler, WebApi } from 'azure-devops-node-api';
export class AzurePublisher implements PublisherBase {
private readonly client: GitApi;
private readonly token: string;
private readonly logger: Logger;
private readonly integrations: AzureIntegrationConfig[];
private readonly apiBaseUrl?: string;
private readonly token?: string;
constructor(config: Config, { logger }: { logger: Logger }) {
this.logger = logger;
this.client = client;
this.token = token;
this.integrations = readAzureIntegrationConfigs(
config.getOptionalConfigArray('integrations.azure') ?? [],
);
if (!this.integrations.length) {
logger.warn(
'Integrations for Azure in Scaffolder are not set. This will cause errors in a future release. Please migrate to using integrations config and specifying tokens under hostnames',
);
}
this.token = config.getOptionalString('scaffolder.azure.api.token');
if (this.token) {
logger.warn(
"DEPRECATION: Using the token format under 'scaffolder.github.api.token' will not be respected in future releases. Please consider using integrations config instead",
);
}
this.apiBaseUrl = config.getOptionalString('scaffolder.azure.api.baseUrl');
if (this.apiBaseUrl) {
logger.warn(
"DEPRECATION: Using the apiBaseUrl format under 'scaffolder.azure.api.baseUrl' will not be respected in future releases. Please consider using integrations config instead",
);
}
}
async publish({
@@ -38,7 +64,25 @@ export class AzurePublisher implements PublisherBase {
directory,
logger,
}: PublisherOptions): Promise<PublisherResult> {
const remoteUrl = await this.createRemote(values);
const { resource: host, owner, name } = gitUrlParse(values.storePath);
const token = this.getToken(host);
if (!token) {
throw new Error('No token provided to create the remote repository');
}
const baseUrl = this.getBaseUrl(host);
if (!baseUrl) {
throw new Error('No baseUrl provided to create the remote repository');
}
const authHandler = getPersonalAccessTokenHandler(token);
const webApi = new WebApi(baseUrl, authHandler);
const azureClient = await webApi.getGitApi();
const remoteUrl = await this.createRemote(azureClient, {
project: owner,
name,
});
const catalogInfoUrl = `${remoteUrl}?path=%2Fcatalog-info.yaml`;
await initRepoAndPush({
@@ -46,7 +90,7 @@ export class AzurePublisher implements PublisherBase {
remoteUrl,
auth: {
username: 'notempty',
password: this.token,
password: token,
},
logger,
});
@@ -55,13 +99,24 @@ export class AzurePublisher implements PublisherBase {
}
private async createRemote(
values: RequiredTemplateValues & Record<string, JsonValue>,
client: IGitApi,
opts: { name: string; project: string },
) {
const [project, name] = values.storePath.split('/');
// const [project, name] = values.storePath.split('/');
const { name, project } = opts;
const createOptions: GitRepositoryCreateOptions = { name };
const repo = await this.client.createRepository(createOptions, project);
const repo = await client.createRepository(createOptions, project);
return repo.remoteUrl || '';
}
private getToken(host: string): string | undefined {
return this.token || this.integrations.find(c => c.host === host)?.token;
}
private getBaseUrl(host: string): string | undefined {
return (
this.apiBaseUrl || this.integrations.find(c => c.host === host)?.host
);
}
}
@@ -118,14 +118,7 @@ export class Publishers implements PublisherBuilder {
const azureConfig = config.getOptionalConfig('scaffolder.azure');
if (azureConfig) {
try {
const baseUrl = azureConfig.getString('baseUrl');
const azureToken = azureConfig.getConfig('api').getString('token');
const authHandler = getPersonalAccessTokenHandler(azureToken);
const webApi = new WebApi(baseUrl, authHandler);
const azureClient = await webApi.getGitApi();
const azurePublisher = new AzurePublisher(azureClient, azureToken);
const azurePublisher = new AzurePublisher(config, { logger });
publishers.register('azure/api', azurePublisher);
} catch (e) {
const providerName = 'azure';