2021-04-26 19:54:04 +00:00
|
|
|
import { expect } from 'chai';
|
Show warning instead of exception for invalid network config
A previous PR (#1656) fixed validation for network ipam config,
checking that both network and subnet are defined for each ipam config entry
(as described in the docker documentation).
After that PR, the validations throws an exception if the network target state is incorrect,
but this turns out to be the wrong approach, because that exception is also triggered
when querying target state.
This isn't a problem in normal operation, but it is in local mode, because local
mode queries the old target state before sending a new one. Since the query fails,
the CLI can never push the new target state.
This PR replaces the exception with a warning on the logs, since a
misconfigured network won't cause any engine failures, it will just
prevent containers to communicate through the provided network.
A future improvement should move this validation to an earlier point in the process,
so the target state can get rejected before it even gets to a point it
can be used.
Relates-to: #1693
Change-type: patch
2021-05-04 19:11:07 +00:00
|
|
|
import * as sinon from 'sinon';
|
2021-04-09 17:03:52 +00:00
|
|
|
|
2022-08-17 23:35:08 +00:00
|
|
|
import { Network } from '~/src/compose/network';
|
2021-04-26 16:06:04 +00:00
|
|
|
import { NetworkInspectInfo } from 'dockerode';
|
2021-04-09 17:03:52 +00:00
|
|
|
|
2022-08-17 23:35:08 +00:00
|
|
|
import { log } from '~/lib/supervisor-console';
|
Show warning instead of exception for invalid network config
A previous PR (#1656) fixed validation for network ipam config,
checking that both network and subnet are defined for each ipam config entry
(as described in the docker documentation).
After that PR, the validations throws an exception if the network target state is incorrect,
but this turns out to be the wrong approach, because that exception is also triggered
when querying target state.
This isn't a problem in normal operation, but it is in local mode, because local
mode queries the old target state before sending a new one. Since the query fails,
the CLI can never push the new target state.
This PR replaces the exception with a warning on the logs, since a
misconfigured network won't cause any engine failures, it will just
prevent containers to communicate through the provided network.
A future improvement should move this validation to an earlier point in the process,
so the target state can get rejected before it even gets to a point it
can be used.
Relates-to: #1693
Change-type: patch
2021-05-04 19:11:07 +00:00
|
|
|
|
2022-08-24 23:09:35 +00:00
|
|
|
describe('compose/network: unit tests', () => {
|
2021-04-26 16:06:04 +00:00
|
|
|
describe('creating a network from a compose object', () => {
|
2021-04-09 17:03:52 +00:00
|
|
|
it('creates a default network configuration if no config is given', () => {
|
2021-08-25 23:25:47 +00:00
|
|
|
const network = Network.fromComposeObject(
|
|
|
|
'default',
|
|
|
|
12345,
|
|
|
|
'deadbeef',
|
|
|
|
{},
|
|
|
|
);
|
2021-04-09 17:03:52 +00:00
|
|
|
|
|
|
|
expect(network.name).to.equal('default');
|
|
|
|
expect(network.appId).to.equal(12345);
|
2021-08-25 23:25:47 +00:00
|
|
|
expect(network.appUuid).to.equal('deadbeef');
|
2021-04-09 17:03:52 +00:00
|
|
|
|
|
|
|
// Default configuration options
|
|
|
|
expect(network.config.driver).to.equal('bridge');
|
|
|
|
expect(network.config.ipam).to.deep.equal({
|
|
|
|
driver: 'default',
|
|
|
|
config: [],
|
|
|
|
options: {},
|
|
|
|
});
|
|
|
|
expect(network.config.enableIPv6).to.equal(false);
|
2021-08-25 23:25:47 +00:00
|
|
|
expect(network.config.labels).to.deep.equal({
|
|
|
|
'io.balena.app-id': '12345',
|
|
|
|
});
|
2021-04-09 17:03:52 +00:00
|
|
|
expect(network.config.options).to.deep.equal({});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('normalizes legacy labels', () => {
|
2021-08-25 23:25:47 +00:00
|
|
|
const network = Network.fromComposeObject('default', 12345, 'deadbeef', {
|
2021-04-09 17:03:52 +00:00
|
|
|
labels: {
|
|
|
|
'io.resin.features.something': '1234',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(network.config.labels).to.deep.equal({
|
|
|
|
'io.balena.features.something': '1234',
|
2021-08-25 23:25:47 +00:00
|
|
|
'io.balena.app-id': '12345',
|
2021-04-09 17:03:52 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('accepts valid IPAM configurations', () => {
|
2021-08-25 23:25:47 +00:00
|
|
|
const network0 = Network.fromComposeObject('default', 12345, 'deadbeef', {
|
2021-04-09 17:03:52 +00:00
|
|
|
ipam: { driver: 'dummy', config: [], options: {} },
|
|
|
|
});
|
|
|
|
|
|
|
|
// Default configuration options
|
|
|
|
expect(network0.config.ipam).to.deep.equal({
|
|
|
|
driver: 'dummy',
|
|
|
|
config: [],
|
|
|
|
options: {},
|
|
|
|
});
|
|
|
|
|
2021-08-25 23:25:47 +00:00
|
|
|
const network1 = Network.fromComposeObject('default', 12345, 'deadbeef', {
|
2021-04-09 17:03:52 +00:00
|
|
|
ipam: {
|
|
|
|
driver: 'default',
|
|
|
|
config: [
|
|
|
|
{
|
|
|
|
subnet: '172.20.0.0/16',
|
|
|
|
ip_range: '172.20.10.0/24',
|
2021-04-26 16:06:04 +00:00
|
|
|
aux_addresses: { host0: '172.20.10.15', host1: '172.20.10.16' },
|
2021-04-09 17:03:52 +00:00
|
|
|
gateway: '172.20.0.1',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
options: {},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
// Default configuration options
|
|
|
|
expect(network1.config.ipam).to.deep.equal({
|
|
|
|
driver: 'default',
|
|
|
|
config: [
|
|
|
|
{
|
|
|
|
subnet: '172.20.0.0/16',
|
2021-04-26 16:06:04 +00:00
|
|
|
ipRange: '172.20.10.0/24',
|
2021-04-09 17:03:52 +00:00
|
|
|
gateway: '172.20.0.1',
|
2021-04-26 16:06:04 +00:00
|
|
|
auxAddress: { host0: '172.20.10.15', host1: '172.20.10.16' },
|
2021-04-09 17:03:52 +00:00
|
|
|
},
|
|
|
|
],
|
|
|
|
options: {},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
Show warning instead of exception for invalid network config
A previous PR (#1656) fixed validation for network ipam config,
checking that both network and subnet are defined for each ipam config entry
(as described in the docker documentation).
After that PR, the validations throws an exception if the network target state is incorrect,
but this turns out to be the wrong approach, because that exception is also triggered
when querying target state.
This isn't a problem in normal operation, but it is in local mode, because local
mode queries the old target state before sending a new one. Since the query fails,
the CLI can never push the new target state.
This PR replaces the exception with a warning on the logs, since a
misconfigured network won't cause any engine failures, it will just
prevent containers to communicate through the provided network.
A future improvement should move this validation to an earlier point in the process,
so the target state can get rejected before it even gets to a point it
can be used.
Relates-to: #1693
Change-type: patch
2021-05-04 19:11:07 +00:00
|
|
|
it('warns about IPAM configuration without both gateway and subnet', () => {
|
2022-08-25 15:55:21 +00:00
|
|
|
const logStub = log.warn as sinon.SinonStub;
|
Show warning instead of exception for invalid network config
A previous PR (#1656) fixed validation for network ipam config,
checking that both network and subnet are defined for each ipam config entry
(as described in the docker documentation).
After that PR, the validations throws an exception if the network target state is incorrect,
but this turns out to be the wrong approach, because that exception is also triggered
when querying target state.
This isn't a problem in normal operation, but it is in local mode, because local
mode queries the old target state before sending a new one. Since the query fails,
the CLI can never push the new target state.
This PR replaces the exception with a warning on the logs, since a
misconfigured network won't cause any engine failures, it will just
prevent containers to communicate through the provided network.
A future improvement should move this validation to an earlier point in the process,
so the target state can get rejected before it even gets to a point it
can be used.
Relates-to: #1693
Change-type: patch
2021-05-04 19:11:07 +00:00
|
|
|
|
2021-08-25 23:25:47 +00:00
|
|
|
Network.fromComposeObject('default', 12345, 'deadbeef', {
|
Show warning instead of exception for invalid network config
A previous PR (#1656) fixed validation for network ipam config,
checking that both network and subnet are defined for each ipam config entry
(as described in the docker documentation).
After that PR, the validations throws an exception if the network target state is incorrect,
but this turns out to be the wrong approach, because that exception is also triggered
when querying target state.
This isn't a problem in normal operation, but it is in local mode, because local
mode queries the old target state before sending a new one. Since the query fails,
the CLI can never push the new target state.
This PR replaces the exception with a warning on the logs, since a
misconfigured network won't cause any engine failures, it will just
prevent containers to communicate through the provided network.
A future improvement should move this validation to an earlier point in the process,
so the target state can get rejected before it even gets to a point it
can be used.
Relates-to: #1693
Change-type: patch
2021-05-04 19:11:07 +00:00
|
|
|
ipam: {
|
|
|
|
driver: 'default',
|
|
|
|
config: [
|
|
|
|
{
|
|
|
|
subnet: '172.20.0.0/16',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
options: {},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2022-08-25 15:55:21 +00:00
|
|
|
expect(logStub).to.have.been.calledOnce;
|
|
|
|
expect(logStub).to.have.been.calledWithMatch(
|
2021-04-09 17:03:52 +00:00
|
|
|
'Network IPAM config entries must have both a subnet and gateway',
|
|
|
|
);
|
|
|
|
|
2022-08-25 15:55:21 +00:00
|
|
|
logStub.resetHistory();
|
Show warning instead of exception for invalid network config
A previous PR (#1656) fixed validation for network ipam config,
checking that both network and subnet are defined for each ipam config entry
(as described in the docker documentation).
After that PR, the validations throws an exception if the network target state is incorrect,
but this turns out to be the wrong approach, because that exception is also triggered
when querying target state.
This isn't a problem in normal operation, but it is in local mode, because local
mode queries the old target state before sending a new one. Since the query fails,
the CLI can never push the new target state.
This PR replaces the exception with a warning on the logs, since a
misconfigured network won't cause any engine failures, it will just
prevent containers to communicate through the provided network.
A future improvement should move this validation to an earlier point in the process,
so the target state can get rejected before it even gets to a point it
can be used.
Relates-to: #1693
Change-type: patch
2021-05-04 19:11:07 +00:00
|
|
|
|
2021-08-25 23:25:47 +00:00
|
|
|
Network.fromComposeObject('default', 12345, 'deadbeef', {
|
Show warning instead of exception for invalid network config
A previous PR (#1656) fixed validation for network ipam config,
checking that both network and subnet are defined for each ipam config entry
(as described in the docker documentation).
After that PR, the validations throws an exception if the network target state is incorrect,
but this turns out to be the wrong approach, because that exception is also triggered
when querying target state.
This isn't a problem in normal operation, but it is in local mode, because local
mode queries the old target state before sending a new one. Since the query fails,
the CLI can never push the new target state.
This PR replaces the exception with a warning on the logs, since a
misconfigured network won't cause any engine failures, it will just
prevent containers to communicate through the provided network.
A future improvement should move this validation to an earlier point in the process,
so the target state can get rejected before it even gets to a point it
can be used.
Relates-to: #1693
Change-type: patch
2021-05-04 19:11:07 +00:00
|
|
|
ipam: {
|
|
|
|
driver: 'default',
|
|
|
|
config: [
|
|
|
|
{
|
|
|
|
gateway: '172.20.0.1',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
options: {},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2022-08-25 15:55:21 +00:00
|
|
|
expect(logStub).to.have.been.calledOnce;
|
|
|
|
expect(logStub).to.have.been.calledWithMatch(
|
2021-04-09 17:03:52 +00:00
|
|
|
'Network IPAM config entries must have both a subnet and gateway',
|
|
|
|
);
|
|
|
|
});
|
2021-05-06 14:50:11 +00:00
|
|
|
|
|
|
|
it('parses values from a compose object', () => {
|
2021-08-25 23:25:47 +00:00
|
|
|
const network1 = Network.fromComposeObject('default', 12345, 'deadbeef', {
|
2021-05-06 14:50:11 +00:00
|
|
|
driver: 'bridge',
|
|
|
|
enable_ipv6: true,
|
|
|
|
internal: false,
|
|
|
|
ipam: {
|
|
|
|
driver: 'default',
|
|
|
|
options: {
|
|
|
|
'com.docker.ipam-option': 'abcd',
|
|
|
|
},
|
|
|
|
config: [
|
|
|
|
{
|
|
|
|
subnet: '172.18.0.0/16',
|
|
|
|
gateway: '172.18.0.1',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
driver_opts: {
|
|
|
|
'com.docker.network-option': 'abcd',
|
|
|
|
},
|
|
|
|
labels: {
|
|
|
|
'com.docker.some-label': 'yes',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
const dockerConfig = network1.toDockerConfig();
|
|
|
|
|
|
|
|
expect(dockerConfig.Driver).to.equal('bridge');
|
|
|
|
// Check duplicate forced to be true
|
|
|
|
expect(dockerConfig.CheckDuplicate).to.equal(true);
|
|
|
|
expect(dockerConfig.Internal).to.equal(false);
|
|
|
|
expect(dockerConfig.EnableIPv6).to.equal(true);
|
|
|
|
|
|
|
|
expect(dockerConfig.IPAM).to.deep.equal({
|
|
|
|
Driver: 'default',
|
|
|
|
Options: {
|
|
|
|
'com.docker.ipam-option': 'abcd',
|
|
|
|
},
|
|
|
|
Config: [
|
|
|
|
{
|
|
|
|
Subnet: '172.18.0.0/16',
|
|
|
|
Gateway: '172.18.0.1',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(dockerConfig.Labels).to.deep.equal({
|
|
|
|
'io.balena.supervised': 'true',
|
2021-08-25 23:25:47 +00:00
|
|
|
'io.balena.app-id': '12345',
|
2021-05-06 14:50:11 +00:00
|
|
|
'com.docker.some-label': 'yes',
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(dockerConfig.Options).to.deep.equal({
|
|
|
|
'com.docker.network-option': 'abcd',
|
|
|
|
});
|
|
|
|
});
|
2021-04-09 17:03:52 +00:00
|
|
|
});
|
2021-04-26 16:06:04 +00:00
|
|
|
|
|
|
|
describe('creating a network from docker engine state', () => {
|
|
|
|
it('rejects networks without the proper name format', () => {
|
|
|
|
expect(() =>
|
|
|
|
Network.fromDockerNetwork({
|
|
|
|
Id: 'deadbeef',
|
|
|
|
Name: 'abcd',
|
|
|
|
} as NetworkInspectInfo),
|
|
|
|
).to.throw();
|
|
|
|
|
|
|
|
expect(() =>
|
|
|
|
Network.fromDockerNetwork({
|
|
|
|
Id: 'deadbeef',
|
|
|
|
Name: 'abcd_1234',
|
|
|
|
} as NetworkInspectInfo),
|
|
|
|
).to.throw();
|
|
|
|
|
|
|
|
expect(() =>
|
|
|
|
Network.fromDockerNetwork({
|
|
|
|
Id: 'deadbeef',
|
|
|
|
Name: 'abcd_abcd',
|
|
|
|
} as NetworkInspectInfo),
|
|
|
|
).to.throw();
|
|
|
|
|
|
|
|
expect(() =>
|
|
|
|
Network.fromDockerNetwork({
|
|
|
|
Id: 'deadbeef',
|
|
|
|
Name: '1234',
|
|
|
|
} as NetworkInspectInfo),
|
|
|
|
).to.throw();
|
2021-08-25 23:25:47 +00:00
|
|
|
|
|
|
|
expect(() =>
|
|
|
|
Network.fromDockerNetwork({
|
|
|
|
Id: 'deadbeef',
|
|
|
|
Name: 'a173bdb734884b778f5cc3dffd18733e_default',
|
|
|
|
Labels: {}, // no app-id
|
|
|
|
} as NetworkInspectInfo),
|
|
|
|
).to.throw();
|
2021-04-26 16:06:04 +00:00
|
|
|
});
|
|
|
|
|
2021-08-25 23:25:47 +00:00
|
|
|
it('creates a network object from a legacy docker network configuration', () => {
|
2021-04-26 16:06:04 +00:00
|
|
|
const network = Network.fromDockerNetwork({
|
|
|
|
Id: 'deadbeef',
|
|
|
|
Name: '1234_default',
|
|
|
|
Driver: 'bridge',
|
|
|
|
EnableIPv6: true,
|
|
|
|
IPAM: {
|
|
|
|
Driver: 'default',
|
|
|
|
Options: {},
|
|
|
|
Config: [
|
|
|
|
{
|
|
|
|
Subnet: '172.18.0.0/16',
|
|
|
|
Gateway: '172.18.0.1',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
} as NetworkInspectInfo['IPAM'],
|
|
|
|
Internal: true,
|
|
|
|
Containers: {},
|
|
|
|
Options: {
|
|
|
|
'com.docker.some-option': 'abcd',
|
|
|
|
} as NetworkInspectInfo['Options'],
|
|
|
|
Labels: {
|
2021-08-25 23:25:47 +00:00
|
|
|
'io.balena.supervised': 'true',
|
|
|
|
'io.balena.features.something': '123',
|
|
|
|
} as NetworkInspectInfo['Labels'],
|
|
|
|
} as NetworkInspectInfo);
|
|
|
|
|
|
|
|
expect(network.appId).to.equal(1234);
|
|
|
|
expect(network.name).to.equal('default');
|
|
|
|
expect(network.config.enableIPv6).to.equal(true);
|
|
|
|
expect(network.config.ipam.driver).to.equal('default');
|
|
|
|
expect(network.config.ipam.options).to.deep.equal({});
|
|
|
|
expect(network.config.ipam.config).to.deep.equal([
|
|
|
|
{
|
|
|
|
subnet: '172.18.0.0/16',
|
|
|
|
gateway: '172.18.0.1',
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
expect(network.config.internal).to.equal(true);
|
|
|
|
expect(network.config.options).to.deep.equal({
|
|
|
|
'com.docker.some-option': 'abcd',
|
|
|
|
});
|
|
|
|
expect(network.config.labels).to.deep.equal({
|
|
|
|
'io.balena.features.something': '123',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('creates a network object from a docker network configuration', () => {
|
|
|
|
const network = Network.fromDockerNetwork({
|
|
|
|
Id: 'deadbeef',
|
|
|
|
Name: 'a173bdb734884b778f5cc3dffd18733e_default',
|
|
|
|
Driver: 'bridge',
|
|
|
|
EnableIPv6: true,
|
|
|
|
IPAM: {
|
|
|
|
Driver: 'default',
|
|
|
|
Options: {},
|
|
|
|
Config: [
|
|
|
|
{
|
|
|
|
Subnet: '172.18.0.0/16',
|
|
|
|
Gateway: '172.18.0.1',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
} as NetworkInspectInfo['IPAM'],
|
|
|
|
Internal: true,
|
|
|
|
Containers: {},
|
|
|
|
Options: {
|
|
|
|
'com.docker.some-option': 'abcd',
|
|
|
|
} as NetworkInspectInfo['Options'],
|
|
|
|
Labels: {
|
|
|
|
'io.balena.supervised': 'true',
|
2021-04-26 16:06:04 +00:00
|
|
|
'io.balena.features.something': '123',
|
2021-08-25 23:25:47 +00:00
|
|
|
'io.balena.app-id': '1234',
|
2021-04-26 16:06:04 +00:00
|
|
|
} as NetworkInspectInfo['Labels'],
|
|
|
|
} as NetworkInspectInfo);
|
|
|
|
|
|
|
|
expect(network.appId).to.equal(1234);
|
2021-08-25 23:25:47 +00:00
|
|
|
expect(network.appUuid).to.equal('a173bdb734884b778f5cc3dffd18733e');
|
2021-04-26 16:06:04 +00:00
|
|
|
expect(network.name).to.equal('default');
|
|
|
|
expect(network.config.enableIPv6).to.equal(true);
|
|
|
|
expect(network.config.ipam.driver).to.equal('default');
|
|
|
|
expect(network.config.ipam.options).to.deep.equal({});
|
|
|
|
expect(network.config.ipam.config).to.deep.equal([
|
|
|
|
{
|
|
|
|
subnet: '172.18.0.0/16',
|
|
|
|
gateway: '172.18.0.1',
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
expect(network.config.internal).to.equal(true);
|
|
|
|
expect(network.config.options).to.deep.equal({
|
|
|
|
'com.docker.some-option': 'abcd',
|
|
|
|
});
|
|
|
|
expect(network.config.labels).to.deep.equal({
|
|
|
|
'io.balena.features.something': '123',
|
2021-08-25 23:25:47 +00:00
|
|
|
'io.balena.app-id': '1234',
|
2021-04-26 16:06:04 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('normalizes legacy label names and excludes supervised label', () => {
|
|
|
|
const network = Network.fromDockerNetwork({
|
|
|
|
Id: 'deadbeef',
|
|
|
|
Name: '1234_default',
|
|
|
|
IPAM: {
|
|
|
|
Driver: 'default',
|
|
|
|
Options: {},
|
|
|
|
Config: [],
|
|
|
|
} as NetworkInspectInfo['IPAM'],
|
|
|
|
Labels: {
|
|
|
|
'io.resin.features.something': '123',
|
|
|
|
'io.balena.features.dummy': 'abc',
|
|
|
|
'io.balena.supervised': 'true',
|
|
|
|
} as NetworkInspectInfo['Labels'],
|
|
|
|
} as NetworkInspectInfo);
|
|
|
|
|
|
|
|
expect(network.config.labels).to.deep.equal({
|
|
|
|
'io.balena.features.something': '123',
|
|
|
|
'io.balena.features.dummy': 'abc',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('creating a network compose configuration from a network instance', () => {
|
|
|
|
it('creates a docker compose network object from the internal network config', () => {
|
|
|
|
const network = Network.fromDockerNetwork({
|
|
|
|
Id: 'deadbeef',
|
2021-08-25 23:25:47 +00:00
|
|
|
Name: 'a173bdb734884b778f5cc3dffd18733e_default',
|
2021-04-26 16:06:04 +00:00
|
|
|
Driver: 'bridge',
|
|
|
|
EnableIPv6: true,
|
|
|
|
IPAM: {
|
|
|
|
Driver: 'default',
|
|
|
|
Options: {},
|
|
|
|
Config: [
|
|
|
|
{
|
|
|
|
Subnet: '172.18.0.0/16',
|
|
|
|
Gateway: '172.18.0.1',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
} as NetworkInspectInfo['IPAM'],
|
|
|
|
Internal: true,
|
|
|
|
Containers: {},
|
|
|
|
Options: {
|
|
|
|
'com.docker.some-option': 'abcd',
|
|
|
|
} as NetworkInspectInfo['Options'],
|
|
|
|
Labels: {
|
|
|
|
'io.balena.features.something': '123',
|
2021-08-25 23:25:47 +00:00
|
|
|
'io.balena.app-id': '12345',
|
2021-04-26 16:06:04 +00:00
|
|
|
} as NetworkInspectInfo['Labels'],
|
|
|
|
} as NetworkInspectInfo);
|
|
|
|
|
2021-08-25 23:25:47 +00:00
|
|
|
expect(network.appId).to.equal(12345);
|
|
|
|
expect(network.appUuid).to.equal('a173bdb734884b778f5cc3dffd18733e');
|
|
|
|
|
2021-04-26 16:06:04 +00:00
|
|
|
// Convert to compose object
|
|
|
|
const compose = network.toComposeObject();
|
|
|
|
expect(compose.driver).to.equal('bridge');
|
|
|
|
expect(compose.driver_opts).to.deep.equal({
|
|
|
|
'com.docker.some-option': 'abcd',
|
|
|
|
});
|
|
|
|
expect(compose.enable_ipv6).to.equal(true);
|
|
|
|
expect(compose.internal).to.equal(true);
|
|
|
|
expect(compose.ipam).to.deep.equal({
|
|
|
|
driver: 'default',
|
|
|
|
options: {},
|
|
|
|
config: [
|
|
|
|
{
|
|
|
|
subnet: '172.18.0.0/16',
|
|
|
|
gateway: '172.18.0.1',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
});
|
|
|
|
expect(compose.labels).to.deep.equal({
|
|
|
|
'io.balena.features.something': '123',
|
2021-08-25 23:25:47 +00:00
|
|
|
'io.balena.app-id': '12345',
|
2021-04-26 16:06:04 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('generateDockerName', () => {
|
2021-08-25 23:25:47 +00:00
|
|
|
it('creates a proper network name from the user given name and the app uuid', () => {
|
|
|
|
expect(Network.generateDockerName('deadbeef', 'default')).to.equal(
|
|
|
|
'deadbeef_default',
|
|
|
|
);
|
|
|
|
expect(Network.generateDockerName('deadbeef', 'bleh')).to.equal(
|
|
|
|
'deadbeef_bleh',
|
2021-04-26 16:06:04 +00:00
|
|
|
);
|
|
|
|
expect(Network.generateDockerName(1, 'default')).to.equal('1_default');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('comparing network configurations', () => {
|
|
|
|
it('ignores IPAM configuration', () => {
|
2021-08-25 23:25:47 +00:00
|
|
|
const network = Network.fromComposeObject('default', 12345, 'deadbeef', {
|
2021-04-26 16:06:04 +00:00
|
|
|
ipam: {
|
|
|
|
driver: 'default',
|
|
|
|
config: [
|
|
|
|
{
|
|
|
|
subnet: '172.20.0.0/16',
|
|
|
|
ip_range: '172.20.10.0/24',
|
|
|
|
gateway: '172.20.0.1',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
options: {},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
expect(
|
2021-08-25 23:25:47 +00:00
|
|
|
network.isEqualConfig(
|
|
|
|
Network.fromComposeObject('default', 12345, 'deadbeef', {}),
|
|
|
|
),
|
2021-04-26 16:06:04 +00:00
|
|
|
).to.be.true;
|
|
|
|
|
|
|
|
// Only ignores ipam.config, not other ipam elements
|
|
|
|
expect(
|
|
|
|
network.isEqualConfig(
|
2021-08-25 23:25:47 +00:00
|
|
|
Network.fromComposeObject('default', 12345, 'deadbeef', {
|
2021-04-26 16:06:04 +00:00
|
|
|
ipam: { driver: 'aaa' },
|
|
|
|
}),
|
|
|
|
),
|
|
|
|
).to.be.false;
|
|
|
|
});
|
|
|
|
|
|
|
|
it('compares configurations recursively', () => {
|
|
|
|
expect(
|
2021-08-25 23:25:47 +00:00
|
|
|
Network.fromComposeObject(
|
|
|
|
'default',
|
|
|
|
12345,
|
|
|
|
'deadbeef',
|
|
|
|
{},
|
|
|
|
).isEqualConfig(
|
|
|
|
Network.fromComposeObject('default', 12345, 'deadbeef', {}),
|
2021-04-26 16:06:04 +00:00
|
|
|
),
|
|
|
|
).to.be.true;
|
|
|
|
expect(
|
2021-08-25 23:25:47 +00:00
|
|
|
Network.fromComposeObject('default', 12345, 'deadbeef', {
|
2021-04-26 16:06:04 +00:00
|
|
|
driver: 'default',
|
2021-08-25 23:25:47 +00:00
|
|
|
}).isEqualConfig(
|
|
|
|
Network.fromComposeObject('default', 12345, 'deadbeef', {}),
|
|
|
|
),
|
2021-04-26 16:06:04 +00:00
|
|
|
).to.be.false;
|
|
|
|
expect(
|
2021-08-25 23:25:47 +00:00
|
|
|
Network.fromComposeObject('default', 12345, 'deadbeef', {
|
2021-04-26 16:06:04 +00:00
|
|
|
enable_ipv6: true,
|
2021-08-25 23:25:47 +00:00
|
|
|
}).isEqualConfig(
|
|
|
|
Network.fromComposeObject('default', 12345, 'deadbeef', {}),
|
|
|
|
),
|
2021-04-26 16:06:04 +00:00
|
|
|
).to.be.false;
|
|
|
|
expect(
|
2021-08-25 23:25:47 +00:00
|
|
|
Network.fromComposeObject('default', 12345, 'deadbeef', {
|
2021-04-26 16:06:04 +00:00
|
|
|
enable_ipv6: false,
|
|
|
|
internal: false,
|
|
|
|
}).isEqualConfig(
|
2021-08-25 23:25:47 +00:00
|
|
|
Network.fromComposeObject('default', 12345, 'deadbeef', {
|
|
|
|
internal: true,
|
|
|
|
}),
|
|
|
|
),
|
|
|
|
).to.be.false;
|
|
|
|
|
|
|
|
// Comparison of a network without the app-uuid and a network
|
|
|
|
// with uuid has to return false
|
|
|
|
expect(
|
|
|
|
Network.fromComposeObject(
|
|
|
|
'default',
|
|
|
|
12345,
|
|
|
|
'deadbeef',
|
|
|
|
{},
|
|
|
|
).isEqualConfig(
|
|
|
|
Network.fromDockerNetwork({
|
|
|
|
Id: 'deadbeef',
|
|
|
|
Name: '12345_default',
|
|
|
|
IPAM: {
|
|
|
|
Driver: 'default',
|
|
|
|
Options: {},
|
|
|
|
Config: [],
|
|
|
|
} as NetworkInspectInfo['IPAM'],
|
|
|
|
Labels: {
|
|
|
|
'io.balena.supervised': 'true',
|
|
|
|
} as NetworkInspectInfo['Labels'],
|
|
|
|
} as NetworkInspectInfo),
|
2021-04-26 16:06:04 +00:00
|
|
|
),
|
|
|
|
).to.be.false;
|
|
|
|
});
|
|
|
|
});
|
2021-04-09 17:03:52 +00:00
|
|
|
});
|