Skip to content
Draft
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
3 changes: 1 addition & 2 deletions __tests__/proxy-integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ integration('ProxyBuilder', () => {
}
]

const cachedMode = true
const builder = new ProxyBuilder(docker, PROXY_IMAGE_NAME, cachedMode)
const builder = new ProxyBuilder(docker, PROXY_IMAGE_NAME)

beforeAll(async () => {
await ImageService.pull(PROXY_IMAGE_NAME)
Expand Down
60 changes: 57 additions & 3 deletions __tests__/proxy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {Updater} from '../src/updater'
type ProxyTestResources = {
container: Container
containerRemove: jest.Mock
createContainer: jest.Mock
externalNetworkRemove: jest.Mock
internalNetworkRemove: jest.Mock
proxy: Proxy
Expand All @@ -20,7 +21,8 @@ const alreadyStoppedError = (): Error =>
async function buildProxyWithStopError(
stopError: Error,
containerRemoveError?: Error,
containerRemoveOverride?: jest.Mock
containerRemoveOverride?: jest.Mock,
experiments: object = {}
): Promise<ProxyTestResources> {
const containerRemove =
containerRemoveOverride ??
Expand Down Expand Up @@ -48,15 +50,16 @@ async function buildProxyWithStopError(
const internalNetwork = {
remove: internalNetworkRemove
} as unknown as Network
const createContainer = jest.fn().mockResolvedValue(container)
const docker = {
listNetworks: jest.fn().mockResolvedValue([]),
createNetwork: jest
.fn()
.mockResolvedValueOnce(externalNetwork)
.mockResolvedValueOnce(internalNetwork),
createContainer: jest.fn().mockResolvedValue(container)
createContainer
} as unknown as Docker
const proxy = await new ProxyBuilder(docker, 'proxy-image', false).run(
const proxy = await new ProxyBuilder(docker, 'proxy-image', experiments).run(
1,
'job-token',
'https://dependabot-api.example.com',
Expand All @@ -66,6 +69,7 @@ async function buildProxyWithStopError(
return {
container,
containerRemove,
createContainer,
externalNetworkRemove,
internalNetworkRemove,
proxy
Expand Down Expand Up @@ -107,6 +111,56 @@ function buildUpdaterWithProxy(proxy: Proxy): {
}
}

describe('Proxy config', () => {
it('forwards experiments without changing their names or values', async () => {
const experiments = {
'proxy-read-only-git-credentials': true,
disabled: false,
timeout: 30,
mode: 'strict',
configuration: {enabled: true}
}
const storeInput = jest
.spyOn(ContainerService, 'storeInput')
.mockResolvedValue(undefined)

try {
await buildProxyWithStopError(
alreadyStoppedError(),
undefined,
undefined,
experiments
)

expect(storeInput).toHaveBeenCalledWith(
'config.json',
'/',
expect.anything(),
expect.objectContaining({
all_credentials: [],
experiments
})
)
} finally {
storeInput.mockRestore()
}
})
})

describe('Proxy environment', () => {
it('always enables the proxy cache', async () => {
const {createContainer} = await buildProxyWithStopError(
alreadyStoppedError()
)

expect(createContainer).toHaveBeenCalledWith(
expect.objectContaining({
Env: expect.arrayContaining(['PROXY_CACHE=true'])
})
)
})
})

describe('Proxy readiness', () => {
it('checks readiness inside the proxy container network namespace', async () => {
const {container, proxy} = await buildProxyWithStopError(
Expand Down
36 changes: 18 additions & 18 deletions __tests__/updater-builder-integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ integration('UpdaterBuilder', () => {
})

it('createUpdaterContainer returns a container only connected to the internal network', async () => {
const cachedMode = true
const proxy = await new ProxyBuilder(
docker,
PROXY_IMAGE_NAME,
cachedMode
).run(1, dependabotApiUrl, jobToken, credentials)
const proxy = await new ProxyBuilder(docker, PROXY_IMAGE_NAME).run(
1,
jobToken,
dependabotApiUrl,
credentials
)
await proxy.container.start()
const input = {job: details}
const params = new JobParameters(
Expand Down Expand Up @@ -79,12 +79,12 @@ integration('UpdaterBuilder', () => {
it('passes through OPENSSL_FORCE_FIPS_MODE when set on host', async () => {
process.env.OPENSSL_FORCE_FIPS_MODE = '0'

const cachedMode = true
const proxy = await new ProxyBuilder(
docker,
PROXY_IMAGE_NAME,
cachedMode
).run(1, dependabotApiUrl, jobToken, credentials)
const proxy = await new ProxyBuilder(docker, PROXY_IMAGE_NAME).run(
1,
jobToken,
dependabotApiUrl,
credentials
)
await proxy.container.start()
const input = {job: details}
const params = new JobParameters(
Expand Down Expand Up @@ -116,12 +116,12 @@ integration('UpdaterBuilder', () => {
it('does not set OPENSSL_FORCE_FIPS_MODE when not set on host', async () => {
delete process.env.OPENSSL_FORCE_FIPS_MODE

const cachedMode = true
const proxy = await new ProxyBuilder(
docker,
PROXY_IMAGE_NAME,
cachedMode
).run(1, dependabotApiUrl, jobToken, credentials)
const proxy = await new ProxyBuilder(docker, PROXY_IMAGE_NAME).run(
1,
jobToken,
dependabotApiUrl,
credentials
)
await proxy.container.start()
const input = {job: details}
const params = new JobParameters(
Expand Down
25 changes: 25 additions & 0 deletions __tests__/updater.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,31 @@ describe('Updater', () => {
expect(await updater.runUpdater()).toBe(true)
})

it('passes job experiments to the proxy builder', async () => {
const jobDetails = {
...mockJobDetails,
experiments: {
'proxy-read-only-git-credentials': true,
'other-experiment': true
}
}
const updaterWithExperiment = new Updater(
'MOCK_UPDATER_IMAGE_NAME',
'MOCK_PROXY_IMAGE_NAME',
mockApiClient,
jobDetails,
[]
)

await updaterWithExperiment.runUpdater()

expect(ProxyBuilder).toHaveBeenCalledWith(
expect.any(Docker),
'MOCK_PROXY_IMAGE_NAME',
jobDetails.experiments
)
})

it('does not start the updater until the proxy is ready', async () => {
const {promise, resolve} = Promise.withResolvers<void>()
mockProxy.waitUntilReady.mockReturnValueOnce(promise)
Expand Down
21 changes: 11 additions & 10 deletions dist/main.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/config-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ export type CertificateAuthority = {
export type ProxyConfig = {
all_credentials: Credential[]
ca: CertificateAuthority
experiments: object
}
10 changes: 7 additions & 3 deletions src/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class ProxyBuilder {
constructor(
private readonly docker: Docker,
private readonly proxyImage: string,
private readonly cachedMode: boolean
private readonly experiments: object = {}
) {}

async run(
Expand Down Expand Up @@ -213,7 +213,11 @@ export class ProxyBuilder {
private buildProxyConfig(credentials: Credential[]): ProxyConfig {
const ca = this.generateCertificateAuthority()

const config: ProxyConfig = {all_credentials: credentials, ca}
const config: ProxyConfig = {
all_credentials: credentials,
ca,
experiments: this.experiments
}

return config
}
Expand Down Expand Up @@ -292,7 +296,7 @@ export class ProxyBuilder {
`no_proxy=${process.env.no_proxy || process.env.NO_PROXY || ''}`,
`JOB_ID=${jobId}`,
`JOB_TOKEN=${jobToken}`,
`PROXY_CACHE=${this.cachedMode ? 'true' : 'false'}`,
'PROXY_CACHE=true',
`DEPENDABOT_API_URL=${dependabotApiUrl}`,
`ACTIONS_ID_TOKEN_REQUEST_TOKEN=${process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN || ''}`,
`ACTIONS_ID_TOKEN_REQUEST_URL=${process.env.ACTIONS_ID_TOKEN_REQUEST_URL || ''}`,
Expand Down
7 changes: 2 additions & 5 deletions src/updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,12 @@ export class Updater {
* Execute an update job and report the result to Dependabot API.
*/
async runUpdater(): Promise<boolean> {
const cachedMode = Object.hasOwn(
this.details.experiments ?? {},
'proxy-cached'
)
const experiments = this.details.experiments ?? {}

const proxyBuilder = new ProxyBuilder(
this.docker,
this.proxyImage,
cachedMode
experiments
)

const proxy = await proxyBuilder.run(
Expand Down
Loading