mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-02-11 13:35:28 +00:00
Move noProxy handling to separate module
Signed-off-by: Christina Ying Wang <christina@balena.io>
This commit is contained in:
parent
0cf5a4bf18
commit
725d7790fb
@ -3,7 +3,12 @@ import _ from 'lodash';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import * as applicationManager from './compose/application-manager';
|
import * as applicationManager from './compose/application-manager';
|
||||||
import { readHostname, setHostname } from './host-config/index';
|
import {
|
||||||
|
readHostname,
|
||||||
|
setHostname,
|
||||||
|
readNoProxy,
|
||||||
|
setNoProxy,
|
||||||
|
} from './host-config/index';
|
||||||
import * as dbus from './lib/dbus';
|
import * as dbus from './lib/dbus';
|
||||||
import { isENOENT } from './lib/errors';
|
import { isENOENT } from './lib/errors';
|
||||||
import { mkdirp, unlinkAll } from './lib/fs-utils';
|
import { mkdirp, unlinkAll } from './lib/fs-utils';
|
||||||
@ -30,7 +35,6 @@ const proxyFields = ['type', 'ip', 'port', 'login', 'password'];
|
|||||||
|
|
||||||
const proxyBasePath = pathOnBoot('system-proxy');
|
const proxyBasePath = pathOnBoot('system-proxy');
|
||||||
const redsocksConfPath = path.join(proxyBasePath, 'redsocks.conf');
|
const redsocksConfPath = path.join(proxyBasePath, 'redsocks.conf');
|
||||||
const noProxyPath = path.join(proxyBasePath, 'no_proxy');
|
|
||||||
|
|
||||||
interface ProxyConfig {
|
interface ProxyConfig {
|
||||||
[key: string]: string | string[] | number;
|
[key: string]: string | string[] | number;
|
||||||
@ -83,18 +87,9 @@ async function readProxy(): Promise<ProxyConfig | undefined> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
const noProxy = await readNoProxy();
|
||||||
const noProxy = await readFromBoot(noProxyPath, 'utf-8')
|
if (noProxy.length) {
|
||||||
// Prevent empty newline from being reported as a noProxy address
|
conf.noProxy = noProxy;
|
||||||
.then((addrs) => addrs.split('\n').filter((addr) => addr !== ''));
|
|
||||||
|
|
||||||
if (noProxy.length) {
|
|
||||||
conf.noProxy = noProxy;
|
|
||||||
}
|
|
||||||
} catch (e: unknown) {
|
|
||||||
if (!isENOENT(e)) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert port to number per API doc spec
|
// Convert port to number per API doc spec
|
||||||
@ -121,14 +116,15 @@ function generateRedsocksConfEntries(conf: ProxyConfig): string {
|
|||||||
|
|
||||||
async function setProxy(maybeConf: ProxyConfig | null): Promise<void> {
|
async function setProxy(maybeConf: ProxyConfig | null): Promise<void> {
|
||||||
if (_.isEmpty(maybeConf)) {
|
if (_.isEmpty(maybeConf)) {
|
||||||
await unlinkAll(redsocksConfPath, noProxyPath);
|
await unlinkAll(redsocksConfPath);
|
||||||
|
await setNoProxy([]);
|
||||||
} else {
|
} else {
|
||||||
// We know that maybeConf is not null due to the _.isEmpty check above,
|
// We know that maybeConf is not null due to the _.isEmpty check above,
|
||||||
// but the compiler doesn't
|
// but the compiler doesn't
|
||||||
const conf = maybeConf as ProxyConfig;
|
const conf = maybeConf as ProxyConfig;
|
||||||
await mkdirp(proxyBasePath);
|
await mkdirp(proxyBasePath);
|
||||||
if (Array.isArray(conf.noProxy)) {
|
if (Array.isArray(conf.noProxy)) {
|
||||||
await writeToBoot(noProxyPath, conf.noProxy.join('\n'));
|
await setNoProxy(conf.noProxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
let currentConf: ProxyConfig | undefined;
|
let currentConf: ProxyConfig | undefined;
|
||||||
|
@ -3,6 +3,8 @@ import { promises as fs } from 'fs';
|
|||||||
import * as config from '../config';
|
import * as config from '../config';
|
||||||
import { pathOnRoot } from '../lib/host-utils';
|
import { pathOnRoot } from '../lib/host-utils';
|
||||||
|
|
||||||
|
export * from './proxy';
|
||||||
|
|
||||||
const hostnamePath = pathOnRoot('/etc/hostname');
|
const hostnamePath = pathOnRoot('/etc/hostname');
|
||||||
|
|
||||||
export async function readHostname() {
|
export async function readHostname() {
|
||||||
|
36
src/host-config/proxy.ts
Normal file
36
src/host-config/proxy.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { promises as fs } from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
import { pathOnBoot, readFromBoot } from '../lib/host-utils';
|
||||||
|
import { unlinkAll } from '../lib/fs-utils';
|
||||||
|
import { isENOENT } from '../lib/errors';
|
||||||
|
|
||||||
|
const proxyBasePath = pathOnBoot('system-proxy');
|
||||||
|
const noProxyPath = path.join(proxyBasePath, 'no_proxy');
|
||||||
|
|
||||||
|
export async function readNoProxy(): Promise<string[]> {
|
||||||
|
try {
|
||||||
|
const noProxy = await readFromBoot(noProxyPath, 'utf-8')
|
||||||
|
// Prevent empty newline from being reported as a noProxy address
|
||||||
|
.then((addrs) => addrs.split('\n').filter((addr) => addr !== ''));
|
||||||
|
|
||||||
|
if (noProxy.length) {
|
||||||
|
return noProxy;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
} catch (e: unknown) {
|
||||||
|
if (!isENOENT(e)) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setNoProxy(list: string[]) {
|
||||||
|
if (!list || !Array.isArray(list) || !list.length) {
|
||||||
|
await unlinkAll(noProxyPath);
|
||||||
|
} else {
|
||||||
|
await fs.writeFile(noProxyPath, list.join('\n'));
|
||||||
|
}
|
||||||
|
}
|
@ -98,6 +98,42 @@ describe('host-config', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('noProxy', () => {
|
||||||
|
it('reads IPs to exclude from proxy', async () => {
|
||||||
|
expect(await hostConfig.readNoProxy()).to.deep.equal([
|
||||||
|
'152.10.30.4',
|
||||||
|
'253.1.1.0/16',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets IPs to exclude from proxy', async () => {
|
||||||
|
await hostConfig.setNoProxy(['balena.io', '1.1.1.1']);
|
||||||
|
expect(await fs.readFile(noProxy, 'utf-8')).to.equal(
|
||||||
|
'balena.io\n1.1.1.1',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('removes no_proxy file if empty or invalid', async () => {
|
||||||
|
// Set initial no_proxy
|
||||||
|
await hostConfig.setNoProxy(['2.2.2.2']);
|
||||||
|
expect(await hostConfig.readNoProxy()).to.deep.equal(['2.2.2.2']);
|
||||||
|
|
||||||
|
// Set to empty array
|
||||||
|
await hostConfig.setNoProxy([]);
|
||||||
|
expect(await hostConfig.readNoProxy()).to.deep.equal([]);
|
||||||
|
expect(await fs.readdir(proxyBase)).to.not.have.members(['no_proxy']);
|
||||||
|
|
||||||
|
// Reset initial no_proxy
|
||||||
|
await hostConfig.setNoProxy(['2.2.2.2']);
|
||||||
|
expect(await hostConfig.readNoProxy()).to.deep.equal(['2.2.2.2']);
|
||||||
|
|
||||||
|
// Set to invalid value
|
||||||
|
await hostConfig.setNoProxy(null as any);
|
||||||
|
expect(await hostConfig.readNoProxy()).to.deep.equal([]);
|
||||||
|
expect(await fs.readdir(proxyBase)).to.not.have.members(['no_proxy']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('reads proxy configs and hostname', async () => {
|
it('reads proxy configs and hostname', async () => {
|
||||||
const { network } = await get();
|
const { network } = await get();
|
||||||
expect(network).to.have.property('hostname', 'deadbeef');
|
expect(network).to.have.property('hostname', 'deadbeef');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user