Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F3769351
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
31 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/_modules/node.py b/_modules/node.py
index 4ec9b53..ae089ef 100644
--- a/_modules/node.py
+++ b/_modules/node.py
@@ -1,317 +1,401 @@
# -*- coding: utf-8 -*-
# -------------------------------------------------------------
# Salt — Node execution module
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# Created: 2017-10-21
# Description: Functions related to the nodes' pillar entry
# License: BSD-2-Clause
# -------------------------------------------------------------
from salt.exceptions import CommandExecutionError, SaltCloudConfigError
from salt._compat import ipaddress
def _get_all_nodes():
return __pillar__.get("nodes", {})
def get_all_properties(nodename=None):
"""
A function to get a node pillar configuration.
CLI Example:
salt * node.get_all_properties
"""
if nodename is None:
nodename = __grains__["id"]
all_nodes = _get_all_nodes()
if nodename not in all_nodes:
raise CommandExecutionError(
SaltCloudConfigError("Node {0} not declared in pillar.".format(nodename))
)
return all_nodes[nodename]
def get(key, nodename=None):
"""
A function to get a node pillar configuration key.
CLI Example:
salt * node.get hostname
"""
return _get_property(key, nodename, None)
def _explode_key(k):
return k.split(":")
def _get_first_key(k):
return _explode_key(k)[0]
def _strip_first_key(k):
return ":".join(_explode_key(k)[1:])
def _get_property(key, nodename, default_value, parent=None):
if parent is None:
parent = get_all_properties(nodename)
if ":" in key:
first_key = _get_first_key(key)
if first_key in parent:
return _get_property(
_strip_first_key(key), nodename, default_value, parent[first_key]
)
elif key in parent:
return parent[key]
return default_value
def get_list(key, nodename=None):
"""
A function to get a node pillar configuration.
Returns a list if found, or an empty list if not found.
CLI Example:
salt * node.list network:ipv4_aliases
"""
return _get_property(key, nodename, [])
def has(key, nodename=None):
"""
A function to get a node pillar configuration.
Returns a boolean, False if not found.
CLI Example:
salt * node.has network:ipv6_tunnel
"""
value = _get_property(key, nodename, False)
return bool(value)
def has_role(role, nodename=None):
"""
A function to determine if a node has the specified role.
Returns a boolean, False if not found.
CLI Example:
salt * node.has_role devserver
"""
return role in get_list("roles", nodename)
def filter_by_role(pillar_key, nodename=None):
"""
A function to filter a dictionary by roles.
The dictionary must respect the following structure:
- keys are role to check the current node against
- values are list of items
If a key '*' is also present, it will be included
for every role.
Returns a list, extending all the filtered lists.
CLI Example:
salt * node.filter_by_role web_content_sls
"""
roles = get_list("roles", nodename)
dictionary = __pillar__.get(pillar_key, {})
filtered_list = []
for role, items in dictionary.items():
if role == "*" or role in roles:
filtered_list.extend(items)
return filtered_list
def filter_by_name(pillar_key, nodename=None):
"""
A function to filter a dictionary by node name.
The dictionary must respect the following structure:
- keys are names to check the current node against
- values are list of items
If a key '*' is also present, it will be included
for every node.
Returns a list, extending all the filtered lists.
CLI Example:
salt * node.filter_by_name mars
"""
if nodename is None:
nodename = __grains__["id"]
dictionary = __pillar__.get(pillar_key, {})
filtered_list = []
for name, items in dictionary.items():
if name == "*" or name == nodename:
filtered_list.extend(items)
return filtered_list
def has_web_content(content, nodename=None):
return content in filter_by_role("web_content_sls", nodename)
def get_wwwroot(nodename=None):
"""
A function to determine the wwwroot folder to use.
Returns a string depending on the FQDN.
CLI Example:
salt * node.get_wwwroot
"""
hostname = _get_property("hostname", nodename, None)
if hostname is None:
raise CommandExecutionError(
SaltCloudConfigError(
"Node {0} doesn't have a hostname property".format(nodename)
)
)
if hostname.count(".") < 2:
return "wwwroot/{0}/www".format(hostname)
fqdn = hostname.split(".")
return "wwwroot/{1}/{0}".format(".".join(fqdn[0:-2]), ".".join(fqdn[-2:]))
def get_ipv6_list():
"""
A function to get a list of IPv6, enclosed by [].
Returns a string depending on the IPv6 currently assigned.
CLI Example:
salt * node.get_ipv6_list
"""
ipv6 = __grains__.get("ipv6")
return " ".join(["[" + ip + "]" for ip in ipv6])
def resolve_network():
"""
A function to determine canonical properties of networks
from the nodes pillar.
CLI Example:
salt * node.resolve_network
"""
network = {
"ipv4_address": "",
"ipv4_gateway": "",
}
private_network = network.copy()
interfaces = _get_property("network:interfaces", __grains__["id"], {})
for interface_name, interface in interfaces.items():
if "ipv4" not in interface:
continue
ipv4 = interface["ipv4"]["address"]
if ipaddress.ip_address(ipv4).is_private:
target = private_network
else:
target = network
if target["ipv4_address"] != "":
continue
target["ipv4_address"] = ipv4
try:
target["ipv4_gateway"] = interface["ipv4"]["gateway"]
except KeyError:
pass
if network["ipv4_address"] == "":
return private_network
return network
def _resolve_gre_tunnels_for_router(network, netmask):
tunnels = []
for node, tunnel in __pillar__.get(f"{network}_gre_tunnels", {}).items():
tunnels.append(
{
"description": f"{network}_to_{node}",
"interface": tunnel["router"]["interface"],
"src": tunnel["router"]["addr"],
"dst": tunnel["node"]["addr"],
"netmask": netmask,
"icann_src": get("network")["canonical_public_ipv4"],
"icann_dst": get("network", node)["canonical_public_ipv4"],
}
)
return tunnels
def resolve_gre_tunnels():
"""
A function to get the GRE tunnels for a node
CLI Example:
salt * node.resolve_gre_tunnels
"""
gre_tunnels = []
for network, network_args in __pillar__.get("networks", {}).items():
if __grains__["id"] == network_args["router"]:
gre_tunnels += _resolve_gre_tunnels_for_router(
network, network_args["netmask"]
)
continue
tunnel = __salt__["pillar.get"](f"{network}_gre_tunnels:{__grains__['id']}")
if not tunnel:
continue
gre_tunnels.append(
{
"description": f"{network}_via_{network_args['router']}",
"interface": tunnel["node"].get("interface", "gre0"),
"src": tunnel["node"]["addr"],
"dst": tunnel["router"]["addr"],
"netmask": network_args["netmask"],
"icann_src": get("network")["canonical_public_ipv4"],
"icann_dst": get("network", network_args["router"])[
"canonical_public_ipv4"
],
}
)
return gre_tunnels
+
+
+def get_gateway(network):
+ # For tunnels, gateway is the tunnel endpoint
+ tunnel = __salt__["pillar.get"](f"{network}_gre_tunnels:{__grains__['id']}")
+ if tunnel:
+ return tunnel["router"]["addr"]
+
+ return __salt__["pillar.get"](f"networks:{network}:default_gateway")
+
+
+def _get_static_route(cidr, gateway):
+ if __grains__["os_family"] == "FreeBSD":
+ return f"-net {cidr} {gateway}"
+
+ if __grains__["kernel"] == "Linux":
+ return f"{cidr} via {gateway}"
+
+ raise ValueError("No static route implementation for " + __grains__["os_family"])
+
+
+def _get_default_route(gateway):
+ if __grains__["os_family"] == "FreeBSD":
+ return f"default {gateway}"
+
+ if __grains__["kernel"] == "Linux":
+ return f"default via {gateway}"
+
+ raise ValueError("No static route implementation for " + __grains__["os_family"])
+
+
+def _get_interface_route(ip, interface):
+ if __grains__["os_family"] == "FreeBSD":
+ return f"-net {ip}/32 -interface {interface}"
+
+ if __grains__["kernel"] == "Linux":
+ return f"{ip} dev {interface}"
+
+ raise ValueError("No static route implementation for " + __grains__["os_family"])
+
+
+def _get_routes_for_private_networks():
+ """
+ Every node, excepted the routeur, should have a route
+ for the private network CIDR to the router.
+
+ For GRE tunnels, the gateway is the tunnel endpoint.
+ In other cases, the gateway is the main router (private) IP.
+
+ """
+ routes = {}
+
+ for network, network_args in __pillar__.get("networks", {}).items():
+ if network_args["router"] == __grains__["id"]:
+ continue
+
+ gateway = get_gateway(network)
+ routes[f"private_{network}"] = _get_static_route(network_args["cidr"], gateway)
+
+ return routes
+
+
+def get_routes():
+ routes = {}
+
+ interfaces = _get_property("network:interfaces", __grains__["id"], {})
+ for interface_name, interface in interfaces.items():
+ flags = interface.get("flags", [])
+
+ if "gateway" in interface.get("ipv4", {}):
+ gateway = interface["ipv4"]["gateway"]
+
+ if "ipv4_ovh_failover" in flags:
+ routes[f"{interface_name}_gateway"] = _get_interface_route(
+ gateway, interface["device"]
+ )
+
+ if __grains__["os_family"] != "RedHat":
+ # On RHEL/CentOS/Rocky, legacy network scripts take care of this with GATEWAY=
+ routes[f"{interface_name}_default"] = _get_default_route(gateway)
+
+ routes.update(_get_routes_for_private_networks())
+
+ return routes
diff --git a/pillar/core/network.sls b/pillar/core/network.sls
index ab5e9b8..307f69d 100644
--- a/pillar/core/network.sls
+++ b/pillar/core/network.sls
@@ -1,49 +1,55 @@
networks:
drake:
+ cidr: 172.27.27.0/24
netmask: 255.255.255.0
+
+ # router-001 acts as a gateway for all nodes
+ # For GRE tunnels, gateway is probably the tunnel endpoint
+ # The other nodes can use the default_gateway IP.
router: router-001
+ default_gateway: 172.27.27.1
# -------------------------------------------------------------
# Drake - GRE tunnels
#
# Describe GRE tunnels between a node and {networks.drake.router}
#
# {id}:
# router:
# interface: gre0, gre1, ... / increment for each tunnel
# addr: The tunnel IPv4 on the router in 172.27.27.240/28
#
# node:
# interface: Not needed on Linux as the interface name will be
# descriptive: gre-drake_via_{networks.drake.router}
#
# Not needed on FreeBSD if default value "gre0" is fine.
# If there is several GRE tunnels, can be gre1, gre2, etc.
#
# addr: The canonical IPv4 for the server in 172.27.27.0/24
#
# IP should be sync between the pillar and the Operations grimoire
# at https://agora.nasqueron.org/Operations_grimoire/Network
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
drake_gre_tunnels:
ysul:
router:
interface: gre0
addr: 172.27.27.252
node:
addr: 172.27.27.33
cloudhugger:
router:
interface: gre1
addr: 172.27.27.253
node:
addr: 172.27.27.28
windriver:
router:
interface: gre2
addr: 172.27.27.254
node:
addr: 172.27.27.35
diff --git a/pillar/nodes/nodes.sls b/pillar/nodes/nodes.sls
index 7448a2c..bcc0cb2 100644
--- a/pillar/nodes/nodes.sls
+++ b/pillar/nodes/nodes.sls
@@ -1,204 +1,205 @@
# -------------------------------------------------------------
# Salt — Nodes
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# Created: 2017-10-20
# License: Trivial work, not eligible to copyright
# -------------------------------------------------------------
nodes:
##
## Forest: Nasqueron
## Semantic field: https://devcentral.nasqueron.org/P27
##
cloudhugger:
forest: nasqueron-infra
hostname: cloudhugger.nasqueron.org
roles:
- opensearch
network:
ipv6_native: True
ipv6_tunnel: False
canonical_public_ipv4: 188.165.200.229
interfaces:
eno1:
device: eno1
ipv4:
address: 188.165.200.229
gateway: 188.165.200.254
ipv6:
address: fe80::ec4:7aff:fe6a:36e8
prefix: 64
gateway: fe80::ee30:91ff:fee0:df80
dwellers:
forest: nasqueron-infra
hostname: dwellers.nasqueron.org
roles:
- paas-lxc
- paas-docker
- mastodon
flags:
install_docker_devel_tools: True
network:
ipv6_tunnel: True
canonical_public_ipv4: 51.255.124.11
interfaces:
- ens192:
+ public:
device: ens192
uuid: 6e05ebea-f2fd-4ca1-a21f-78a778664d8c
ipv4:
address: 51.255.124.11
netmask: 255.255.255.252
gateway: 91.121.86.254
- ens224:
+ intranought:
device: ens224
uuid: 8e8ca793-b2eb-46d8-9266-125aba6d06c4
ipv4:
address: 172.27.27.4
netmask: &intranought_netmask 255.255.255.240
gateway: 172.27.27.1
docker-001:
forest: nasqueron-infra
hostname: docker-001.nasqueron.org
roles:
- paas-docker
network:
ipv6_tunnel: False
canonical_public_ipv4: 51.255.124.9
interfaces:
- ens192:
+ public:
device: ens192
uuid: ef7370c5-5060-4d89-82bb-dbeabf4a35f6
ipv4:
address: 51.255.124.9
netmask: 255.255.255.252
gateway: 91.121.86.254
- ens224:
+ intranought:
device: ens224
uuid: 3fd0b9f8-ecc3-400d-bc61-3ba21d0b6337
ipv4:
address: 172.27.27.6
netmask: *intranought_netmask
gateway: 172.27.27.1
router-001:
forest: nasqueron-infra
hostname: router-001.nasqueron.org
roles:
- router
network:
- ipv4_ovh_failover: True
ipv6_tunnel: False
canonical_public_ipv4: 51.255.124.8
interfaces:
- vmx0:
+ public:
device: vmx0
ipv4:
address: 51.255.124.8
netmask: 255.255.255.252
gateway: 91.121.86.254
+ flags:
+ - ipv4_ovh_failover
- vmx1:
+ intranought:
device: vmx1
ipv4:
address: 172.27.27.1
netmask: *intranought_netmask
ysul:
forest: nasqueron-dev
hostname: ysul.nasqueron.org
roles:
- devserver
- saltmaster
- dbserver-mysql
- webserver-legacy
zfs:
pool: arcology
network:
ipv6_tunnel: True
ipv6_gateway: 2001:470:1f12:9e1::1
canonical_public_ipv4: 212.83.187.132
interfaces:
igb0:
device: igb0
ipv4:
address: 163.172.49.16
netmask: 255.255.255.255
gateway: 163.172.49.1
aliases:
- 212.83.187.132
windriver:
forest: nasqueron-dev
hostname: windriver.nasqueron.org
roles:
- devserver
- saltmaster
- dbserver-mysql
- webserver-legacy
zfs:
pool: arcology
network:
ipv6_native: True
ipv6_tunnel: False
canonical_public_ipv4: 51.159.18.59
interfaces:
igb0:
device: igb0
ipv4:
address: 51.159.18.59
netmask: 255.255.255.255
gateway: 51.159.18.1
ipv6:
address: 2001:0bc8:6005:0005:aa1e:84ff:fef3:5d9c
gateway: fe80::a293:51ff:feb7:5073
prefix: 128
##
## Forest: Eglide
## Semantic field: ? (P27 used for "Eglide" too)
##
## This forest is intended to separate credentials
## between Eglide and Nasqueron servers.
##
eglide:
forest: eglide
hostname: eglide.org
roles:
- shellserver
network:
ipv6_tunnel: True
canonical_public_ipv4: 51.159.150.221
interfaces:
ens2:
device: ens2
ipv4:
address: 51.159.150.221
gateway: ""
flags:
# This interface is configured by cloud-init
- skip_interface_configuration
fixes:
rsyslog_xconsole: True
diff --git a/roles/core/network/files/FreeBSD/routing_ipv4.rc b/roles/core/network/files/FreeBSD/routing_ipv4.rc
index 97cd605..5206223 100644
--- a/roles/core/network/files/FreeBSD/routing_ipv4.rc
+++ b/roles/core/network/files/FreeBSD/routing_ipv4.rc
@@ -1,21 +1,18 @@
# -------------------------------------------------------------
# Network — rc configuration
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# License: Trivial work, not eligible to copyright
# Source file: roles/core/network/files/FreeBSD/routing_ipv4.rc
# -------------------------------------------------------------
#
# <auto-generated>
# This file is managed by our rOPS SaltStack repository.
#
# Changes to this file may cause incorrect behavior
# and will be lost if the state is redeployed.
# </auto-generated>
-{% if ipv4_ovh_failover %}
-static_routes="net1 net2"
-route_net1="-net {{ ipv4_gateway }}/32 -interface {{ ipv4_interface }}"
-route_net2="default {{ ipv4_gateway }}"
-{%- else -%}
-defaultrouter="{{ ipv4_gateway }}"
-{% endif -%}
+static_routes={{ " ".join(routes.keys()) }}
+{% for key, value in routes.items() %}
+route_{{ key }}="{{ value }}"
+{% endfor -%}
diff --git a/roles/core/network/files/FreeBSD/routing_ipv4.rc b/roles/core/network/files/Linux/routes.conf
similarity index 60%
copy from roles/core/network/files/FreeBSD/routing_ipv4.rc
copy to roles/core/network/files/Linux/routes.conf
index 97cd605..8561094 100644
--- a/roles/core/network/files/FreeBSD/routing_ipv4.rc
+++ b/roles/core/network/files/Linux/routes.conf
@@ -1,21 +1,17 @@
# -------------------------------------------------------------
-# Network — rc configuration
+# Network — routes configuration
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# License: Trivial work, not eligible to copyright
-# Source file: roles/core/network/files/FreeBSD/routing_ipv4.rc
+# Source file: roles/core/network/files/Linux/routes.conf
# -------------------------------------------------------------
#
# <auto-generated>
# This file is managed by our rOPS SaltStack repository.
#
# Changes to this file may cause incorrect behavior
# and will be lost if the state is redeployed.
# </auto-generated>
-{% if ipv4_ovh_failover %}
-static_routes="net1 net2"
-route_net1="-net {{ ipv4_gateway }}/32 -interface {{ ipv4_interface }}"
-route_net2="default {{ ipv4_gateway }}"
-{%- else -%}
-defaultrouter="{{ ipv4_gateway }}"
-{% endif -%}
+{%- for route in routes.values() %}
+{{ route }}
+{%- endfor -%}
diff --git a/roles/core/network/files/FreeBSD/routing_ipv4.rc b/roles/core/network/files/Linux/routes.service
similarity index 56%
copy from roles/core/network/files/FreeBSD/routing_ipv4.rc
copy to roles/core/network/files/Linux/routes.service
index 97cd605..7b568b0 100644
--- a/roles/core/network/files/FreeBSD/routing_ipv4.rc
+++ b/roles/core/network/files/Linux/routes.service
@@ -1,21 +1,28 @@
# -------------------------------------------------------------
-# Network — rc configuration
+# Network — routes configuration
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# License: Trivial work, not eligible to copyright
-# Source file: roles/core/network/files/FreeBSD/routing_ipv4.rc
+# Source file: roles/core/network/files/Linux/routes.service
# -------------------------------------------------------------
#
# <auto-generated>
# This file is managed by our rOPS SaltStack repository.
#
# Changes to this file may cause incorrect behavior
# and will be lost if the state is redeployed.
# </auto-generated>
-{% if ipv4_ovh_failover %}
-static_routes="net1 net2"
-route_net1="-net {{ ipv4_gateway }}/32 -interface {{ ipv4_interface }}"
-route_net2="default {{ ipv4_gateway }}"
-{%- else -%}
-defaultrouter="{{ ipv4_gateway }}"
-{% endif -%}
+
+[Unit]
+Description=Apply static routes through ip routes
+ConditionPathExists=/etc/routes.conf
+Documentation=https://agora.nasqueron.org/Operations_grimoire/Network
+After=network.target
+
+[Service]
+ExecStart=/usr/sbin/routes
+Type=oneshot
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/core/network/files/Linux/routes.sh b/roles/core/network/files/Linux/routes.sh
new file mode 100755
index 0000000..8da47d8
--- /dev/null
+++ b/roles/core/network/files/Linux/routes.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+# -------------------------------------------------------------
+# Network — routes configuration for Linux systems
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: Trivial work, not eligible to copyright
+# Source file: roles/core/network/files/Linux/routes.sh
+# Dependencies: iproute
+# GNU xargs for -r
+# -------------------------------------------------------------
+#
+# <auto-generated>
+# This file is managed by our rOPS SaltStack repository.
+#
+# Changes to this file may cause incorrect behavior
+# and will be lost if the state is redeployed.
+# </auto-generated>
+
+ROUTES_CONFIG_PATH=/etc/routes.conf
+
+# Runs as root only
+test -z $UID && UID=$(id -u)
+if [ "$UID" -ne 0 ]; then
+ echo This script must be run as root. >&2
+ exit 1
+fi
+
+# Warn about configuration missing
+if [ ! -f $ROUTES_CONFIG_PATH ]; then
+ echo No routes configuration file found at $ROUTES_CONFIG_PATH >&2
+ exit 2
+fi
+
+# Apply routes
+# Ignore comments and blank line, pass the remaining lines to `ip route`
+grep '^[^#]' $ROUTES_CONFIG_PATH | xargs -L 1 -r ip route replace
diff --git a/roles/core/network/files/RedHat/ifcfg b/roles/core/network/files/RedHat/ifcfg
index 2338184..32c1d4f 100644
--- a/roles/core/network/files/RedHat/ifcfg
+++ b/roles/core/network/files/RedHat/ifcfg
@@ -1,32 +1,35 @@
# -------------------------------------------------------------
# Network configuration
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# License: Trivial work, not eligible to copyright
# Source file: roles/core/network/files/RedHat/ifcfg
# -------------------------------------------------------------
#
# <auto-generated>
# This file is managed by our rOPS SaltStack repository.
#
# Changes to this file may cause incorrect behavior
# and will be lost if the state is redeployed.
# </auto-generated>
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME={{ interface.device }}
UUID={{ interface.uuid }}
DEVICE={{ interface.device }}
ONBOOT=yes
IPADDR={{ interface.ipv4.address }}
PREFIX={{ prefix }}
+{% if "ipv4" in interface and "gateway" in interface["ipv4"] %}
+GATEWAY={{ interface.ipv4.gateway }}
+{% endif %}
diff --git a/roles/core/network/init.sls b/roles/core/network/init.sls
index 5cf86f5..5d6bce9 100644
--- a/roles/core/network/init.sls
+++ b/roles/core/network/init.sls
@@ -1,19 +1,20 @@
# -------------------------------------------------------------
# Salt — Network
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# Created: 2020-09-20
# License: Trivial work, not eligible to copyright
# -------------------------------------------------------------
include:
- .ipv4
- .ipv6
- .gre
+ - .routes
# Drake can be configured as:
#
# - ipv4 (e.g. IntraNought network cards on EXSi hypervisor VMs)
# - gre (e.g. isolated servers needing a tunnel)
#
# Both are needed for servers with router role.
diff --git a/roles/core/network/ipv4.sls b/roles/core/network/ipv4.sls
index 16ea4d8..3d794d7 100644
--- a/roles/core/network/ipv4.sls
+++ b/roles/core/network/ipv4.sls
@@ -1,52 +1,37 @@
# -------------------------------------------------------------
# Salt — Network
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# Created: 2016-06-15
# License: Trivial work, not eligible to copyright
# -------------------------------------------------------------
{% from "roles/core/network/map.jinja" import interface_config with context %}
{% set network = salt['node.get']('network') %}
# -------------------------------------------------------------
# Interface
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% for interface_name, interface in network["interfaces"].items() %}
{% if "skip_interface_configuration" not in interface.get("flags", []) %}
network_ipv4_{{ interface_name }}:
file.managed:
{% if interface_config["suffix"] == "interface" %}
- name : {{ interface_config["config_path"] }}{{ interface_name }}
{% else %}
- name : {{ interface_config["config_path"] }}{{ interface["device"] }}
{% endif %}
- source: salt://roles/core/network/files/{{ interface_config["source_path"] }}
- makedirs: True
- template: jinja
- defaults:
interface: {{ interface }}
{% if grains['os_family'] == 'RedHat' %}
prefix: {{ salt['network_utils.netmask_to_cidr_prefix'](interface['ipv4']['netmask']) }}
{% endif %}
{% endif %}
{% endfor %}
-# -------------------------------------------------------------
-# Routes
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-{% if grains['os'] == 'FreeBSD' %}
-/etc/rc.conf.d/routing/ipv4:
- file.managed:
- - source: salt://roles/core/network/files/FreeBSD/routing_ipv4.rc
- - makedirs: True
- - template: jinja
- - context:
- ipv4_gateway: {{ network['ipv4_gateway'] }}
- ipv4_interface: {{ network['ipv4_interface'] }}
- ipv4_ovh_failover: {{ salt['node.has']('network:ipv4_ovh_failover') }}
-{% endif %}
diff --git a/roles/core/network/map.jinja b/roles/core/network/map.jinja
index 5961208..be6d555 100644
--- a/roles/core/network/map.jinja
+++ b/roles/core/network/map.jinja
@@ -1,51 +1,68 @@
# -------------------------------------------------------------
# Salt — Network
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# License: Trivial work, not eligible to copyright
# -------------------------------------------------------------
# -------------------------------------------------------------
# Interface configuration by OS/distro
#
# config_path: the configuration file to write in OS
# source_path: in this repo, roles/core/network/files/<source_path>
#
# Don't set default value, so we MUST define them
# for EACH os/distro.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% set interface_config = salt['grains.filter_by']({
'FreeBSD': {
"config_path": "/etc/rc.conf.d/netif/ipv4_",
"source_path": "FreeBSD/netif_ipv4.rc",
"suffix": "interface",
},
'RedHat': {
"config_path": "/etc/sysconfig/network-scripts/ifcfg-",
"source_path": "RedHat/ifcfg",
"suffix": "device",
},
'Debian': {
"config_path": "/etc/network/interfaces.d/10-net-",
"source_path": "Debian/10-net.jinja",
"suffix": "device",
},
}) %}
# -------------------------------------------------------------
# GRE tunnels configuration by OS/distro
#
# See interface configuration for the documentation.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% set gre = salt['grains.filter_by']({
'FreeBSD': {
"config_path": "/etc/rc.conf.d/netif/gre_",
"source_path": "FreeBSD/netif_gre.rc",
},
'Debian': {
"config_path": "/etc/network/interfaces.d/10-gre-",
"source_path": "Debian/10-gre.jinja",
},
}) %}
+
+# -------------------------------------------------------------
+# Routes configuration by OS/distro
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{% set routes_config = salt['grains.filter_by']({
+ 'FreeBSD': {
+ "config_path": "/etc/rc.conf.d/routing/managed",
+ "source_path": "FreeBSD/routing_ipv4.rc",
+ "provider": "os"
+ },
+ 'RedHat': {
+ "config_path": "/etc/routes.conf",
+ "source_path": "Linux/routes.conf",
+ "provider": "custom-service"
+ }
+}, default="RedHat") %}
diff --git a/roles/core/network/routes.sls b/roles/core/network/routes.sls
new file mode 100644
index 0000000..e90298e
--- /dev/null
+++ b/roles/core/network/routes.sls
@@ -0,0 +1,40 @@
+# -------------------------------------------------------------
+# Salt — Network
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: Trivial work, not eligible to copyright
+# -------------------------------------------------------------
+
+{% from "roles/core/network/map.jinja" import routes_config with context %}
+
+# -------------------------------------------------------------
+# Routes
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{{ routes_config["config_path"] }}:
+ file.managed:
+ - source: salt://roles/core/network/files/{{ routes_config["source_path"] }}
+ - makedirs: True
+ - template: jinja
+ - context:
+ routes: {{ salt["node.get_routes"]() }}
+
+# -------------------------------------------------------------
+# Systemd unit for Linux systems using our /etc/routes.conf
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{% if routes_config["provider"] == "custom-service" %}
+
+/usr/sbin/routes:
+ file.managed:
+ - source: salt://roles/core/network/files/Linux/routes.sh
+ - mode: 0755
+
+/etc/systemd/system/routes.service:
+ file.managed:
+ - source: salt://roles/core/network/files/Linux/routes.service
+ service.running:
+ - name: routes
+ - enable: true
+
+{% endif %}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Nov 25, 14:17 (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2260341
Default Alt Text
(31 KB)
Attached To
Mode
rOPS Nasqueron Operations
Attached
Detach File
Event Timeline
Log In to Comment