Fix comments on GoogleGcsUrlReader
Signed-off-by: Martina Iglesias Fernandez <martina@roadie.io>
This commit is contained in:
+6
-30
@@ -17,12 +17,12 @@
|
||||
import { ConfigReader, JsonObject } from '@backstage/config';
|
||||
import { getVoidLogger } from '../logging';
|
||||
import { ReadTreeResponseFactory } from './tree';
|
||||
import { GcsUrlReader } from './GcsUrlReader';
|
||||
import { GoogleGcsUrlReader } from './GoogleGcsUrlReader';
|
||||
import { UrlReaderPredicateTuple } from './types';
|
||||
|
||||
describe('GcsUrlReader', () => {
|
||||
const createReader = (config: JsonObject): UrlReaderPredicateTuple[] => {
|
||||
return GcsUrlReader.factory({
|
||||
return GoogleGcsUrlReader.factory({
|
||||
config: new ConfigReader(config),
|
||||
logger: getVoidLogger(),
|
||||
treeResponseFactory: ReadTreeResponseFactory.create({
|
||||
@@ -57,43 +57,19 @@ describe('GcsUrlReader', () => {
|
||||
expect(entries).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('does not create a reader if the privateKey is missing', () => {
|
||||
it('creates a reader with default credentials provider', () => {
|
||||
const entries = createReader({
|
||||
integrations: {
|
||||
googleGcs: [
|
||||
{
|
||||
clientEmail: 'someone@example.com',
|
||||
},
|
||||
],
|
||||
googleGcs: [{}],
|
||||
},
|
||||
});
|
||||
expect(entries).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('does not create a reader if the clientEmail is missing', () => {
|
||||
const entries = createReader({
|
||||
integrations: {
|
||||
googleGcs: [
|
||||
{
|
||||
privateKey:
|
||||
'-----BEGIN PRIVATE KEY----- fakekey -----END PRIVATE KEY-----',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
expect(entries).toHaveLength(0);
|
||||
expect(entries).toHaveLength(1);
|
||||
});
|
||||
|
||||
describe('predicates', () => {
|
||||
const readers = createReader({
|
||||
integrations: {
|
||||
googleGcs: [
|
||||
{
|
||||
privateKey:
|
||||
'-----BEGIN PRIVATE KEY----- fakekey -----END PRIVATE KEY-----',
|
||||
clientEmail: 'someone@example.com',
|
||||
},
|
||||
],
|
||||
googleGcs: [{}],
|
||||
},
|
||||
});
|
||||
const predicate = readers[0].predicate;
|
||||
+26
-34
@@ -22,13 +22,17 @@ import {
|
||||
UrlReader,
|
||||
} from './types';
|
||||
import getRawBody from 'raw-body';
|
||||
import {
|
||||
GOOGLE_GCS_HOST,
|
||||
readGoogleGcsIntegrationConfigs,
|
||||
} from '@backstage/integration';
|
||||
|
||||
const parseURL = (
|
||||
url: string,
|
||||
): { host: string; bucket: string; key: string } => {
|
||||
const { host, pathname } = new URL(url);
|
||||
|
||||
if (host !== 'storage.cloud.google.com') {
|
||||
if (host !== GOOGLE_GCS_HOST) {
|
||||
throw new Error(`not a valid GCS URL: ${url}`);
|
||||
}
|
||||
|
||||
@@ -40,45 +44,33 @@ const parseURL = (
|
||||
};
|
||||
};
|
||||
|
||||
export class GcsUrlReader implements UrlReader {
|
||||
export class GoogleGcsUrlReader implements UrlReader {
|
||||
static factory: ReaderFactory = ({ config, logger }) => {
|
||||
if (!config.has('integrations.googleGcs')) {
|
||||
return [];
|
||||
}
|
||||
const configs = config.getOptionalConfigArray('integrations.googleGcs');
|
||||
if (!configs) {
|
||||
return [];
|
||||
}
|
||||
return configs
|
||||
.filter(integration => {
|
||||
if (!integration.has('clientEmail') || !integration.has('privateKey')) {
|
||||
logger.warn(
|
||||
"Skipping gcs integration, Missing required config value at 'integration.gcs.clientEmail' or 'integration.gcs.privateKey'",
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map(integration => {
|
||||
const privKey = integration
|
||||
.getOptionalString('privateKey')
|
||||
?.split('\\n')
|
||||
.join('\n');
|
||||
|
||||
const storage = new Storage({
|
||||
const configs = readGoogleGcsIntegrationConfigs(
|
||||
config.getOptionalConfigArray('integrations.googleGcs') ?? [],
|
||||
);
|
||||
return configs.map(integration => {
|
||||
let storage: Storage;
|
||||
if (!integration.clientEmail || !integration.privateKey) {
|
||||
logger.warn(
|
||||
'googleGcs credentials not found in config. Using default credentials provider.',
|
||||
);
|
||||
storage = new Storage();
|
||||
} else {
|
||||
storage = new Storage({
|
||||
credentials: {
|
||||
client_email: integration.getOptionalString('clientEmail'),
|
||||
private_key: privKey,
|
||||
client_email: integration.clientEmail || undefined,
|
||||
private_key: integration.privateKey || undefined,
|
||||
},
|
||||
});
|
||||
const reader = new GcsUrlReader(storage);
|
||||
const host =
|
||||
integration.getOptionalString('host') || 'storage.cloud.google.com';
|
||||
|
||||
logger.info('Configuring integration, gcs');
|
||||
const predicate = (url: URL) => url.host === host;
|
||||
return { reader, predicate };
|
||||
});
|
||||
}
|
||||
const reader = new GoogleGcsUrlReader(storage);
|
||||
const predicate = (url: URL) => url.host === GOOGLE_GCS_HOST;
|
||||
return { reader, predicate };
|
||||
});
|
||||
};
|
||||
|
||||
constructor(private readonly storage: Storage) {}
|
||||
@@ -104,6 +96,6 @@ export class GcsUrlReader implements UrlReader {
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `gcs{host=storage.cloud.google.com,authed=true}}`;
|
||||
return `gcs{host=${GOOGLE_GCS_HOST},authed=true}}`;
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import { GithubUrlReader } from './GithubUrlReader';
|
||||
import { GitlabUrlReader } from './GitlabUrlReader';
|
||||
import { ReadTreeResponseFactory } from './tree';
|
||||
import { FetchUrlReader } from './FetchUrlReader';
|
||||
import { GcsUrlReader } from './GcsUrlReader';
|
||||
import { GoogleGcsUrlReader } from './GoogleGcsUrlReader';
|
||||
|
||||
type CreateOptions = {
|
||||
/** Root config object */
|
||||
@@ -71,7 +71,7 @@ export class UrlReaders {
|
||||
BitbucketUrlReader.factory,
|
||||
GithubUrlReader.factory,
|
||||
GitlabUrlReader.factory,
|
||||
GcsUrlReader.factory,
|
||||
GoogleGcsUrlReader.factory,
|
||||
FetchUrlReader.factory,
|
||||
]),
|
||||
});
|
||||
|
||||
Vendored
+14
@@ -149,5 +149,19 @@ export interface Config {
|
||||
*/
|
||||
baseUrl?: string;
|
||||
}>;
|
||||
|
||||
/** Integration configuration for Google Cloud Storage */
|
||||
googleGcs?: Array<{
|
||||
/**
|
||||
* Service account email used to authenticate requests.
|
||||
* @visibility secret
|
||||
*/
|
||||
clientEmail?: string;
|
||||
/**
|
||||
* Service account private key used to authenticate requests.
|
||||
* @visibility secret
|
||||
*/
|
||||
privateKey?: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Config, ConfigReader } from '@backstage/config';
|
||||
import {
|
||||
GoogleGcsIntegrationConfig,
|
||||
readGoogleGcsIntegrationConfig,
|
||||
readGoogleGcsIntegrationConfigs,
|
||||
} from './config';
|
||||
|
||||
describe('readGoogleGcsIntegrationConfig', () => {
|
||||
function buildConfig(data: Partial<GoogleGcsIntegrationConfig>): Config {
|
||||
return new ConfigReader(data);
|
||||
}
|
||||
|
||||
it('reads all values', () => {
|
||||
const output = readGoogleGcsIntegrationConfig(
|
||||
buildConfig({
|
||||
privateKey: 'fake-key',
|
||||
clientEmail: 'someone@example.com',
|
||||
}),
|
||||
);
|
||||
expect(output).toEqual({
|
||||
privateKey: 'fake-key',
|
||||
token: 'someone@example.com',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('readGoogleGcsIntegrationConfigs', () => {
|
||||
function buildConfig(data: Partial<GoogleGcsIntegrationConfig>[]): Config[] {
|
||||
return data.map(item => new ConfigReader(item));
|
||||
}
|
||||
|
||||
it('reads all values', () => {
|
||||
const output = readGoogleGcsIntegrationConfigs(
|
||||
buildConfig([
|
||||
{
|
||||
privateKey: 'fake-key',
|
||||
clientEmail: 'someone@example.com',
|
||||
},
|
||||
]),
|
||||
);
|
||||
expect(output).toContainEqual({
|
||||
privateKey: 'fake-key',
|
||||
clientEmail: 'someone@example.com',
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
/**
|
||||
* The configuration parameters for a single Google Cloud Storage provider.
|
||||
*/
|
||||
export type GoogleGcsIntegrationConfig = {
|
||||
/**
|
||||
* Service account email used to authenticate requests.
|
||||
*/
|
||||
clientEmail?: string;
|
||||
/**
|
||||
* Service account private key used to authenticate requests.
|
||||
*/
|
||||
privateKey?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reads a single Google GCS integration config.
|
||||
*
|
||||
* @param config The config object of a single integration
|
||||
*/
|
||||
export function readGoogleGcsIntegrationConfig(
|
||||
config: Config,
|
||||
): GoogleGcsIntegrationConfig {
|
||||
if (!config.has('clientEmail') || !config.has('privateKey')) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const privateKey = config
|
||||
.getOptionalString('privateKey')
|
||||
?.split('\\n')
|
||||
.join('\n');
|
||||
|
||||
const clientEmail = config.getOptionalString('clientEmail');
|
||||
return { clientEmail: clientEmail, privateKey: privateKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a set of Google Cloud Storage integration configs.
|
||||
*
|
||||
* @param configs All of the integration config objects
|
||||
*/
|
||||
export function readGoogleGcsIntegrationConfigs(
|
||||
configs: Config[],
|
||||
): GoogleGcsIntegrationConfig[] {
|
||||
return configs.map(readGoogleGcsIntegrationConfig);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export {
|
||||
readGoogleGcsIntegrationConfig,
|
||||
readGoogleGcsIntegrationConfigs,
|
||||
} from './config';
|
||||
export type { GoogleGcsIntegrationConfig } from './config';
|
||||
export const GOOGLE_GCS_HOST = 'storage.cloud.google.com';
|
||||
@@ -18,6 +18,7 @@ export * from './azure';
|
||||
export * from './bitbucket';
|
||||
export * from './github';
|
||||
export * from './gitlab';
|
||||
export * from './googleGcs';
|
||||
export { defaultScmResolveUrl } from './helpers';
|
||||
export { ScmIntegrations } from './ScmIntegrations';
|
||||
export type {
|
||||
|
||||
Reference in New Issue
Block a user