buildx: resolveCertsDriverOpts

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax 2023-02-10 12:08:44 +01:00
parent b223e0a42b
commit ec7bb99421
No known key found for this signature in database
GPG Key ID: 3248E46B6BB8C7F7
3 changed files with 150 additions and 0 deletions

View File

@ -24,6 +24,8 @@ import * as exec from '@actions/exec';
import {Buildx} from '../../src/buildx/buildx';
import {Context} from '../../src/context';
import {Cert} from '../../src/types/buildx';
// prettier-ignore
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildx-jest').split(path.sep).join(path.posix.sep);
const tmpName = path.join(tmpDir, '.tmpname-jest').split(path.sep).join(path.posix.sep);
@ -192,3 +194,88 @@ describe('versionSatisfies', () => {
expect(await buildx.versionSatisfies(range, version)).toBe(expected);
});
});
describe('resolveCertsDriverOpts', () => {
const originalEnv = process.env;
beforeEach(() => {
jest.resetModules();
process.env = {
...originalEnv,
BUILDX_CONFIG: path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx')
};
});
afterEach(() => {
process.env = originalEnv;
rimraf.sync(path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx'));
});
// prettier-ignore
test.each([
[
1,
'mycontext',
'docker-container',
{},
[],
[]
],
[
2,
'docker-container://mycontainer',
'docker-container',
{},
[],
[]
],
[
3,
'tcp://graviton2:1234',
'remote',
{},
[],
[]
],
[
4,
'tcp://graviton2:1234',
'remote',
{
cacert: 'foo',
cert: 'foo',
key: 'foo',
} as Cert,
[
path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'cacert_graviton2-1234.pem'),
path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'cert_graviton2-1234.pem'),
path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'key_graviton2-1234.pem')
],
[
`cacert=${path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'cacert_graviton2-1234.pem')}`,
`cert=${path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'cert_graviton2-1234.pem')}`,
`key=${path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'key_graviton2-1234.pem')}`
]
],
[
5,
'tcp://mybuilder:1234',
'docker-container',
{
cacert: 'foo',
cert: 'foo',
key: 'foo',
} as Cert,
[
path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'cacert_mybuilder-1234.pem'),
path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'cert_mybuilder-1234.pem'),
path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'key_mybuilder-1234.pem')
],
[]
],
])('%p. given %p endpoint, %p driver', async (id: number, endpoint: string, driver: string, cert: Cert, expectedFiles: Array<string>, expectedOpts: Array<string>) => {
fs.mkdirSync(Buildx.certsDir, {recursive: true});
expect(Buildx.resolveCertsDriverOpts(driver, endpoint, cert)).toEqual(expectedOpts);
for (const k in expectedFiles) {
const file = expectedFiles[k];
expect(fs.existsSync(file)).toBe(true);
}
});
});

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
import fs from 'fs';
import path from 'path';
import * as exec from '@actions/exec';
import * as semver from 'semver';
@ -23,6 +24,8 @@ import {Context} from '../context';
import {Inputs} from './inputs';
import {Install} from './install';
import {Cert} from '../types/buildx';
export interface BuildxOpts {
context: Context;
standalone?: boolean;
@ -126,4 +129,43 @@ export class Buildx {
}
return semver.satisfies(ver, range) || /^[0-9a-f]{7}$/.exec(ver) !== null;
}
public static resolveCertsDriverOpts(driver: string, endpoint: string, cert: Cert): Array<string> {
let url: URL;
try {
url = new URL(endpoint);
} catch (e) {
return [];
}
if (url.protocol != 'tcp:') {
return [];
}
const driverOpts: Array<string> = [];
if (Object.keys(cert).length == 0) {
return driverOpts;
}
let host = url.hostname;
if (url.port.length > 0) {
host += `-${url.port}`;
}
if (cert.cacert !== undefined) {
const cacertpath = path.join(Buildx.certsDir, `cacert_${host}.pem`);
fs.writeFileSync(cacertpath, cert.cacert);
driverOpts.push(`cacert=${cacertpath}`);
}
if (cert.cert !== undefined) {
const certpath = path.join(Buildx.certsDir, `cert_${host}.pem`);
fs.writeFileSync(certpath, cert.cert);
driverOpts.push(`cert=${certpath}`);
}
if (cert.key !== undefined) {
const keypath = path.join(Buildx.certsDir, `key_${host}.pem`);
fs.writeFileSync(keypath, cert.key);
driverOpts.push(`key=${keypath}`);
}
if (driver != 'remote') {
return [];
}
return driverOpts;
}
}

21
src/types/buildx.ts Normal file
View File

@ -0,0 +1,21 @@
/**
* Copyright 2023 actions-toolkit authors
*
* 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 interface Cert {
cacert?: string;
cert?: string;
key?: string;
}