Remove unnecessary exports from host-config

This limits the host-config interface to necessary methods
only

Signed-off-by: Christina Ying Wang <christina@balena.io>
This commit is contained in:
Christina Ying Wang 2024-07-01 19:07:00 -07:00
parent 53f5641ef1
commit f99ccb58c6
5 changed files with 14 additions and 157 deletions

View File

@ -10,7 +10,7 @@ import * as hostConfig from '../host-config';
import type {
HostConfiguration,
LegacyHostConfiguration,
} from '../host-config';
} from '../host-config/types';
import * as applicationManager from '../compose/application-manager';
import type { CompositionStepAction } from '../compose/composition-steps';
import { generateStep } from '../compose/composition-steps';

View File

@ -12,17 +12,14 @@ import { pathOnRoot } from '../lib/host-utils';
import log from '../lib/supervisor-console';
import * as updateLock from '../lib/update-lock';
export * from './proxy';
export * from './types';
const hostnamePath = pathOnRoot('/etc/hostname');
export async function readHostname() {
async function readHostname() {
const hostnameData = await fs.readFile(hostnamePath, 'utf-8');
return hostnameData.trim();
}
export async function setHostname(val: string) {
async function setHostname(val: string) {
let hostname = val;
// If hostname is an empty string, return first 7 digits of device uuid
if (!val) {
@ -59,7 +56,7 @@ export function parse(
throw new Error('Could not parse host config input to a valid format');
}
export function patchProxy(
function patchProxy(
currentConf: RedsocksConfig,
inputConf: Partial<{
redsocks: Partial<ProxyConfig>;
@ -123,10 +120,12 @@ export async function patch(
}
export async function get(): Promise<HostConfiguration> {
const proxy = await readProxy();
return {
network: {
hostname: await readHostname(),
proxy: await readProxy(),
// Only return proxy if readProxy is not undefined
...(proxy && { proxy }),
},
};
}

View File

@ -219,7 +219,7 @@ async function restartProxyServices() {
}
}
export async function readNoProxy(): Promise<string[]> {
async function readNoProxy(): Promise<string[]> {
try {
const noProxy = await readFromBoot(noProxyPath, 'utf-8')
// Prevent empty newline from being reported as a noProxy address
@ -238,7 +238,7 @@ export async function readNoProxy(): Promise<string[]> {
}
}
export async function setNoProxy(list: Nullable<string[]>) {
async function setNoProxy(list: Nullable<string[]>) {
const current = await readNoProxy();
if (!list || !Array.isArray(list) || !list.length) {
await unlinkAll(noProxyPath);

View File

@ -7,7 +7,6 @@ import { stub } from 'sinon';
import * as fs from 'fs/promises';
import { get, patch } from '~/src/host-config';
import * as hostConfig from '~/src/host-config';
import * as config from '~/src/config';
import * as applicationManager from '~/src/compose/application-manager';
import type { InstancedAppState } from '~/src/compose/types';
@ -83,96 +82,6 @@ describe('host-config', () => {
(applicationManager.getCurrentApps as SinonStub).restore();
});
describe('hostname', () => {
it('reads hostname', async () => {
expect(await hostConfig.readHostname()).to.equal('deadbeef');
});
it('sets hostname', async () => {
await hostConfig.setHostname('test');
expect(await config.get('hostname')).to.equal('test');
});
it('sets hostname to first 7 characters of UUID if empty', async () => {
await config.set({ uuid: '1234567' });
await hostConfig.setHostname('');
expect(await config.get('hostname')).to.equal('1234567');
});
});
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',
);
await hostConfig.setNoProxy(['balena.io', '2.2.2.2']);
expect(await fs.readFile(noProxy, 'utf-8')).to.equal(
'balena.io\n2.2.2.2',
);
});
it('returns whether noProxy was changed', async () => {
// Set initial no_proxy as empty
await hostConfig.setNoProxy([]);
// Change no_proxy
expect(await hostConfig.setNoProxy(['balena.io', '1.1.1.1'])).to.be.true;
expect(await hostConfig.readNoProxy())
.to.deep.include.members(['balena.io', '1.1.1.1'])
.and.have.lengthOf(2);
// Change no_proxy to same value
expect(await hostConfig.setNoProxy(['1.1.1.1', 'balena.io'])).to.be.false;
expect(await hostConfig.readNoProxy())
.to.deep.include.members(['balena.io', '1.1.1.1'])
.and.have.lengthOf(2);
// Remove a value
expect(await hostConfig.setNoProxy(['1.1.1.1'])).to.be.true;
expect(await hostConfig.readNoProxy())
.to.deep.include.members(['1.1.1.1'])
.and.have.lengthOf(1);
// Add a value
expect(await hostConfig.setNoProxy(['2.2.2.2', '1.1.1.1'])).to.be.true;
expect(await hostConfig.readNoProxy())
.to.deep.include.members(['2.2.2.2', '1.1.1.1'])
.and.have.lengthOf(2);
// Remove no_proxy
expect(await hostConfig.setNoProxy([])).to.be.true;
expect(await hostConfig.readNoProxy()).to.deep.equal([]);
});
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 () => {
const { network } = await get();
expect(network).to.have.property('hostname', 'deadbeef');
@ -204,10 +113,10 @@ describe('host-config', () => {
try {
await patch({ network: { proxy: {} } }, true);
expect(await hostConfig.readProxy()).to.be.undefined;
} catch (e: unknown) {
expect.fail(`Expected hostConfig.patch to not throw, but got ${e}`);
}
expect(await get()).to.deep.equal({ network: { hostname: 'deadbeef' } });
});
it('patches hostname regardless of update locks', async () => {
@ -279,7 +188,7 @@ describe('host-config', () => {
it('patches proxy to empty if input is empty', async () => {
await patch({ network: { proxy: {} } });
const { network } = await get();
expect(network).to.have.property('proxy', undefined);
expect(network).to.not.have.property('proxy');
});
it('keeps current proxy if input is invalid', async () => {
@ -341,7 +250,7 @@ describe('host-config', () => {
it('patches redsocks.conf to be empty if prompted', async () => {
await patch({ network: { proxy: {} } });
const { network } = await get();
expect(network).to.have.property('proxy', undefined);
expect(network).to.not.have.property('proxy');
expect(await fs.readdir(proxyBase)).to.not.have.members([
'redsocks.conf',
'no_proxy',

View File

@ -3,8 +3,8 @@ import { stripIndent } from 'common-tags';
import type { SinonStub } from 'sinon';
import * as hostConfig from '~/src/host-config';
import { RedsocksConf } from '~/src/host-config';
import type { RedsocksConfig, ProxyConfig } from '~/src/host-config';
import { RedsocksConf } from '~/src/host-config/proxy';
import type { RedsocksConfig, ProxyConfig } from '~/src/host-config/types';
import log from '~/lib/supervisor-console';
describe('RedsocksConf', () => {
@ -379,57 +379,6 @@ describe('RedsocksConf', () => {
});
describe('src/host-config', () => {
describe('patchProxy', () => {
it('patches RedsocksConfig with new values', () => {
const current = {
redsocks: {
type: 'socks5',
ip: 'example.org',
port: 1080,
login: '"foo"',
password: '"bar"',
},
} as RedsocksConfig;
const input = {
redsocks: {
type: 'http-connect',
ip: 'test.balena.io',
},
} as any;
const patched = hostConfig.patchProxy(current, input);
expect(patched).to.deep.equal({
redsocks: {
// Patched fields are updated
type: 'http-connect',
ip: 'test.balena.io',
// Unpatched fields retain their original values
port: 1080,
login: '"foo"',
password: '"bar"',
},
});
});
it('returns empty RedsocksConfig if redsocks config block is empty or invalid', () => {
const current: RedsocksConfig = {
redsocks: {
type: 'socks5',
ip: 'example.org',
port: 1080,
login: '"foo"',
password: '"bar"',
},
};
expect(hostConfig.patchProxy(current, { redsocks: {} })).to.deep.equal(
{},
);
expect(
hostConfig.patchProxy(current, { redsocks: true } as any),
).to.deep.equal({});
expect(hostConfig.patchProxy(current, {})).to.deep.equal({});
});
});
describe('parse', () => {
it('parses valid HostConfiguration', () => {
const conf = {