Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright 2025 GoodRx, Inc.
*
* 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 { Knex } from 'knex';

export async function up(knex: Knex): Promise<void> {
await knex.raw(`
UPDATE global_config
SET config = (
(config::jsonb || '{
"barbican": {
"enabled": true,
"clusterSecretStore": "barbican-secretsmanager",
"refreshInterval": "1h",
"allowedPrefixes": []
}
}'::jsonb)
|| jsonb_set(
config::jsonb,
'{gcp,clusterSecretStore}',
'"gcp-secretsmanager"'::jsonb
)
)::json,
"updatedAt" = now()
WHERE key = 'secretProviders';
`);
}

export async function down(knex: Knex): Promise<void> {
await knex.raw(`
UPDATE global_config
SET config = (
(config::jsonb - 'barbican')
|| jsonb_set(
config::jsonb,
'{gcp,clusterSecretStore}',
'"gcp-secretmanager"'::jsonb
)
)::json,
"updatedAt" = now()
WHERE key = 'secretProviders';
`);
}
24 changes: 12 additions & 12 deletions src/server/lib/envVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export abstract class EnvironmentVariables {
buildUUID: string,
fullYamlSupport: boolean,
build: Build,
additionalVariables?: Record<string, any>
additionalVariables?: Record<string, any>,
): Promise<Record<string, any>> {
let availableEnv: Record<string, any>;

Expand Down Expand Up @@ -185,7 +185,7 @@ export abstract class EnvironmentVariables {

if (build == null) {
throw Error(
'Critical problem. Attempt retrieving environment Variables from empty build, which should NEVER happen.'
'Critical problem. Attempt retrieving environment Variables from empty build, which should NEVER happen.',
);
}

Expand All @@ -196,7 +196,7 @@ export abstract class EnvironmentVariables {
throw new LifecycleError(
build.runUUID,
'',
'Critical problem. Missing associated deploys with the build, which should NEVER happen.'
'Critical problem. Missing associated deploys with the build, which should NEVER happen.',
);
}

Expand All @@ -219,7 +219,7 @@ export abstract class EnvironmentVariables {
*/
async configurationServiceEnvironments(
deploys: Deploy[],
fullYamlSupport: boolean
fullYamlSupport: boolean,
): Promise<Array<Record<string, any>>> {
const configurationDeploys = deploys.filter((deploy) => {
const serviceType: DeployTypes = fullYamlSupport ? deploy.deployable?.type : deploy.service?.type;
Expand All @@ -237,7 +237,7 @@ export abstract class EnvironmentVariables {
.where('key', deploy.branchName)
.first();
}
})
}),
);

return _.compact(configurations.map((configuration) => (configuration ? configuration.data : null)));
Expand All @@ -262,7 +262,7 @@ export abstract class EnvironmentVariables {
envString: Record<string, any>,
availableEnv: Record<string, string>,
useDefaultUUID: boolean,
namespace: string
namespace: string,
) {
const str = JSON.stringify(envString || '').replace(/-/g, HYPHEN_REPLACEMENT);
return await this.compileEnvironmentWithAvailableEnvironment(str, availableEnv, useDefaultUUID, namespace);
Expand All @@ -278,7 +278,7 @@ export abstract class EnvironmentVariables {
environment: string,
availableEnv: Record<string, any>,
useDefaultUUID: boolean,
namespace: string
namespace: string,
) {
return await this.customRender(environment, availableEnv, useDefaultUUID, namespace);
}
Expand Down Expand Up @@ -306,7 +306,7 @@ export abstract class EnvironmentVariables {
* @returns the rendered template
*/
async customRender(template, data, useDefaultUUID = true, namespace: string) {
const secretPatternRegex = /\{\{(aws|gcp):([^}]+)\}\}/g;
const secretPatternRegex = /\{\{(aws|gcp|barbican|vault|onepassword):([^}]+)\}\}/g;
const secretPlaceholders: Map<string, string> = new Map();
let placeholderIndex = 0;

Expand Down Expand Up @@ -364,7 +364,7 @@ export abstract class EnvironmentVariables {
if (captureGroup.includes('_internalHostname')) {
template = template.replace(
fullMatch,
this.buildHostname({ host: data[captureGroup], suffix, rest, namespace: nsForDeploy })
this.buildHostname({ host: data[captureGroup], suffix, rest, namespace: nsForDeploy }),
);
}
continue;
Expand All @@ -378,14 +378,14 @@ export abstract class EnvironmentVariables {
const defaultedInternalHostname = serviceToUpdate.replace(/_internalHostname$/, `-${defaultUuid}`);
template = template.replace(
fullMatch,
this.buildHostname({ host: defaultedInternalHostname, namespace: staticEnvNamespace, suffix, rest })
this.buildHostname({ host: defaultedInternalHostname, namespace: staticEnvNamespace, suffix, rest }),
);
}
if (captureGroup.includes('_publicUrl')) {
const serviceToUpdate = captureGroup.replace(HYPHEN_REPLACEMENT_REGEX, '-');
const defaultedPublicUrl = serviceToUpdate.replace(
/_publicUrl$/,
`-${globalConfig.lifecycleDefaults.defaultPublicUrl}`
`-${globalConfig.lifecycleDefaults.defaultPublicUrl}`,
);
getLogger().debug(`publicUrl for ${serviceToUpdate} defaulted to ${defaultedPublicUrl} using global_config`);
template = template.replace(fullMatch, defaultedPublicUrl);
Expand All @@ -405,6 +405,6 @@ export abstract class EnvironmentVariables {
// eslint-disable-next-line no-unused-vars
build: Build,
// eslint-disable-next-line no-unused-vars
webhook?: any
webhook?: any,
): Promise<Record<string, any>>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ describe('externalSecret', () => {
providerConfig,
});

expect(manifest.apiVersion).toBe('external-secrets.io/v1beta1');
expect(manifest.apiVersion).toBe('external-secrets.io/v1');
expect(manifest.kind).toBe('ExternalSecret');
expect(manifest.metadata.name).toBe('api-server-aws-secrets');
expect(manifest.metadata.namespace).toBe('lfc-abc123');
Expand Down
2 changes: 1 addition & 1 deletion src/server/lib/kubernetes/externalSecret.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export function generateExternalSecretManifest(options: GenerateExternalSecretOp
}

return {
apiVersion: 'external-secrets.io/v1beta1',
apiVersion: 'external-secrets.io/v1',
kind: 'ExternalSecret',
metadata: {
name: secretName,
Expand Down
4 changes: 2 additions & 2 deletions src/server/lib/secretRefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export interface ValidationResult {
error?: string;
}

const SECRET_REF_REGEX = /^\{\{(aws|gcp):([^:}]+)(?::([^}]+))?\}\}$/;
const SECRET_REF_REGEX = /^\{\{(aws|gcp|barbican|vault|onepassword):([^:}]+)(?::([^}]+))?\}\}$/;

export function isSecretRef(value: string): boolean {
if (!value || typeof value !== 'string') {
Expand Down Expand Up @@ -65,7 +65,7 @@ export function parseSecretRef(value: string): SecretRef | null {

export function validateSecretRef(
ref: SecretRef,
secretProviders: SecretProvidersConfig | undefined
secretProviders: SecretProvidersConfig | undefined,
): ValidationResult {
if (!secretProviders) {
return { valid: false, error: `Secret provider '${ref.provider}' not configured` };
Expand Down
Loading