Skip to content

Commit 979abd5

Browse files
committed
add possibility to manage network interfaces with a template
1 parent 1fc5d99 commit 979abd5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+3727
-3
lines changed

REFERENCE.md

+2,071
Large diffs are not rendered by default.

manifests/networkd.pp

+77-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,53 @@
55
# @param ensure The state that the ``networkd`` service should be in
66
# @param path path where all networkd files are placed in
77
# @param manage_all_network_files if enabled, all networkd files that aren't managed by puppet will be purged
8+
# @param link_profiles
9+
# Hash of network link profiles that can be referenced by it's key on an interface
10+
# The structure is equal to the 'link' parameter of an interface.
11+
# @param netdev_profiles
12+
# Hash of netdev profiles that can be referenced by it's key on an interface
13+
# The structure is equal to the 'netdev' parameter of an interface.
14+
# @param network_profiles
15+
# Hash of network profiles that can be referenced by it's key on an interface
16+
# The structure is equal to the 'network' parameter of an interface.
17+
# @param interfaces
18+
# Hash of interfaces to configure on a node.
19+
# The link, netdev and network parameters are deep merged with the respective profile
20+
# (referenced by the key of the interface).
21+
# With the profiles you can set the default values for a network.
22+
# Hint: to remove a profile setting for an interface you can either overwrite or
23+
# set it to '~' for removal.
24+
# Example (hiera yaml notation):
25+
# systemd::networkd::network_profiles:
26+
# mynet:
27+
# Network:
28+
# Gateway: '192.168.0.1'
29+
#
30+
# systemd::networkd
31+
# mynet:
32+
# filename: '50-static'
33+
# network:
34+
# Match:
35+
# Name: 'eno0'
36+
# Network:
37+
# Address: '192.168.0.15/24'
38+
#
39+
# Gives you a file /etc/systemd/network/50-static.network
40+
# with content:
41+
# [Match]
42+
# Name=enp2s0
43+
# [Network]
44+
# Address=192.168.0.15/24
45+
# Gateway=192.168.0.1
46+
#
847
class systemd::networkd (
9-
Enum['stopped','running'] $ensure = $systemd::networkd_ensure,
10-
Stdlib::Absolutepath $path = $systemd::network_path,
11-
Boolean $manage_all_network_files = $systemd::manage_all_network_files,
48+
Enum['stopped','running'] $ensure = $systemd::networkd_ensure,
49+
Stdlib::Absolutepath $path = $systemd::network_path,
50+
Boolean $manage_all_network_files = $systemd::manage_all_network_files,
51+
Hash[String[1],Systemd::Interface::Link] $link_profiles = {},
52+
Hash[String[1],Systemd::Interface::Netdev] $netdev_profiles = {},
53+
Hash[String[1],Systemd::Interface::Network] $network_profiles = {},
54+
Hash[String[1],Systemd::Interface] $interfaces = {},
1255
) {
1356
assert_private()
1457

@@ -32,4 +75,35 @@
3275
notify => Service['systemd-networkd'],
3376
}
3477
}
78+
79+
$interfaces.each | String[1] $interface_name, Systemd::Interface $interface | {
80+
$_filename=pick($interface['filename'], $interface_name)
81+
if 'link' in $interface.keys() {
82+
systemd::network { "${_filename}.link":
83+
path => $path,
84+
content => epp('systemd/network.epp', {
85+
fname => "${_filename}.link",
86+
config => deep_merge(pick($link_profiles[$interface_name], {}), $interface['link']),
87+
}),
88+
}
89+
}
90+
if 'netdev' in $interface.keys() {
91+
systemd::network { "${_filename}.netdev":
92+
path => $path,
93+
content => epp('systemd/network.epp', {
94+
fname => "${_filename}.netdev",
95+
config => deep_merge(pick($netdev_profiles[$interface_name], {}), $interface['netdev']),
96+
}),
97+
}
98+
}
99+
if 'network' in $interface.keys() {
100+
systemd::network { "${_filename}.network":
101+
path => $path,
102+
content => epp('systemd/network.epp', {
103+
fname => "${_filename}.network",
104+
config => deep_merge(pick($network_profiles[$interface_name], {}), $interface['network']),
105+
}),
106+
}
107+
}
108+
}
35109
}

spec/classes/networkd_spec.rb

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
describe 'systemd::networkd' do
6+
on_supported_os.each do |os, os_facts|
7+
context "on #{os}" do
8+
let(:facts) { os_facts }
9+
let(:pre_condition) do
10+
[
11+
'include systemd',
12+
# Fake assert_private function from stdlib to not fail within this test
13+
'function assert_private () { }',
14+
]
15+
end
16+
17+
it { is_expected.to compile.with_all_deps }
18+
end
19+
end
20+
end
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
require 'spec_helper'
3+
4+
describe 'Systemd::Interface::Link' do
5+
describe 'valid types' do
6+
context 'with valid types' do
7+
[
8+
{},
9+
].each do |value|
10+
describe value.inspect do
11+
it { is_expected.to allow_value(value) }
12+
end
13+
end
14+
end
15+
end
16+
17+
describe 'invalid types' do
18+
context 'with garbage inputs' do
19+
[
20+
true,
21+
false,
22+
:keyword,
23+
nil,
24+
{ 'foo' => 'bar' },
25+
'42',
26+
].each do |value|
27+
describe value.inspect do
28+
it { is_expected.not_to allow_value(value) }
29+
end
30+
end
31+
end
32+
end
33+
end
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
require 'spec_helper'
3+
4+
describe 'Systemd::Interface::Netdev' do
5+
describe 'valid types' do
6+
context 'with valid types' do
7+
[
8+
{},
9+
].each do |value|
10+
describe value.inspect do
11+
it { is_expected.to allow_value(value) }
12+
end
13+
end
14+
end
15+
end
16+
17+
describe 'invalid types' do
18+
context 'with garbage inputs' do
19+
[
20+
true,
21+
false,
22+
:keyword,
23+
nil,
24+
{ 'foo' => 'bar' },
25+
'42',
26+
].each do |value|
27+
describe value.inspect do
28+
it { is_expected.not_to allow_value(value) }
29+
end
30+
end
31+
end
32+
end
33+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
require 'spec_helper'
3+
4+
describe 'Systemd::Interface::Network' do
5+
describe 'valid types' do
6+
context 'with valid types' do
7+
[
8+
{},
9+
].each do |value|
10+
describe value.inspect do
11+
it { is_expected.to allow_value(value) }
12+
end
13+
end
14+
end
15+
end
16+
17+
describe 'invalid types' do
18+
context 'with garbage inputs' do
19+
[
20+
true,
21+
false,
22+
:keyword,
23+
nil,
24+
{ 'foo' => 'bar' },
25+
'42',
26+
].each do |value|
27+
describe value.inspect do
28+
it { is_expected.not_to allow_value(value) }
29+
end
30+
end
31+
end
32+
end
33+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
require 'spec_helper'
3+
4+
describe 'Systemd::Interface' do
5+
describe 'valid types' do
6+
context 'with valid types' do
7+
[
8+
{},
9+
].each do |value|
10+
describe value.inspect do
11+
it { is_expected.to allow_value(value) }
12+
end
13+
end
14+
end
15+
end
16+
17+
describe 'invalid types' do
18+
context 'with garbage inputs' do
19+
[
20+
true,
21+
false,
22+
:keyword,
23+
nil,
24+
{ 'foo' => 'bar' },
25+
'42',
26+
].each do |value|
27+
describe value.inspect do
28+
it { is_expected.not_to allow_value(value) }
29+
end
30+
end
31+
end
32+
end
33+
end

templates/network.epp

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<%- | String[1] $fname = {},
2+
Hash $config = {},
3+
| -%>
4+
#
5+
# This file is managed with puppet
6+
#
7+
# File name: <%= $fname %>
8+
#
9+
<% $config.each |String $head, Variant[Hash,Array] $vals| { -%>
10+
<%- if $vals =~ Array { $_loop= $vals } else { $_loop = [ $vals ] } -%>
11+
<%- $_loop.each | Hash $vals | { -%>
12+
13+
<%- %>[<%= $head %>]
14+
<%- $vals.each() | String $key, Any $value | { -%>
15+
<%- if $value =~ Array[String] { -%>
16+
<%- $value.each() | String $val | { -%>
17+
<%- %><%= $key %>=<%= $val %>
18+
<%- } -%>
19+
<%- } else { -%>
20+
<%- if $value !~ Undef { -%>
21+
<%- %><%= $key %>=<%= $value %>
22+
<%- } -%>
23+
<%- } -%>
24+
<%- } -%>
25+
<%- } -%>
26+
<% } -%>

types/interface.pp

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# network interface definition
2+
type Systemd::Interface = Struct[{
3+
filename => Optional[String[1]],
4+
network => Optional[Systemd::Interface::Network],
5+
netdev => Optional[Systemd::Interface::Netdev],
6+
link => Optional[Systemd::Interface::Link],
7+
}]

types/interface/link.pp

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# interface definition
2+
type Systemd::Interface::Link = Struct[{
3+
'Match' => Optional[Systemd::Interface::Link::Match],
4+
'Link' => Optional[Systemd::Interface::Link::Link],
5+
'SR-IOV' => Optional[Systemd::Interface::Link::Sr_iov],
6+
}]

types/interface/link/link.pp

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# interface definition
2+
type Systemd::Interface::Link::Link = Struct[{
3+
'Description' => Optional[String[1]],
4+
'Property' => Optional[String[1]],
5+
'ImportProperty' => Optional[String[1]],
6+
'UnsetProperty' => Optional[String[1]],
7+
'Alias' => Optional[String[1]],
8+
'MACAddressPolicy' => Optional[Enum['persistent', 'random', 'none', '']],
9+
'MACAddress' => Optional[String[1]],
10+
'NamePolicy' => Optional[Enum[
11+
'kernel', 'database', 'onboard', 'slot',
12+
'path', 'mac', 'keep'
13+
]],
14+
'Name' => Optional[String[1]],
15+
'AlternativeNamesPolicy' => Optional[String[1]],
16+
'AlternativeName' => Optional[String[1]],
17+
'TransmitQueues' => Optional[Integer[1,4096]],
18+
'ReceiveQueues' => Optional[Integer[1,4096]],
19+
'TransmitQueueLength' => Optional[Integer[0, 4294967294]],
20+
'MTUBytes' => Optional[Integer[1280]],
21+
'BitsPerSecond' => Optional[String[1]],
22+
'Duplex' => Optional[String[1]],
23+
'AutoNegotiation' => Optional[Enum['yes','no']],
24+
'WakeOnLan' => Optional[Enum[
25+
'phy', 'unicast', 'multicast', 'broadcast',
26+
'arp', 'magic', 'secureon'
27+
]],
28+
'WakeOnLanPassword' => Optional[String[1]],
29+
'Port' => Optional[Enum['tp', 'aui', 'bnc', 'mii', 'fibre']],
30+
'Advertise' => Optional[Variant[
31+
Systemd::Interface::Link::Link_advertise,
32+
Array[Systemd::Interface::Link::Link_advertise]
33+
]],
34+
'ReceiveChecksumOffload' => Optional[Enum['yes','no']],
35+
'TransmitChecksumOffload' => Optional[Enum['yes','no']],
36+
'TCPSegmentationOffload' => Optional[Enum['yes','no']],
37+
'TCP6SegmentationOffload' => Optional[Enum['yes','no']],
38+
'GenericSegmentationOffload' => Optional[Enum['yes','no']],
39+
'GenericReceiveOffload' => Optional[Enum['yes','no']],
40+
'LargeReceiveOffload' => Optional[Enum['yes','no']],
41+
'ReceivePacketSteeringCPUMask' => Optional[String[1]],
42+
'ReceiveVLANCTAGHardwareAcceleration' => Optional[Enum['yes','no']],
43+
'TransmitVLANCTAGHardwareAcceleration'=> Optional[Enum['yes','no']],
44+
'ReceiveVLANCTAGFilter' => Optional[Enum['yes','no']],
45+
'TransmitVLANSTAGHardwareAcceleration'=> Optional[Enum['yes','no']],
46+
'NTupleFilter' => Optional[Enum['yes','no']],
47+
'RxChannels' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
48+
'TxChannels' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
49+
'OtherChannels' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
50+
'CombinedChannels' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
51+
'RxBufferSize' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
52+
'RxMiniBufferSize' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
53+
'RxJumboBufferSize' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
54+
'TxBufferSize' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
55+
'RxFlowControl' => Optional[Enum['yes','no']],
56+
'TxFlowControl' => Optional[Enum['yes','no']],
57+
'AutoNegotiationFlowControl' => Optional[Enum['yes','no']],
58+
'GenericSegmentOffloadMaxBytes' => Optional[String[1]],
59+
'GenericSegmentOffloadMaxSegments' => Optional[Integer[1, 65535]],
60+
'UseAdaptiveRxCoalesce' => Optional[Enum['yes','no']],
61+
'UseAdaptiveTxCoalesce' => Optional[Enum['yes','no']],
62+
'RxCoalesceSec' => Optional[Integer],
63+
'RxCoalesceIrqSec' => Optional[Integer],
64+
'RxCoalesceLowSec' => Optional[Integer],
65+
'RxCoalesceHighSec' => Optional[Integer],
66+
'TxCoalesceSec' => Optional[Integer],
67+
'TxCoalesceIrqSec' => Optional[Integer],
68+
'TxCoalesceLowSec' => Optional[Integer],
69+
'TxCoalesceHighSec' => Optional[Integer],
70+
'RxMaxCoalescedFrames' => Optional[Integer],
71+
'RxMaxCoalescedIrqFrames' => Optional[Integer],
72+
'RxMaxCoalescedLowFrames' => Optional[Integer],
73+
'RxMaxCoalescedHighFrames' => Optional[Integer],
74+
'TxMaxCoalescedFrames' => Optional[Integer],
75+
'TxMaxCoalescedIrqFrames' => Optional[Integer],
76+
'TxMaxCoalescedLowFrames' => Optional[Integer],
77+
'TxMaxCoalescedHighFrames' => Optional[Integer],
78+
'CoalescePacketRateLow' => Optional[Integer],
79+
'CoalescePacketRateHigh' => Optional[Integer],
80+
'CoalescePacketRateSampleIntervalSec' => Optional[Integer],
81+
'StatisticsBlockCoalesceSec' => Optional[Integer[1]],
82+
'MDI' => Optional[Enum['straight', 'mdi', 'crossover', 'mdi-x', 'mdix', 'auto']],
83+
'SR_IOVVirtualFunctions' => Optional[Integer[0, 2147483647]],
84+
}]

0 commit comments

Comments
 (0)