pmcf 2.29.2 → 2.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -21
- package/package.json +1 -1
- package/src/base.mjs +1 -1
- package/src/host-utils.mjs +1 -113
- package/src/host.mjs +19 -9
- package/src/module.mjs +5 -1
- package/src/network-address.mjs +1 -5
- package/src/network-interfaces/ethernet.mjs +37 -0
- package/src/network-interfaces/loopback.mjs +44 -0
- package/src/network-interfaces/network-interface.mjs +245 -0
- package/src/network-interfaces/skeleton.mjs +119 -0
- package/src/network-interfaces/wireguard.mjs +30 -0
- package/src/network-interfaces/wlan.mjs +77 -0
- package/src/service.mjs +1 -1
- package/src/services/dns.mjs +1 -1
- package/src/subnet.mjs +3 -2
- package/types/cluster.d.mts +1 -0
- package/types/extra-source-service.d.mts +1 -1
- package/types/host-utils.d.mts +0 -1
- package/types/host.d.mts +2 -0
- package/types/module.d.mts +5 -1
- package/types/network-address.d.mts +1 -5
- package/types/network-interfaces/ethernet.d.mts +338 -0
- package/types/network-interfaces/loopback.d.mts +319 -0
- package/types/network-interfaces/network-interface.d.mts +339 -0
- package/types/network-interfaces/skeleton.d.mts +26 -0
- package/types/network-interfaces/wireguard.d.mts +316 -0
- package/types/network-interfaces/wlan.d.mts +486 -0
- package/types/service.d.mts +2 -2
- package/types/services/dhcp.d.mts +2 -2
- package/types/services/dns.d.mts +2 -2
- package/types/services/ntp.d.mts +2 -2
- package/types/subnet.d.mts +1 -0
- package/src/network-interface.mjs +0 -366
- package/types/network-interface.d.mts +0 -1357
package/README.md
CHANGED
|
@@ -14,21 +14,27 @@
|
|
|
14
14
|
|
|
15
15
|
## Poor mans configuration management
|
|
16
16
|
|
|
17
|
-
|
|
18
17
|
# API
|
|
19
18
|
|
|
20
19
|
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
|
21
20
|
|
|
22
21
|
### Table of Contents
|
|
23
22
|
|
|
24
|
-
* [
|
|
23
|
+
* [networkAddresses](#networkaddresses)
|
|
25
24
|
* [Parameters](#parameters)
|
|
26
|
-
|
|
25
|
+
* [NetworkAddress](#networkaddress)
|
|
26
|
+
* [Parameters](#parameters-1)
|
|
27
27
|
* [subnet](#subnet)
|
|
28
28
|
* [networkInterface](#networkinterface)
|
|
29
29
|
* [address](#address)
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
|
|
31
|
+
## networkAddresses
|
|
32
|
+
|
|
33
|
+
### Parameters
|
|
34
|
+
|
|
35
|
+
* `filter` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** (optional, default `n=>true`)
|
|
36
|
+
|
|
37
|
+
Returns **Iterable<[NetworkAddress](#networkaddress)>** 
|
|
32
38
|
|
|
33
39
|
## NetworkAddress
|
|
34
40
|
|
|
@@ -38,14 +44,6 @@
|
|
|
38
44
|
* `address`  
|
|
39
45
|
* `subnet`  
|
|
40
46
|
|
|
41
|
-
### Properties
|
|
42
|
-
|
|
43
|
-
* `networkInterface` **NetworkInterface** 
|
|
44
|
-
* `address` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | [Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | [Uint16Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array))** 
|
|
45
|
-
* `family` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
|
|
46
|
-
* `subnet` **Subnet** 
|
|
47
|
-
* `domainNames` **[Set](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Set)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** 
|
|
48
|
-
|
|
49
47
|
### subnet
|
|
50
48
|
|
|
51
49
|
Type: Subnet
|
|
@@ -58,14 +56,6 @@ Type: NetworkInterface
|
|
|
58
56
|
|
|
59
57
|
Type: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | [Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | [Uint16Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array))
|
|
60
58
|
|
|
61
|
-
## networkAddresses
|
|
62
|
-
|
|
63
|
-
### Parameters
|
|
64
|
-
|
|
65
|
-
* `filter` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** (optional, default `n=>true`)
|
|
66
|
-
|
|
67
|
-
Returns **Iterable<[NetworkAddress](#networkaddress)>** 
|
|
68
|
-
|
|
69
59
|
# install
|
|
70
60
|
|
|
71
61
|
With [npm](http://npmjs.org) do:
|
package/package.json
CHANGED
package/src/base.mjs
CHANGED
package/src/host-utils.mjs
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { writeFile, mkdir } from "node:fs/promises";
|
|
2
1
|
import { join } from "node:path";
|
|
3
|
-
import { writeLines
|
|
4
|
-
import { addHook } from "./hooks.mjs";
|
|
5
|
-
import { cidrAddresses } from "./network-support.mjs";
|
|
2
|
+
import { writeLines } from "../src/utils.mjs";
|
|
6
3
|
|
|
7
4
|
export async function generateMachineInfo(host, packageData) {
|
|
8
5
|
const etcDir = join(packageData.dir, "etc");
|
|
@@ -22,115 +19,6 @@ export async function generateMachineInfo(host, packageData) {
|
|
|
22
19
|
await writeLines(etcDir, "hostname", host.hostName);
|
|
23
20
|
}
|
|
24
21
|
|
|
25
|
-
export async function generateNetworkDefs(host, packageData) {
|
|
26
|
-
const networkDir = join(packageData.dir, "etc/systemd/network");
|
|
27
|
-
|
|
28
|
-
for (const ni of host.networkInterfaces.values()) {
|
|
29
|
-
await ni.systemdDefinitions(packageData);
|
|
30
|
-
|
|
31
|
-
switch (ni.kind) {
|
|
32
|
-
case "loopback":
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (ni.name !== "eth0" && ni.hwaddr) {
|
|
37
|
-
await writeLines(networkDir, `${ni.name}.link`, [
|
|
38
|
-
sectionLines("Match", { MACAddress: ni.hwaddr }),
|
|
39
|
-
"",
|
|
40
|
-
sectionLines("Link", { Name: ni.name })
|
|
41
|
-
]);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const networkSections = [sectionLines("Match", { Name: ni.name })];
|
|
45
|
-
|
|
46
|
-
for (const Address of cidrAddresses(ni.networkAddresses())) {
|
|
47
|
-
networkSections.push(
|
|
48
|
-
"",
|
|
49
|
-
sectionLines("Address", {
|
|
50
|
-
Address
|
|
51
|
-
})
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
switch (ni.kind) {
|
|
56
|
-
case "ethernet":
|
|
57
|
-
case "wlan":
|
|
58
|
-
const routeSectionExtra = ni.destination
|
|
59
|
-
? { Destination: ni.destination }
|
|
60
|
-
: { Gateway: ni.gatewayAddress };
|
|
61
|
-
|
|
62
|
-
const networkSectionExtra = ni.arpbridge
|
|
63
|
-
? {
|
|
64
|
-
IPForward: "yes",
|
|
65
|
-
IPv4ProxyARP: "yes"
|
|
66
|
-
}
|
|
67
|
-
: {};
|
|
68
|
-
|
|
69
|
-
networkSections.push(
|
|
70
|
-
"",
|
|
71
|
-
sectionLines("Network", {
|
|
72
|
-
...networkSectionExtra,
|
|
73
|
-
DHCP: "no",
|
|
74
|
-
DHCPServer: "no",
|
|
75
|
-
MulticastDNS: ni.network.multicastDNS ? "yes" : "no",
|
|
76
|
-
LinkLocalAddressing: "ipv6",
|
|
77
|
-
IPv6LinkLocalAddressGenerationMode: "stable-privacy"
|
|
78
|
-
}),
|
|
79
|
-
"",
|
|
80
|
-
sectionLines("Route", {
|
|
81
|
-
...routeSectionExtra,
|
|
82
|
-
Scope: ni.scope,
|
|
83
|
-
Metric: ni.metric,
|
|
84
|
-
InitialCongestionWindow: 20,
|
|
85
|
-
InitialAdvertisedReceiveWindow: 20
|
|
86
|
-
}),
|
|
87
|
-
"",
|
|
88
|
-
sectionLines("IPv6AcceptRA", {
|
|
89
|
-
UseAutonomousPrefix: "true",
|
|
90
|
-
UseOnLinkPrefix: "true",
|
|
91
|
-
DHCPv6Client: "false",
|
|
92
|
-
Token: "eui64"
|
|
93
|
-
})
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
if (ni.arpbridge) {
|
|
97
|
-
networkSections.push(
|
|
98
|
-
"",
|
|
99
|
-
sectionLines("Link", { Promiscuous: "yes" })
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
await writeLines(networkDir, `${ni.name}.network`, networkSections);
|
|
105
|
-
|
|
106
|
-
switch (ni.kind) {
|
|
107
|
-
case "wifi": {
|
|
108
|
-
const d = join(packageData.dir, "etc/wpa_supplicant");
|
|
109
|
-
await mkdir(d, { recursive: true });
|
|
110
|
-
writeFile(
|
|
111
|
-
join(d, `wpa_supplicant-${ni.name}.conf`),
|
|
112
|
-
`country=${host.location.country}
|
|
113
|
-
ctrl_interface=DIR=/run/wpa_supplicant GROUP=netdev
|
|
114
|
-
update_config=1
|
|
115
|
-
p2p_disabled=1
|
|
116
|
-
network={
|
|
117
|
-
ssid="${ni.ssid}"
|
|
118
|
-
psk=${ni.psk}
|
|
119
|
-
scan_ssid=1
|
|
120
|
-
}`,
|
|
121
|
-
"utf8"
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
addHook(
|
|
125
|
-
packageData.properties.hooks,
|
|
126
|
-
"post_install",
|
|
127
|
-
`systemctl enable wpa_supplicant@${ni.name}.service`
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
22
|
export async function generateKnownHosts(hosts, dir) {
|
|
135
23
|
const keys = [];
|
|
136
24
|
for await (const host of hosts) {
|
package/src/host.mjs
CHANGED
|
@@ -7,12 +7,8 @@ import { domainFromDominName, domainName } from "./utils.mjs";
|
|
|
7
7
|
import { objectFilter } from "./filter.mjs";
|
|
8
8
|
import { addType, types } from "./types.mjs";
|
|
9
9
|
import { loadHooks } from "./hooks.mjs";
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
generateMachineInfo,
|
|
13
|
-
generateKnownHosts
|
|
14
|
-
} from "./host-utils.mjs";
|
|
15
|
-
import { NetworkInterfaceTypeDefinition } from "./network-interface.mjs";
|
|
10
|
+
import { generateMachineInfo, generateKnownHosts } from "./host-utils.mjs";
|
|
11
|
+
import { NetworkInterfaceTypeDefinition } from "./network-interfaces/network-interface.mjs";
|
|
16
12
|
|
|
17
13
|
const HostTypeDefinition = {
|
|
18
14
|
name: "host",
|
|
@@ -45,12 +41,17 @@ const HostTypeDefinition = {
|
|
|
45
41
|
weight: { type: "number", collection: false, writeable: true },
|
|
46
42
|
serial: { type: "string", collection: false, writeable: true },
|
|
47
43
|
vendor: { type: "string", collection: false, writeable: true },
|
|
48
|
-
chassis: {
|
|
44
|
+
chassis: {
|
|
45
|
+
type: "string",
|
|
46
|
+
collection: false,
|
|
47
|
+
writeable: true,
|
|
48
|
+
values: ["phone", "tablet", "router", "desktop", "server"]
|
|
49
|
+
},
|
|
49
50
|
architecture: {
|
|
50
51
|
type: "string",
|
|
51
52
|
collection: false,
|
|
52
53
|
writeable: true,
|
|
53
|
-
values: ["x86", "aarch64", "armv7"]
|
|
54
|
+
values: ["x86", "x86_64", "aarch64", "armv7"]
|
|
54
55
|
},
|
|
55
56
|
replaces: { type: "string", collection: true, writeable: true },
|
|
56
57
|
depends: { type: "string", collection: true, writeable: true },
|
|
@@ -446,6 +447,12 @@ export class Host extends Base {
|
|
|
446
447
|
return addresses(this.networkAddresses());
|
|
447
448
|
}
|
|
448
449
|
|
|
450
|
+
*subnets() {
|
|
451
|
+
for (const networkInterface of this.networkInterfaces.values()) {
|
|
452
|
+
yield* networkInterface.subnets;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
449
456
|
async publicKey(type = "ed25519") {
|
|
450
457
|
return readFile(join(this.directory, `ssh_host_${type}_key.pub`), "utf8");
|
|
451
458
|
}
|
|
@@ -483,7 +490,10 @@ export class Host extends Base {
|
|
|
483
490
|
}
|
|
484
491
|
};
|
|
485
492
|
|
|
486
|
-
|
|
493
|
+
for (const ni of this.networkInterfaces.values()) {
|
|
494
|
+
await ni.systemdDefinitions(packageData);
|
|
495
|
+
}
|
|
496
|
+
|
|
487
497
|
await generateMachineInfo(this, packageData);
|
|
488
498
|
await generateKnownHosts(this.owner.hosts(), join(dir, "root", ".ssh"));
|
|
489
499
|
|
package/src/module.mjs
CHANGED
|
@@ -8,7 +8,11 @@ export * from "./subnet.mjs";
|
|
|
8
8
|
export * from "./network.mjs";
|
|
9
9
|
export * from "./network-address.mjs";
|
|
10
10
|
export * from "./network-support.mjs";
|
|
11
|
-
export * from "./network-interface.mjs";
|
|
11
|
+
export * from "./network-interfaces/network-interface.mjs";
|
|
12
|
+
export * from "./network-interfaces/loopback.mjs";
|
|
13
|
+
export * from "./network-interfaces/ethernet.mjs";
|
|
14
|
+
export * from "./network-interfaces/wlan.mjs";
|
|
15
|
+
export * from "./network-interfaces/wireguard.mjs";
|
|
12
16
|
export * from "./host.mjs";
|
|
13
17
|
export * from "./service.mjs";
|
|
14
18
|
export * from "./endpoint.mjs";
|
package/src/network-address.mjs
CHANGED
|
@@ -2,11 +2,7 @@ import { familyIP, formatCIDR } from "ip-utilties";
|
|
|
2
2
|
import { Subnet } from "./subnet.mjs";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* @property {string|Uint8Array|Uint16Array} address
|
|
7
|
-
* @property {string} family
|
|
8
|
-
* @property {Subnet} subnet
|
|
9
|
-
* @property {Set<string>} domainNames
|
|
5
|
+
*
|
|
10
6
|
*/
|
|
11
7
|
export class NetworkAddress {
|
|
12
8
|
/** @type {Subnet} */ subnet;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { addType } from "../types.mjs";
|
|
2
|
+
import {
|
|
3
|
+
NetworkInterface,
|
|
4
|
+
NetworkInterfaceTypeDefinition
|
|
5
|
+
} from "./network-interface.mjs";
|
|
6
|
+
|
|
7
|
+
export const EthernetNetworkInterfaceTypeDefinition = {
|
|
8
|
+
name: "ethernet",
|
|
9
|
+
specializationOf: NetworkInterfaceTypeDefinition,
|
|
10
|
+
owners: NetworkInterfaceTypeDefinition.owners,
|
|
11
|
+
extends: NetworkInterfaceTypeDefinition,
|
|
12
|
+
priority: 0.1,
|
|
13
|
+
properties: {
|
|
14
|
+
arpbridge: { type: "network_interface", collection: true, writeable: true }
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export class EthernetNetworkInterface extends NetworkInterface {
|
|
19
|
+
arpbridge;
|
|
20
|
+
|
|
21
|
+
static {
|
|
22
|
+
addType(this);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static get typeDefinition() {
|
|
26
|
+
return EthernetNetworkInterfaceTypeDefinition;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
constructor(owner, data) {
|
|
30
|
+
super(owner, data);
|
|
31
|
+
this.read(data, EthernetNetworkInterfaceTypeDefinition);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get kind() {
|
|
35
|
+
return EthernetNetworkInterfaceTypeDefinition.name;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { SUBNET_LOCALHOST_IPV4, SUBNET_LOCALHOST_IPV6 } from "pmcf";
|
|
2
|
+
import { SkeletonNetworkInterface } from "./skeleton.mjs";
|
|
3
|
+
import { NetworkInterfaceTypeDefinition } from "./network-interface.mjs";
|
|
4
|
+
import { addType } from "../types.mjs";
|
|
5
|
+
|
|
6
|
+
const LoopbackNetworkInterfaceTypeDefinition = {
|
|
7
|
+
name: "loopback",
|
|
8
|
+
specializationOf: NetworkInterfaceTypeDefinition,
|
|
9
|
+
owners: NetworkInterfaceTypeDefinition.owners,
|
|
10
|
+
extends: NetworkInterfaceTypeDefinition,
|
|
11
|
+
priority: 0.1,
|
|
12
|
+
properties: {}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const _localAddresses = new Map([
|
|
16
|
+
["127.0.0.1", SUBNET_LOCALHOST_IPV4],
|
|
17
|
+
["::1", SUBNET_LOCALHOST_IPV6]
|
|
18
|
+
]);
|
|
19
|
+
|
|
20
|
+
export class LoopbackNetworkInterface extends SkeletonNetworkInterface {
|
|
21
|
+
static {
|
|
22
|
+
addType(this);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static get typeDefinition() {
|
|
26
|
+
return LoopbackNetworkInterfaceTypeDefinition;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get kind() {
|
|
30
|
+
return LoopbackNetworkInterfaceTypeDefinition.name;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get scope() {
|
|
34
|
+
return "host";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get hostName() {
|
|
38
|
+
return "localhost";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get ipAddresses() {
|
|
42
|
+
return _localAddresses;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { hasWellKnownSubnet, normalizeIP } from "ip-utilties";
|
|
3
|
+
import { Base } from "pmcf";
|
|
4
|
+
import {
|
|
5
|
+
networkProperties,
|
|
6
|
+
networkAddressProperties
|
|
7
|
+
} from "../network-support.mjs";
|
|
8
|
+
import { asArray, writeLines, sectionLines } from "../utils.mjs";
|
|
9
|
+
import { addType } from "../types.mjs";
|
|
10
|
+
import { cidrAddresses } from "../network-support.mjs";
|
|
11
|
+
import { SkeletonNetworkInterface } from "./skeleton.mjs";
|
|
12
|
+
|
|
13
|
+
export const NetworkInterfaceTypeDefinition = {
|
|
14
|
+
name: "network_interface",
|
|
15
|
+
priority: 0.4,
|
|
16
|
+
owners: ["host"],
|
|
17
|
+
extends: Base.typeDefinition,
|
|
18
|
+
specializations: {},
|
|
19
|
+
factoryFor(owner, value) {
|
|
20
|
+
const kind = value.kind;
|
|
21
|
+
const t = NetworkInterfaceTypeDefinition.specializations[kind];
|
|
22
|
+
|
|
23
|
+
if (!t) {
|
|
24
|
+
console.warn("FACTORY", owner.name, value, t?.name);
|
|
25
|
+
}
|
|
26
|
+
if (t) {
|
|
27
|
+
delete value.type;
|
|
28
|
+
delete value.kind;
|
|
29
|
+
return t.clazz;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return NetworkInterface;
|
|
33
|
+
},
|
|
34
|
+
properties: {
|
|
35
|
+
...networkProperties,
|
|
36
|
+
...networkAddressProperties,
|
|
37
|
+
hostName: { type: "string", collection: false, writeable: true },
|
|
38
|
+
ipAddresses: { type: "string", collection: true, writeable: true },
|
|
39
|
+
|
|
40
|
+
hwaddr: { type: "string", collection: false, writeable: true },
|
|
41
|
+
network: { type: "network", collection: false, writeable: true },
|
|
42
|
+
destination: { type: "string", collection: false, writeable: true }
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export class NetworkInterface extends SkeletonNetworkInterface {
|
|
47
|
+
static {
|
|
48
|
+
addType(this);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static get typeDefinition() {
|
|
52
|
+
return NetworkInterfaceTypeDefinition;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
_ipAddresses = new Map();
|
|
56
|
+
_scope;
|
|
57
|
+
_metric;
|
|
58
|
+
_kind;
|
|
59
|
+
_hostName;
|
|
60
|
+
_hwaddr;
|
|
61
|
+
_class;
|
|
62
|
+
|
|
63
|
+
constructor(owner, data) {
|
|
64
|
+
super(owner, data);
|
|
65
|
+
this.read(data, NetworkInterfaceTypeDefinition);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
addSubnet(address) {
|
|
69
|
+
if (!this.network) {
|
|
70
|
+
if (!hasWellKnownSubnet(address)) {
|
|
71
|
+
this.error("Missing network", address);
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
return this.network.addSubnet(address);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
get ipAddresses() {
|
|
79
|
+
return this._ipAddresses;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
set ipAddresses(value) {
|
|
83
|
+
for (const address of asArray(value)) {
|
|
84
|
+
this._ipAddresses.set(normalizeIP(address), this.addSubnet(address));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
subnetForAddress(address) {
|
|
89
|
+
return (
|
|
90
|
+
this.network?.subnetForAddress(address) ||
|
|
91
|
+
this.host.owner.subnetForAddress(address)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
get gateway() {
|
|
96
|
+
return this.network?.gateway;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
get gatewayAddress() {
|
|
100
|
+
for (const a of this.gateway.networkAddresses()) {
|
|
101
|
+
if (a.networkInterface.network === this.network) {
|
|
102
|
+
return a.address;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
get hostName() {
|
|
108
|
+
return this.extendedProperty("_hostName") ?? this.host.hostName;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
set hostName(value) {
|
|
112
|
+
this._hostName = value;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
get domainNames() {
|
|
116
|
+
return this.hostName
|
|
117
|
+
? new Set([[this.hostName, this.host.domain].join(".")])
|
|
118
|
+
: this.host.directDomainNames;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
set scope(value) {
|
|
122
|
+
this._scope = value;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
get scope() {
|
|
126
|
+
return (
|
|
127
|
+
this.extendedProperty("_scope") ??
|
|
128
|
+
this.network?.scope ??
|
|
129
|
+
networkProperties.scope.default
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
set hwaddr(value) {
|
|
134
|
+
this._hwaddr = value;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
get hwaddr() {
|
|
138
|
+
return this.extendedProperty("_hwaddr");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
set metric(value) {
|
|
142
|
+
this._metric = value;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
get metric() {
|
|
146
|
+
return (
|
|
147
|
+
this.extendedProperty("_metric") ??
|
|
148
|
+
this.network?.metric ??
|
|
149
|
+
networkProperties.metric.default
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
set MTU(value) {
|
|
154
|
+
this._MTU = value;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
get MTU() {
|
|
158
|
+
return this.extendedProperty("_MTU") ?? networkProperties.MTU.default;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
set class(value) {
|
|
162
|
+
this._class = value;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
get class() {
|
|
166
|
+
return this.extendedProperty("_class") ?? this.network?.class;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
set kind(value) {
|
|
170
|
+
this._kind = value;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
get kind() {
|
|
174
|
+
return this.extendedProperty("_kind") ?? this.network?.kind;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async systemdDefinitions(packageData) {
|
|
178
|
+
await super.systemdDefinitions(packageData);
|
|
179
|
+
|
|
180
|
+
const networkDir = join(packageData.dir, "etc/systemd/network");
|
|
181
|
+
|
|
182
|
+
if (this.name !== "eth0" && this.hwaddr) {
|
|
183
|
+
await writeLines(networkDir, `${this.name}.link`, [
|
|
184
|
+
sectionLines("Match", { MACAddress: this.hwaddr }),
|
|
185
|
+
"",
|
|
186
|
+
sectionLines("Link", { Name: this.name })
|
|
187
|
+
]);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const networkSections = [sectionLines("Match", { Name: this.name })];
|
|
191
|
+
|
|
192
|
+
for (const Address of cidrAddresses(this.networkAddresses())) {
|
|
193
|
+
networkSections.push(
|
|
194
|
+
"",
|
|
195
|
+
sectionLines("Address", {
|
|
196
|
+
Address
|
|
197
|
+
})
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const routeSectionExtra = this.destination
|
|
202
|
+
? { Destination: this.destination }
|
|
203
|
+
: { Gateway: this.gatewayAddress };
|
|
204
|
+
|
|
205
|
+
const networkSectionExtra = this.arpbridge
|
|
206
|
+
? {
|
|
207
|
+
IPForward: "yes",
|
|
208
|
+
IPv4ProxyARP: "yes"
|
|
209
|
+
}
|
|
210
|
+
: {};
|
|
211
|
+
|
|
212
|
+
networkSections.push(
|
|
213
|
+
"",
|
|
214
|
+
sectionLines("Network", {
|
|
215
|
+
...networkSectionExtra,
|
|
216
|
+
DHCP: "no",
|
|
217
|
+
DHCPServer: "no",
|
|
218
|
+
MulticastDNS: this.network.multicastDNS ? "yes" : "no",
|
|
219
|
+
LinkLocalAddressing: "ipv6",
|
|
220
|
+
IPv6LinkLocalAddressGenerationMode: "stable-privacy"
|
|
221
|
+
}),
|
|
222
|
+
"",
|
|
223
|
+
sectionLines("Route", {
|
|
224
|
+
...routeSectionExtra,
|
|
225
|
+
Scope: this.scope,
|
|
226
|
+
Metric: this.metric,
|
|
227
|
+
InitialCongestionWindow: 20,
|
|
228
|
+
InitialAdvertisedReceiveWindow: 20
|
|
229
|
+
}),
|
|
230
|
+
"",
|
|
231
|
+
sectionLines("IPv6AcceptRA", {
|
|
232
|
+
UseAutonomousPrefix: "true",
|
|
233
|
+
UseOnLinkPrefix: "true",
|
|
234
|
+
DHCPv6Client: "false",
|
|
235
|
+
Token: "eui64"
|
|
236
|
+
})
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
if (this.arpbridge) {
|
|
240
|
+
networkSections.push("", sectionLines("Link", { Promiscuous: "yes" }));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
await writeLines(networkDir, `${this.name}.network`, networkSections);
|
|
244
|
+
}
|
|
245
|
+
}
|