pkgs/switches: switch from salt to nix
This commit is contained in:
parent
f54fa47fd8
commit
3072e1e78c
|
@ -4,6 +4,16 @@ let
|
|||
mainServers = [ "server1" "server2" ];
|
||||
pillar = self.lib.saltPillarFor "*";
|
||||
|
||||
clusterServerNets = [
|
||||
"mgmt" "pub" "core" "serv"
|
||||
"c3d2" "cluster" "bmx" "priv23"
|
||||
];
|
||||
clusterServerInterfaces = builtins.foldl' (result: net:
|
||||
result // {
|
||||
"${net}".type = "bridge";
|
||||
}
|
||||
) {} clusterServerNets;
|
||||
|
||||
renameAttr = from: to: attrset:
|
||||
builtins.foldl' (result: name:
|
||||
if name == from
|
||||
|
@ -317,6 +327,26 @@ in
|
|||
proto = "tcp";
|
||||
sourcePort = port;
|
||||
}) [ 25 465 587 110 143 993 995 ];
|
||||
|
||||
server3.interfaces = clusterServerInterfaces;
|
||||
server5.interfaces = clusterServerInterfaces;
|
||||
server6.interfaces = clusterServerInterfaces;
|
||||
server7.interfaces = clusterServerInterfaces;
|
||||
server8.interfaces = clusterServerInterfaces;
|
||||
server9.interfaces = clusterServerInterfaces;
|
||||
|
||||
ap-test1.interfaces = {
|
||||
mgmt.type = "phys";
|
||||
pub.type = "bridge";
|
||||
c3d2.type = "bridge";
|
||||
bmx.type = "bridge";
|
||||
};
|
||||
ap-test2.interfaces = {
|
||||
mgmt.type = "phys";
|
||||
pub.type = "bridge";
|
||||
c3d2.type = "bridge";
|
||||
bmx.type = "bridge";
|
||||
};
|
||||
}
|
||||
|
||||
# host priv*-gw settings
|
||||
|
@ -344,18 +374,47 @@ in
|
|||
builtins.foldl' (result: hosts: result // hosts) {} (builtins.attrValues pillar.hosts-inet6)
|
||||
)
|
||||
)
|
||||
);
|
||||
) // builtins.foldl' (result: container:
|
||||
result // builtins.mapAttrs (net: interface: {
|
||||
type = "bridge";
|
||||
}) container.interfaces
|
||||
) {} (builtins.attrValues pillar.containers);
|
||||
};
|
||||
}) {} mainServers)
|
||||
|
||||
(builtins.mapAttrs (_: switch: {
|
||||
inherit (switch) model location password;
|
||||
role = "switch";
|
||||
links = builtins.mapAttrs (_: { ports, group ? null, ... }: {
|
||||
group = if group != null
|
||||
then toString group
|
||||
else null;
|
||||
ports = map toString (
|
||||
if builtins.isList ports
|
||||
then ports
|
||||
else [ ports ]
|
||||
);
|
||||
}) switch.ports;
|
||||
}) pillar.switches)
|
||||
|
||||
(builtins.mapAttrs (_: ap: {
|
||||
inherit (ap) model location password;
|
||||
role = "ap";
|
||||
interfaces = builtins.foldl' (interfaces: net: interfaces // {
|
||||
"${net}" = {
|
||||
type = "bridge";
|
||||
};
|
||||
}) {
|
||||
mgmt = {
|
||||
type = "phys";
|
||||
gw4 = "mgmt-gw";
|
||||
gw6 = "mgmt-gw";
|
||||
};
|
||||
} (
|
||||
builtins.concatMap ({ ssids, ... }:
|
||||
map ({ net, ... }: net) (builtins.attrValues ssids)
|
||||
) (builtins.attrValues ap.radios)
|
||||
);
|
||||
}) pillar.cpe)
|
||||
|
||||
(builtins.mapAttrs (name: container:
|
||||
|
@ -395,7 +454,7 @@ in
|
|||
in lib.optionalAttrs (ctPillar ? ospf && ospfConf ? stubnets-inet) {
|
||||
stubNets4 = ospfConf.stubnets-inet;
|
||||
} // lib.optionalAttrs (ctPillar ? ospf && ospfConf ? stubnets-inet6) {
|
||||
stubNets6 = ospfConf.stubnets-inet6;
|
||||
stubNets6 = ospfConf.stubnets-inet6;
|
||||
};
|
||||
|
||||
bgp =
|
||||
|
|
|
@ -2,6 +2,79 @@
|
|||
|
||||
with lib;
|
||||
let
|
||||
getLinkNets = link:
|
||||
let
|
||||
hostConfig = config.site.hosts.${link};
|
||||
sort = builtins.sort (net1: net2:
|
||||
config.site.net.${net1}.vlan < config.site.net.${net2}.vlan
|
||||
);
|
||||
in
|
||||
if config.site.hosts ? ${link}
|
||||
then
|
||||
|
||||
if builtins.elem hostConfig.role [ "container" "server" "ap" ]
|
||||
then sort (builtins.attrNames hostConfig.interfaces)
|
||||
|
||||
else if hostConfig.role == "switch"
|
||||
then sort (getSwitchNets link)
|
||||
|
||||
else if hostConfig.role == "client"
|
||||
then if hostConfig.interfaces == {}
|
||||
then builtins.trace "No known networks implemented for client \"${link}\"" []
|
||||
else sort (builtins.attrNames hostConfig.interfaces)
|
||||
|
||||
else throw "getHostNets not implemented for role \"${hostConfig.role}\""
|
||||
|
||||
else if config.site.net ? ${link}
|
||||
then [ link ]
|
||||
|
||||
else builtins.trace "Don't know what nets to configure for link to \"${link}\"" [];
|
||||
|
||||
# breaks the getLinkNets recursion for switches,
|
||||
# requiring any net to be used by at >1 links
|
||||
getSwitchNets = hostName:
|
||||
let
|
||||
linksNets = builtins.mapAttrs (link: _:
|
||||
unique (
|
||||
getSwitchNets' { "${hostName}" = true; } [ link ]
|
||||
)
|
||||
) config.site.hosts.${hostName}.links;
|
||||
allNets = unique (
|
||||
builtins.concatLists (builtins.attrValues linksNets)
|
||||
);
|
||||
netLinkCount = net:
|
||||
builtins.foldl' (netLinkCount: nets:
|
||||
if builtins.elem net nets
|
||||
then netLinkCount + 1
|
||||
else netLinkCount
|
||||
) 0 (builtins.attrValues linksNets);
|
||||
nets = builtins.filter (net:
|
||||
netLinkCount net > 1
|
||||
) allNets;
|
||||
in nets; #builtins.trace "getSwitchNets ${hostName} = ${concatStringsSep "," nets}" nets;
|
||||
|
||||
getSwitchNets' = seen: links:
|
||||
if links == []
|
||||
then []
|
||||
else
|
||||
let
|
||||
link = builtins.head links;
|
||||
seen' = seen // {
|
||||
"${link}" = true;
|
||||
};
|
||||
links' = builtins.tail links;
|
||||
in
|
||||
if config.site.hosts ? ${link} &&
|
||||
config.site.hosts.${link}.role == "switch"
|
||||
then getSwitchNets' seen' (
|
||||
links' ++ (builtins.attrNames config.site.hosts.${link}.links)
|
||||
)
|
||||
else getLinkNets link ++
|
||||
getSwitchNets' seen' (
|
||||
builtins.filter (link: ! seen' ? ${link})
|
||||
links'
|
||||
);
|
||||
|
||||
dhcpOpts = {
|
||||
start = mkOption {
|
||||
description = "First IP address in pool";
|
||||
|
@ -136,7 +209,7 @@ let
|
|||
description = "Static MAC address";
|
||||
};
|
||||
type = mkOption {
|
||||
type = types.enum [ "phys" "veth" "pppoe" ];
|
||||
type = types.enum [ "phys" "veth" "pppoe" "bridge" ];
|
||||
description = ''
|
||||
veth: Virtual ethernet to be attached to a bridge.
|
||||
|
||||
|
@ -307,6 +380,11 @@ let
|
|||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
links = mkOption {
|
||||
description = "Which port is connected to what other device? Keys are either network names or known hostnames.";
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule linkOpts);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -325,6 +403,32 @@ let
|
|||
default = {};
|
||||
};
|
||||
};
|
||||
|
||||
linkOpts = { name, ... }: {
|
||||
options = {
|
||||
ports = mkOption {
|
||||
type = with types; listOf str;
|
||||
description = "Port names";
|
||||
};
|
||||
group = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = "Link aggregation group with a fixed number";
|
||||
};
|
||||
nets = mkOption {
|
||||
type = with types; listOf str;
|
||||
description = "Set for clients, automatically generated for others";
|
||||
default = getLinkNets name;
|
||||
};
|
||||
vlans = mkOption {
|
||||
type = with types; listOf int;
|
||||
description = "Automatically generated, do not set";
|
||||
default = map (net:
|
||||
config.site.net.${net}.vlan
|
||||
) (getLinkNets name);
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
options.site = {
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
{% macro uci_network_mgmt(ifname) -%}
|
||||
set network.mgmt=interface
|
||||
set network.mgmt.ifname={{ ifname }}
|
||||
set network.mgmt.proto=static
|
||||
set network.mgmt.ipaddr={{ pillar['hosts-inet']['mgmt'][hostname] }}
|
||||
set network.mgmt.netmask=255.255.255.0
|
||||
set network.mgmt.gateway={{ pillar['hosts-inet']['mgmt']['mgmt-gw'] }}
|
||||
set network.mgmt.ip6addr={{ pillar['hosts-inet6']['dn42']['mgmt'][hostname] }}/64
|
||||
set network.mgmt.ip6gw={{ pillar['hosts-inet6']['dn42']['mgmt']['mgmt-gw'] }}
|
||||
delete network.mgmt.dns
|
||||
add_list network.mgmt.dns={{ pillar['hosts-inet']['serv']['dnscache'] }}
|
||||
add_list network.mgmt.dns={{ pillar['hosts-inet6']['dn42']['serv']['dnscache'] }}
|
||||
{%- endmacro %}
|
||||
{ pkgs, hostName, config, hostConfig, ... }:
|
||||
let
|
||||
uciNetworkMgmt = ifname: ''
|
||||
set network.mgmt=interface
|
||||
set network.mgmt.ifname={{ ifname }}
|
||||
set network.mgmt.proto=static
|
||||
set network.mgmt.ipaddr={{ pillar['hosts-inet']['mgmt'][hostName] }}
|
||||
set network.mgmt.netmask=255.255.255.0
|
||||
set network.mgmt.gateway={{ pillar['hosts-inet']['mgmt']['mgmt-gw'] }}
|
||||
set network.mgmt.ip6addr={{ pillar['hosts-inet6']['dn42']['mgmt'][hostName] }}/64
|
||||
set network.mgmt.ip6gw={{ pillar['hosts-inet6']['dn42']['mgmt']['mgmt-gw'] }}
|
||||
delete network.mgmt.dns
|
||||
add_list network.mgmt.dns={{ pillar['hosts-inet']['serv']['dnscache'] }}
|
||||
add_list network.mgmt.dns={{ pillar['hosts-inet6']['dn42']['serv']['dnscache'] }}
|
||||
'';
|
||||
in ''
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
|
||||
{%- if conf.get('firstboot') %}
|
||||
ssh-keygen -R 192.168.1.1
|
||||
|
@ -20,7 +22,7 @@ ssh-keygen -R 192.168.1.1
|
|||
ssh root@192.168.1.1 \
|
||||
"ash -e -x" <<__SSH__
|
||||
{%- else %}
|
||||
ssh root@{{ pillar['hosts-inet']['mgmt'][hostname] }} \
|
||||
ssh root@{{ pillar['hosts-inet']['mgmt'][hostName] }} \
|
||||
"ash -e -x" <<__SSH__
|
||||
{%- endif %}
|
||||
|
||||
|
@ -32,7 +34,7 @@ echo "{{ pillar['ssh']['pubkey'] }}" > /etc/dropbear/authorized_keys
|
|||
|
||||
# System configuration
|
||||
uci batch <<__UCI__
|
||||
set system.@system[0].hostname={{ hostname }}
|
||||
set system.@system[0].hostName={{ hostName }}
|
||||
set dhcp.@dnsmasq[0].enabled=0
|
||||
set system.@system[0].log_ip={{ pillar['hosts-inet']['mgmt']['logging'] }}
|
||||
set system.@system[0].log_proto=udp
|
||||
|
@ -78,7 +80,7 @@ set network.@switch_vlan[{{ switchnum }}].ports='0t 1t'
|
|||
set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}'
|
||||
{%- endfor %}
|
||||
|
||||
{{ uci_network_mgmt('eth0.1') }}
|
||||
${uciNetworkMgmt "eth0.1"}
|
||||
|
||||
{%- for net in bridges.keys() %}
|
||||
set network.{{ net }}=interface
|
||||
|
@ -112,7 +114,7 @@ set network.@switch_vlan[{{ switchnum }}].ports='5t 6t'
|
|||
set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}'
|
||||
{%- endfor %}
|
||||
|
||||
{{ uci_network_mgmt('eth0.1') }}
|
||||
${uciNetworkMgmt "eth0.1"}
|
||||
|
||||
{%- for net in bridges.keys() %}
|
||||
set network.{{ net }}=interface
|
||||
|
@ -150,7 +152,7 @@ set network.@switch_vlan[{{ switchnum }}].ports='1t 6t'
|
|||
set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}'
|
||||
{%- endfor %}
|
||||
|
||||
{{ uci_network_mgmt('eth0.1') }}
|
||||
${uciNetworkMgmt "eth0.1"}
|
||||
|
||||
{%- for net in bridges.keys() %}
|
||||
set network.{{ net }}=interface
|
||||
|
@ -187,7 +189,7 @@ set network.@switch_vlan[{{ switchnum }}].ports='0t 1t'
|
|||
set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}'
|
||||
{%- endfor %}
|
||||
|
||||
{{ uci_network_mgmt('eth0.1') }}
|
||||
${uciNetworkMgmt "eth0.1"}
|
||||
|
||||
{%- for net in bridges.keys() %}
|
||||
set network.{{ net }}=interface
|
||||
|
@ -220,7 +222,7 @@ set network.@switch_vlan[{{ switchnum }}].ports='0t 5t'
|
|||
set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}'
|
||||
{%- endfor %}
|
||||
|
||||
{{ uci_network_mgmt('eth0.1') }}
|
||||
${uciNetworkMgmt "eth0.1"}
|
||||
|
||||
{%- for net in bridges.keys() %}
|
||||
set network.{{ net }}=interface
|
||||
|
@ -235,7 +237,7 @@ set network.@switch[0].reset=1
|
|||
set network.@switch[0].enable=1
|
||||
set network.@switch[0].enable_vlan=0
|
||||
|
||||
{{ uci_network_mgmt('eth0.1') }}
|
||||
${uciNetworkMgmt "eth0.1"}
|
||||
|
||||
{%- for net in bridges.keys() %}
|
||||
|
||||
|
@ -260,7 +262,7 @@ set network.@switch[0].reset=1
|
|||
set network.@switch[0].enable=1
|
||||
set network.@switch[0].enable_vlan=0
|
||||
|
||||
{{ uci_network_mgmt('eth1.1') }}
|
||||
${uciNetworkMgmt "eth1.1"}
|
||||
|
||||
{%- for net in bridges.keys() %}
|
||||
|
||||
|
@ -280,7 +282,7 @@ set network.{{ net }}.ifname='{{ ' '.join(ports) }}'
|
|||
{%- elif conf['model'] == 'TL-WA901NDv3' or conf['model'] == 'Ubnt-UniFi-AP-AC-LR' %}
|
||||
{# Only eth0 exists, no switch #}
|
||||
|
||||
{{ uci_network_mgmt('eth0.1') }}
|
||||
${uciNetworkMgmt "eth0.1"}
|
||||
|
||||
{%- for net in bridges.keys() %}
|
||||
|
||||
|
@ -294,7 +296,7 @@ set network.{{ net }}.ifname='{{ 'eth0.' ~ pillar['vlans'][net] }}'
|
|||
{%- elif conf['model'] == 'Ubnt-UAP-nanoHD' %}
|
||||
{# no switch, eth0 exists but is not usable, using "lan" instead #}
|
||||
|
||||
{{ uci_network_mgmt('lan.1') }}
|
||||
${uciNetworkMgmt "lan.1"}
|
||||
|
||||
{%- for net in bridges.keys() %}
|
||||
|
||||
|
@ -332,7 +334,7 @@ set network.@switch_vlan[{{ switchnum }}].ports='4t 6t'
|
|||
set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}'
|
||||
{%- endfor %}
|
||||
|
||||
{{ uci_network_mgmt('eth0.1') }}
|
||||
${uciNetworkMgmt "eth0.1"}
|
||||
|
||||
{%- for net in bridges.keys() %}
|
||||
set network.{{ net }}=interface
|
||||
|
@ -348,7 +350,7 @@ set network.@switch[0].reset=1
|
|||
set network.@switch[0].enable=1
|
||||
set network.@switch[0].enable_vlan=0
|
||||
|
||||
{{ uci_network_mgmt('eth1.1') }}
|
||||
${uciNetworkMgmt "eth1.1"}
|
||||
|
||||
{%- for net in bridges.keys() %}
|
||||
|
||||
|
@ -401,71 +403,71 @@ set wireless.wifi{{ index.iface }}=wifi-iface
|
|||
{%- set ifsuffix = '-eap' %}
|
||||
{%- endif %}
|
||||
{%- else %}
|
||||
{%- set ifsuffix = '' %}
|
||||
{%- set ifsuffix = "" %}
|
||||
{%- endif %}
|
||||
set wireless.wifi{{ index.iface }}.ifname={{ ifprefix }}{{ ssidconf['net'] }}{{ ifsuffix }}
|
||||
set wireless.wifi{{ index.iface }}.device=radio{{ index.radio }}
|
||||
set wireless.wifi{{ index.iface }}.ssid='{{ ssid }}'
|
||||
set wireless.wifi{{ index.iface }}.mode=ap
|
||||
set wireless.wifi{{ index.iface }}.network={{ ssidconf['net'] }}
|
||||
{%- if ssidconf.get('psk') %}
|
||||
set wireless.wifi{{ index.iface }}.encryption=psk2
|
||||
set wireless.wifi{{ index.iface }}.key='{{ ssidconf['psk'] }}'
|
||||
{%- elif ssidconf.get('wpa-eap') %}
|
||||
set wireless.wifi{{ index.iface }}.encryption=wpa2
|
||||
set wireless.wifi{{ index.iface }}.server='{{ ssidconf['wpa-eap']['server'] }}'
|
||||
set wireless.wifi{{ index.iface }}.port='{{ ssidconf['wpa-eap']['port'] }}'
|
||||
set wireless.wifi{{ index.iface }}.auth_secret='{{ ssidconf['wpa-eap']['secret'] }}'
|
||||
{%- else %}
|
||||
set wireless.wifi{{ index.iface }}.encryption=none
|
||||
delete wireless.wifi{{ index.iface }}.key
|
||||
{%- endif %}
|
||||
set wireless.wifi{{ index.iface }}.mcast_rate=18000
|
||||
set wireless.wifi{{ index.iface }}.ifname={{ ifprefix }}{{ ssidconf['net'] }}{{ ifsuffix }}
|
||||
set wireless.wifi{{ index.iface }}.device=radio{{ index.radio }}
|
||||
set wireless.wifi{{ index.iface }}.ssid='{{ ssid }}'
|
||||
set wireless.wifi{{ index.iface }}.mode=ap
|
||||
set wireless.wifi{{ index.iface }}.network={{ ssidconf['net'] }}
|
||||
{%- if ssidconf.get('psk') %}
|
||||
set wireless.wifi{{ index.iface }}.encryption=psk2
|
||||
set wireless.wifi{{ index.iface }}.key='{{ ssidconf['psk'] }}'
|
||||
{%- elif ssidconf.get('wpa-eap') %}
|
||||
set wireless.wifi{{ index.iface }}.encryption=wpa2
|
||||
set wireless.wifi{{ index.iface }}.server='{{ ssidconf['wpa-eap']['server'] }}'
|
||||
set wireless.wifi{{ index.iface }}.port='{{ ssidconf['wpa-eap']['port'] }}'
|
||||
set wireless.wifi{{ index.iface }}.auth_secret='{{ ssidconf['wpa-eap']['secret'] }}'
|
||||
{%- else %}
|
||||
set wireless.wifi{{ index.iface }}.encryption=none
|
||||
delete wireless.wifi{{ index.iface }}.key
|
||||
{%- endif %}
|
||||
set wireless.wifi{{ index.iface }}.mcast_rate=18000
|
||||
|
||||
{%- set x = index.update({ 'iface': index.iface + 1 }) %}
|
||||
{%- endfor %}
|
||||
{%- set x = index.update({ 'radio': index.radio + 1 }) %}
|
||||
{%- endfor %}
|
||||
{%- set x = index.update({ 'iface': index.iface + 1 }) %}
|
||||
{%- endfor %}
|
||||
{%- set x = index.update({ 'radio': index.radio + 1 }) %}
|
||||
{%- endfor %}
|
||||
|
||||
commit
|
||||
__UCI__
|
||||
commit
|
||||
__UCI__
|
||||
|
||||
# Cronjob that makes sure WiFi is only visible when server with all
|
||||
# the gateways is reachable
|
||||
cat >/etc/crontabs/root <<__CRON__
|
||||
* * * * * /usr/sbin/wifi-on-link.sh
|
||||
__CRON__
|
||||
cat >/usr/sbin/wifi-on-link.sh <<__SH__
|
||||
#!/bin/sh
|
||||
# Cronjob that makes sure WiFi is only visible when server with all
|
||||
# the gateways is reachable
|
||||
cat >/etc/crontabs/root <<__CRON__
|
||||
* * * * * /usr/sbin/wifi-on-link.sh
|
||||
__CRON__
|
||||
cat >/usr/sbin/wifi-on-link.sh <<__SH__
|
||||
#!/bin/sh
|
||||
|
||||
if (ping -c 1 -W 3 {{ pillar['hosts-inet']['mgmt']['mgmt-gw'] }}) ; then
|
||||
REACHABLE=y
|
||||
else
|
||||
REACHABLE=n
|
||||
fi
|
||||
if (ping -c 1 -W 3 {{ pillar['hosts-inet']['mgmt']['mgmt-gw'] }}) ; then
|
||||
REACHABLE=y
|
||||
else
|
||||
REACHABLE=n
|
||||
fi
|
||||
|
||||
if [ "\\\$(cat /sys/class/net/wlan2-pub/operstate)" == "up" ] ; then
|
||||
UP=y
|
||||
else
|
||||
UP=n
|
||||
fi
|
||||
if [ "\\\$(cat /sys/class/net/wlan2-pub/operstate)" == "up" ] ; then
|
||||
UP=y
|
||||
else
|
||||
UP=n
|
||||
fi
|
||||
|
||||
{%- if conf.get("error-led") %}
|
||||
ERROR_LED=/sys/class/leds/{{ conf["error-led"] }}/brightness
|
||||
[ \\\$REACHABLE = y ] && echo 0 > \\\$ERROR_LED
|
||||
[ \\\$REACHABLE = n ] && echo 1 > \\\$ERROR_LED
|
||||
{%- endif %}
|
||||
{%- if conf.get("error-led") %}
|
||||
ERROR_LED=/sys/class/leds/{{ conf["error-led"] }}/brightness
|
||||
[ \\\$REACHABLE = y ] && echo 0 > \\\$ERROR_LED
|
||||
[ \\\$REACHABLE = n ] && echo 1 > \\\$ERROR_LED
|
||||
{%- endif %}
|
||||
|
||||
[ \\\$REACHABLE = y ] && [ \\\$UP = n ] && wifi up
|
||||
[ \\\$REACHABLE = n ] && [ \\\$UP = y ] && wifi down
|
||||
[ \\\$REACHABLE = y ] && [ \\\$UP = n ] && wifi up
|
||||
[ \\\$REACHABLE = n ] && [ \\\$UP = y ] && wifi down
|
||||
|
||||
exit 0
|
||||
__SH__
|
||||
chmod a+rx /usr/sbin/wifi-on-link.sh
|
||||
/etc/init.d/cron restart
|
||||
exit 0
|
||||
__SH__
|
||||
chmod a+rx /usr/sbin/wifi-on-link.sh
|
||||
/etc/init.d/cron restart
|
||||
|
||||
for svc in dnsmasq uhttpd ; do
|
||||
rm /etc/rc.d/*\$svc
|
||||
for svc in dnsmasq uhttpd ; do
|
||||
rm /etc/rc.d/*\$svc
|
||||
/etc/init.d/\$svc stop
|
||||
done
|
||||
|
||||
|
@ -476,4 +478,7 @@ reboot
|
|||
__SSH__
|
||||
|
||||
echo "Base configuration done \\o/"
|
||||
echo "Later run: `dirname $0`/ap_install_collectd.sh {{ pillar['hosts-inet']['mgmt'][hostname] }}"
|
||||
echo "Later run: `dirname $0`/ap_install_collectd.sh {{ pillar['hosts-inet']['mgmt'][hostName] }}"
|
||||
|
||||
|
||||
''
|
|
@ -4,43 +4,17 @@ let
|
|||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
config = self.lib.config;
|
||||
|
||||
templates = role: {
|
||||
ap = _: ./ap.sh;
|
||||
switch = model: ../../salt/switches + "/${model}.expect";
|
||||
}.${role};
|
||||
replaceNetmasks = template:
|
||||
builtins.toFile (builtins.baseNameOf template) (
|
||||
builtins.replaceStrings [''{%- import_yaml "netmasks.yaml" as netmasks -%}''] [""] (
|
||||
builtins.readFile template
|
||||
)
|
||||
);
|
||||
expandTemplate = name: template: data:
|
||||
self.lib.expandSaltTemplate name (replaceNetmasks template) data;
|
||||
wrapNixShell = script:
|
||||
pkgs.runCommand (builtins.baseNameOf script) {
|
||||
src = script;
|
||||
} ''
|
||||
(
|
||||
echo '#! /usr/bin/env nix-shell'
|
||||
echo '#! nix-shell -i "expect -f" -p expect telnet'
|
||||
cat $src
|
||||
) > $out
|
||||
chmod a+x $out
|
||||
'';
|
||||
|
||||
device-scripts =
|
||||
builtins.mapAttrs (hostname: { role, model, ... }:
|
||||
wrapNixShell (
|
||||
expandTemplate "${hostname}.sh" (templates role model) ({
|
||||
inherit hostname;
|
||||
pillar = config.salt-pillar;
|
||||
netmasks = self.lib.netmasks;
|
||||
logging = config.salt-pillar.hosts-inet.mgmt.logging;
|
||||
} // optionalAttrs (config.salt-pillar.switches ? ${hostname}) {
|
||||
switch = config.salt-pillar.switches.${hostname};
|
||||
} // optionalAttrs (config.salt-pillar.cpe ? ${hostname}) {
|
||||
conf = config.salt-pillar.cpe.${hostname};
|
||||
})
|
||||
builtins.mapAttrs (hostName: hostConfig@{ role, model, ... }:
|
||||
pkgs.writeScript "${hostName}.sh" (
|
||||
let
|
||||
args = {
|
||||
inherit pkgs self hostName config hostConfig;
|
||||
};
|
||||
in {
|
||||
ap = import ./ap.nix args;
|
||||
switch = import (./switches + "/${model}.nix") args;
|
||||
}.${role}
|
||||
)
|
||||
) (
|
||||
filterAttrs (_: { role, ... }:
|
||||
|
@ -58,8 +32,8 @@ let
|
|||
chmod a+x $out/bin/ap_install_collectd.sh
|
||||
'' +
|
||||
builtins.concatStringsSep "\n" (
|
||||
map (hostname:
|
||||
"ln -s ${device-scripts.${hostname}} $out/bin/${hostname}.sh"
|
||||
map (hostName:
|
||||
"ln -s ${device-scripts.${hostName}} $out/bin/${hostName}.sh"
|
||||
) (builtins.attrNames device-scripts)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
# http://h20628.www2.hp.com/km-ext/kmcsdirect/emr_na-c02586144-1.pdf
|
||||
{ self, pkgs, hostName, config, hostConfig, ... }:
|
||||
with pkgs;
|
||||
with lib;
|
||||
''
|
||||
#! ${expect}/bin/expect -f
|
||||
|
||||
spawn ${inetutils}/bin/telnet ${config.site.net.mgmt.hosts4.${hostName}}
|
||||
|
||||
expect "Password:"
|
||||
send "${hostConfig.password}\r"
|
||||
expect ">"
|
||||
send "system-view\r"
|
||||
expect "]"
|
||||
|
||||
send "sysname ${hostName}\r"
|
||||
expect "]"
|
||||
|
||||
send "user-interface vty 0 4\r"
|
||||
expect "ui-vty0-4]"
|
||||
send "screen-length 0\r"
|
||||
expect "ui-vty0-4]"
|
||||
send "user privilege level 3\r"
|
||||
expect "ui-vty0-4]"
|
||||
send "set authentication password simple ${hostConfig.password}\r"
|
||||
expect "ui-vty0-4]"
|
||||
send "quit\r"
|
||||
expect "${hostName}]"
|
||||
|
||||
send "local-user admin\r"
|
||||
expect -- "-luser-admin]"
|
||||
send "password simple ${hostConfig.password}\r"
|
||||
expect -- "-luser-admin]"
|
||||
send "quit\r"
|
||||
expect "${hostName}]"
|
||||
|
||||
# Enable logging
|
||||
send "info-center enable\r"
|
||||
expect "]"
|
||||
send "info-center loghost ${config.site.net.mgmt.hosts4.logging} channel loghost facility local6\r"
|
||||
expect "]"
|
||||
send "info-center source default channel loghost log level informational\r"
|
||||
expect "]"
|
||||
|
||||
${concatMapStrings (net:
|
||||
let
|
||||
netConfig = config.site.net.${net};
|
||||
vlan = toString netConfig.vlan;
|
||||
inherit (config.site.net.${net}) hosts4;
|
||||
hostAddr4 = hosts4.${hostName};
|
||||
prefixLength = elemAt (
|
||||
builtins.split "/" netConfig.subnet4
|
||||
) 2;
|
||||
netmask = self.lib.netmasks.${prefixLength};
|
||||
in ''
|
||||
send "vlan ${vlan}\r"
|
||||
expect -- "-vlan${vlan}]"
|
||||
send "name ${net}\r"
|
||||
expect -- "-vlan${vlan}]"
|
||||
|
||||
${optionalString (net == "mgmt") ''
|
||||
# Actually only used for mgmt_vlan, switches are not routers
|
||||
send "interface Vlan-interface ${vlan}\r"
|
||||
expect "]"
|
||||
${optionalString (hosts4 ? ${hostName}) ''
|
||||
send "ip address ${hostAddr4} ${netmask}\r"
|
||||
expect "]"
|
||||
''}
|
||||
''}
|
||||
send "quit\r"
|
||||
expect "${hostName}]"
|
||||
'') (builtins.attrNames config.site.net)
|
||||
}
|
||||
|
||||
${concatMapStrings (name:
|
||||
let
|
||||
linkConfig = hostConfig.links.${name};
|
||||
isAccess = config.site.net ? ${name};
|
||||
netConfig = config.site.net.${name};
|
||||
isTrunk = !isAccess;
|
||||
isBond = isTrunk && builtins.length linkConfig.ports > 1;
|
||||
in
|
||||
if isTrunk
|
||||
then ''
|
||||
${optionalString isBond ''
|
||||
send "link-aggregation group ${linkConfig.group} mode static\r"
|
||||
expect {
|
||||
"This aggregation will be modified to static mode. Continue ?" {
|
||||
send "Y\r"
|
||||
}
|
||||
"]" {}
|
||||
}
|
||||
send "link-aggregation group ${linkConfig.group} description ${name}\r"
|
||||
expect "]"
|
||||
''}
|
||||
${concatMapStrings (port: ''
|
||||
send "interface ${port}\r"
|
||||
expect "]"
|
||||
send "undo stp edged-port\r"
|
||||
expect "]"
|
||||
${if isBond
|
||||
then ''
|
||||
send "lacp enable\r"
|
||||
expect "]"
|
||||
send "undo port link-aggregation group\r"
|
||||
expect "]"
|
||||
send "port link-aggregation group ${linkConfig.group}\r"
|
||||
'' else ''
|
||||
send "undo lacp enable\r"
|
||||
''}
|
||||
expect "]"
|
||||
send "jumboframe enable\r"
|
||||
expect "]"
|
||||
|
||||
send "port link-type trunk\r"
|
||||
expect "]"
|
||||
# Set dummy default vlan
|
||||
send "port trunk pvid vlan 4094\r"
|
||||
expect "]"
|
||||
# Deconfigure all but mgmt vlan
|
||||
send "undo port trunk permit vlan 2 to 4094\r"
|
||||
expect "]"
|
||||
${concatMapStrings (vlan: ''
|
||||
send "port trunk permit vlan ${toString vlan}\r"
|
||||
expect "]"
|
||||
'') linkConfig.vlans}
|
||||
send "quit\r"
|
||||
expect "${hostName}]"
|
||||
'') linkConfig.ports}
|
||||
'' else
|
||||
concatMapStrings (port: ''
|
||||
send "interface ${port}\r"
|
||||
expect "]"
|
||||
send "undo port link-aggregation group\r"
|
||||
expect "]"
|
||||
send "port link-type access\r"
|
||||
expect "]"
|
||||
${if name == "mgmt"
|
||||
then ''
|
||||
send "undo port access vlan\r"
|
||||
expect "]"
|
||||
'' else ''
|
||||
send "port access vlan ${toString netConfig.vlan}\r"
|
||||
expect "]"
|
||||
''}
|
||||
send "quit\r"
|
||||
expect "${hostName}]"
|
||||
'') (linkConfig.ports)
|
||||
) (builtins.attrNames hostConfig.links)}
|
||||
|
||||
send "save main\r"
|
||||
expect "Y/N]"
|
||||
send "YES\r"
|
||||
expect "press the enter key):"
|
||||
send "\r"
|
||||
expect "]"
|
||||
send "quit\r"
|
||||
expect ">"
|
||||
send "quit\r"
|
||||
''
|
|
@ -0,0 +1,141 @@
|
|||
# http://ftp.hp.com/pub/networking/software/2600-2800-4100-6108-MgmtConfig-Oct2005-59906023.pdf
|
||||
|
||||
{ self, pkgs, hostName, config, hostConfig, ... }:
|
||||
with pkgs;
|
||||
with lib;
|
||||
''
|
||||
#! ${expect}/bin/expect -f
|
||||
|
||||
spawn ${inetutils}/bin/telnet ${config.site.net.mgmt.hosts4.${hostName}}
|
||||
expect "Press any key to continue"
|
||||
send "\r"
|
||||
expect "assword: "
|
||||
send "${hostConfig.password}\r"
|
||||
expect "#"
|
||||
send "configure terminal\r"
|
||||
expect "(config)# "
|
||||
|
||||
send "hostname ${hostName}\r"
|
||||
expect "(config)# "
|
||||
send "snmp-server location \"${hostConfig.location}\"\r"
|
||||
expect "(config)# "
|
||||
send "snmp-server contact \"astro@spaceboyz.net\"\r"
|
||||
expect "(config)# "
|
||||
send "password manager\r"
|
||||
expect "New password for Manager: "
|
||||
send "${hostConfig.password}\r"
|
||||
expect "Please retype new password for Manager: "
|
||||
send "${hostConfig.password}\r"
|
||||
expect "(config)# "
|
||||
|
||||
# TODO: ssh, password
|
||||
|
||||
# Enable Logging
|
||||
send "logging ${config.site.net.mgmt.hosts4.logging}\r"
|
||||
expect "(config)# "
|
||||
send "logging facility local6\r"
|
||||
expect "(config)# "
|
||||
|
||||
# todo ntp
|
||||
# timesync sntp
|
||||
# ip timep manual {#ntp#} interval 10
|
||||
|
||||
${concatMapStrings (net:
|
||||
let
|
||||
netConfig = config.site.net.${net};
|
||||
vlan = toString netConfig.vlan;
|
||||
inherit (config.site.net.${net}) hosts4;
|
||||
hostAddr4 = hosts4.${hostName};
|
||||
prefixLength = elemAt (
|
||||
builtins.split "/" netConfig.subnet4
|
||||
) 2;
|
||||
netmask = self.lib.netmasks.${prefixLength};
|
||||
in ''
|
||||
send "vlan ${vlan}\r"
|
||||
expect "(vlan-${vlan})#"
|
||||
|
||||
send "name ${hostName}\r"
|
||||
expect "(vlan-${vlan})#"
|
||||
|
||||
send "jumbo\r"
|
||||
expect "(vlan-${vlan})#"
|
||||
|
||||
# Actually only used for mgmt_vlan, switches are not routers
|
||||
${optionalString (hosts4 ? ${hostName}) ''
|
||||
send "ip address ${hostAddr4} ${netmask}\r"
|
||||
expect "(vlan-${vlan})#"
|
||||
''}
|
||||
|
||||
send "exit\r"
|
||||
expect "(config)# "
|
||||
|
||||
${if net == "mgmt"
|
||||
then ''
|
||||
send "management-vlan ${vlan}\r"
|
||||
expect "(config)# "
|
||||
'' else ''
|
||||
# If not mgmt, reset all VLAN mappings
|
||||
send "no vlan ${vlan} tagged all\r"
|
||||
expect "(config)# "
|
||||
send "no vlan ${vlan} untagged all\r"
|
||||
expect "(config)# "
|
||||
''}
|
||||
'') (builtins.attrNames config.site.net)
|
||||
}
|
||||
|
||||
${concatMapStrings (name:
|
||||
let
|
||||
linkConfig = hostConfig.links.${name};
|
||||
isAccess = config.site.net ? ${name};
|
||||
netConfig = config.site.net.${name};
|
||||
isTrunk = !isAccess;
|
||||
isBond = isTrunk && builtins.length linkConfig.ports > 1;
|
||||
ports = concatStringsSep "," linkConfig.ports;
|
||||
in
|
||||
if isTrunk && isBond
|
||||
then ''
|
||||
send "interface ${ports} lacp active\r"
|
||||
expect "(config)# "
|
||||
send "trunk ${ports} trk${linkConfig.group} lacp\r"
|
||||
expect "(config)# "
|
||||
|
||||
${concatMapStrings (vlan: ''
|
||||
send "vlan ${toString vlan} tagged trk${linkConfig.group}\r"
|
||||
expect "(config)# "
|
||||
'') linkConfig.vlans}
|
||||
''
|
||||
|
||||
else if isTrunk
|
||||
then ''
|
||||
send "no trunk ${ports}\r"
|
||||
expect "(config)# "
|
||||
send "no interface ${ports} lacp\r"
|
||||
expect "(config)# "
|
||||
|
||||
${concatMapStrings (vlan: ''
|
||||
send "vlan ${toString vlan} tagged ${ports}\r"
|
||||
expect "(config)# "
|
||||
'') linkConfig.vlans}
|
||||
''
|
||||
|
||||
else ''
|
||||
send "no trunk ${ports}\r"
|
||||
expect "(config)# "
|
||||
|
||||
send "vlan ${toString netConfig.vlan} untagged ${ports}\r"
|
||||
expect "(config)# "
|
||||
''
|
||||
) (builtins.attrNames hostConfig.links)}
|
||||
|
||||
send "exit\r"
|
||||
expect "${hostName}# "
|
||||
|
||||
send "write memory\r"
|
||||
expect "${hostName}# "
|
||||
send "exit\r"
|
||||
expect "${hostName}> "
|
||||
send "exit\r"
|
||||
expect "Do you want to log out "
|
||||
expect "y/n]? "
|
||||
send "y"
|
||||
''
|
|
@ -0,0 +1,131 @@
|
|||
# http://static.tp-link.com/res/down/doc/TL-SG3210(UN)_V2.0_CLI_.pdf
|
||||
{ self, pkgs, hostName, config, hostConfig, ... }:
|
||||
with pkgs;
|
||||
with lib;
|
||||
''
|
||||
#! ${pkgs.expect}/bin/expect -f
|
||||
|
||||
spawn ${pkgs.inetutils}/bin/telnet ${config.site.net.mgmt.hosts4.${hostName}}
|
||||
expect "Password:"
|
||||
send "${hostConfig.password}\r"
|
||||
expect ">"
|
||||
send "\r"
|
||||
expect ">"
|
||||
send "enable\r"
|
||||
expect "Password:"
|
||||
send "${hostConfig.password}\r"
|
||||
expect "#"
|
||||
send "configure\r"
|
||||
expect "(config)#"
|
||||
|
||||
send "enable secret 0 ${hostConfig.password}\r"
|
||||
expect "(config)#"
|
||||
#send "enable password 0 ${hostConfig.password}\r"
|
||||
#expect "(config)#"
|
||||
send "service password-encryption\r"
|
||||
expect "(config)#"
|
||||
send "user name admin privilege admin secret 0 ${hostConfig.password}\r"
|
||||
expect "(config)#"
|
||||
|
||||
send "hostname \"${hostName}\"\r"
|
||||
expect "(config)#"
|
||||
send "location \"${hostConfig.location}\"\r"
|
||||
expect "(config)#"
|
||||
|
||||
send "logging host index 1 ${config.site.net.mgmt.hosts4.logging} 6\r"
|
||||
expect "(config)#"
|
||||
|
||||
send "ip management-vlan ${toString config.site.net.mgmt.vlan}\r"
|
||||
expect "(config)#"
|
||||
send "ip ssh server\r"
|
||||
expect "(config)#"
|
||||
send "telnet enable\r"
|
||||
expect "(config)#"
|
||||
send "line vty 0 15\r"
|
||||
expect "(config-line)#"
|
||||
send "password 0 ${hostConfig.password}\r"
|
||||
expect "(config-line)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
|
||||
${concatMapStrings (net:
|
||||
let
|
||||
netConfig = config.site.net.${net};
|
||||
vlan = toString netConfig.vlan;
|
||||
inherit (config.site.net.${net}) hosts4;
|
||||
hostAddr4 = hosts4.${hostName};
|
||||
prefixLength = elemAt (
|
||||
builtins.split "/" netConfig.subnet4
|
||||
) 2;
|
||||
netmask = self.lib.netmasks.${prefixLength};
|
||||
in ''
|
||||
${optionalString (net != "mgmt") ''
|
||||
send "vlan ${vlan}\r"
|
||||
expect "(config-vlan)#"
|
||||
send "name \"${net}\"\r"
|
||||
expect "(config-vlan)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
''}
|
||||
|
||||
# Actually only used for mgmt_vlan, switches are not routers
|
||||
send "interface vlan ${vlan}\r"
|
||||
expect "(config-if)#"
|
||||
${optionalString (hosts4 ? ${hostName}) ''
|
||||
send "ip address ${hostAddr4} ${netmask}\r"
|
||||
expect "(config-if)#"
|
||||
''}
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
''
|
||||
) (builtins.attrNames config.site.net)}
|
||||
|
||||
${concatMapStrings (name:
|
||||
let
|
||||
linkConfig = hostConfig.links.${name};
|
||||
isAccess = config.site.net ? ${name};
|
||||
netConfig = config.site.net.${name};
|
||||
isTrunk = !isAccess;
|
||||
isBond = isTrunk && builtins.length linkConfig.ports > 1;
|
||||
ports = concatStringsSep "," linkConfig.ports;
|
||||
in
|
||||
if isTrunk
|
||||
then ''
|
||||
send "interface range gigabitEthernet 1/0/${ports}\r"
|
||||
expect "(config-if-range)#"
|
||||
send "switchport mode trunk\r"
|
||||
expect "(config-if-range)#"
|
||||
${if (builtins.length linkConfig.ports > 1)
|
||||
then ''
|
||||
send "channel-group ${linkConfig.group} mode active\r"
|
||||
expect "(config-if-range)#"
|
||||
#send "port-channel load-balance src-dst-ip\r"
|
||||
#expect "(config-if-range)#"
|
||||
'' else ''
|
||||
send "no channel-group\r"
|
||||
expect "(config-if-range)#"
|
||||
''}
|
||||
send "switchport trunk allowed vlan ${concatStringsSep "," (map toString linkConfig.vlans)}\r"
|
||||
expect "(config-if-range)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
'' else ''
|
||||
send "interface range gigabitEthernet 1/0/${ports}\r"
|
||||
expect "(config-if-range)#"
|
||||
send "switchport mode access\r"
|
||||
expect "(config-if-range)#"
|
||||
send "switchport access vlan ${toString netConfig.vlan}\r"
|
||||
expect "(config-if-range)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
''
|
||||
) (builtins.attrNames hostConfig.links)}
|
||||
|
||||
send "exit\r"
|
||||
expect "#"
|
||||
send "copy running-config startup-config\r"
|
||||
expect "#"
|
||||
send "exit\r"
|
||||
expect ">"
|
||||
send "exit\r"
|
||||
''
|
|
@ -0,0 +1,105 @@
|
|||
# https://www.crc.id.au/real-console-on-linksys-srw2024-switch/
|
||||
{ self, pkgs, hostName, config, hostConfig, ... }:
|
||||
with pkgs;
|
||||
with lib;
|
||||
''
|
||||
#! ${expect}/bin/expect -f
|
||||
|
||||
spawn ${inetutils}/bin/telnet ${config.site.net.mgmt.hosts4.${hostName}}
|
||||
expect "Password:"
|
||||
send "admin\t${hostConfig.password}\r"
|
||||
|
||||
# ^z
|
||||
send "\x1A"
|
||||
expect ">"
|
||||
send "lcli\r"
|
||||
|
||||
expect "User Name:"
|
||||
send "admin\r"
|
||||
expect "Password:"
|
||||
send "${hostConfig.password}\r"
|
||||
|
||||
expect "# "
|
||||
send "configure\r"
|
||||
expect "(config)# "
|
||||
send "hostname ${hostName}\r"
|
||||
expect "(config)# "
|
||||
send "management vlan 4094\r"
|
||||
expect "(config)# "
|
||||
send "vlan database\r"
|
||||
expect "(config-vlan)# "
|
||||
|
||||
${concatMapStrings (net: ''
|
||||
send "vlan ${toString config.site.net.${net}.vlan}\r"
|
||||
expect "(config-vlan)#"
|
||||
'') (builtins.attrNames config.site.net)}
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
|
||||
${concatMapStrings (net: ''
|
||||
send "interface vlan ${toString config.site.net.${net}.vlan}\r"
|
||||
expect "(config-if)#"
|
||||
send "name ${net}\r"
|
||||
expect "(config-if)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
'') (builtins.attrNames config.site.net)}
|
||||
|
||||
${concatMapStrings (name:
|
||||
let
|
||||
linkConfig = hostConfig.links.${name};
|
||||
isAccess = config.site.net ? ${name};
|
||||
netConfig = config.site.net.${name};
|
||||
isTrunk = !isAccess;
|
||||
isBond = isTrunk && builtins.length linkConfig.ports > 1;
|
||||
ports = concatStringsSep "," linkConfig.ports;
|
||||
in
|
||||
if isTrunk && isBond
|
||||
then ''
|
||||
send "interface range ethernet ${ports}\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport trunk allowed vlan remove all\r"
|
||||
expect "(config-if)#"
|
||||
send "channel-group ${linkConfig.group} mode auto\r"
|
||||
expect "(config-if)#"
|
||||
send "interface port-channel ${linkConfig.group}\r"
|
||||
expect "(config-if)#"
|
||||
send "exit\r"
|
||||
|
||||
send "interface port-channel ${linkConfig.group}\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport mode trunk\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport trunk allowed vlan add ${concatStringsSep "," (map toString linkConfig.vlans)}\r"
|
||||
expect "(config-if)#"
|
||||
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
''
|
||||
else if isTrunk
|
||||
then concatMapStrings (port: ''
|
||||
send "interface ethernet ${port}\r"
|
||||
expect "(config-if)#"
|
||||
send "no channel-group\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport mode trunk\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport trunk allowed vlan add ${concatStringsSep "," (map toString linkConfig.vlans)}\r"
|
||||
expect "(config-if)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
'') linkConfig.ports
|
||||
else concatMapStrings (port: ''
|
||||
send "interface ethernet ${port}\r"
|
||||
expect "(config-if)#"
|
||||
send "no channel-group\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport mode access\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport access vlan ${toString netConfig.vlan}\r"
|
||||
expect "(config-if)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
'') linkConfig.ports
|
||||
) (builtins.attrNames hostConfig.links)}
|
||||
''
|
|
@ -220,7 +220,7 @@ switches:
|
|||
- g39
|
||||
- g40
|
||||
vlans: *server1_vlans
|
||||
c3d2-server5:
|
||||
server5:
|
||||
mode: bond
|
||||
group: 6
|
||||
ports:
|
||||
|
@ -237,7 +237,7 @@ switches:
|
|||
- cluster
|
||||
- bmx
|
||||
- priv23
|
||||
c3d2-server6:
|
||||
server6:
|
||||
mode: bond
|
||||
group: 8
|
||||
ports:
|
||||
|
@ -246,7 +246,7 @@ switches:
|
|||
- g7
|
||||
- g8
|
||||
vlans: *server_vlans
|
||||
c3d2-server7:
|
||||
server7:
|
||||
mode: bond
|
||||
group: 7
|
||||
ports:
|
||||
|
@ -255,7 +255,7 @@ switches:
|
|||
- g14
|
||||
- g15
|
||||
vlans: *server_vlans
|
||||
c3d2-server8:
|
||||
server8:
|
||||
mode: bond
|
||||
group: 5
|
||||
ports:
|
||||
|
@ -421,14 +421,14 @@ switches:
|
|||
- mgmt
|
||||
- pub
|
||||
- priv17
|
||||
c3d2-server3:
|
||||
server3:
|
||||
mode: bond
|
||||
group: 1
|
||||
ports:
|
||||
- GigabitEthernet1/0/30
|
||||
- GigabitEthernet1/0/31
|
||||
vlans: *server_vlans
|
||||
c3d2-server9:
|
||||
server9:
|
||||
mode: bond
|
||||
group: 3
|
||||
ports:
|
||||
|
@ -734,6 +734,7 @@ switches:
|
|||
switch-b1:
|
||||
mode: bond
|
||||
ports: 1
|
||||
group: 1
|
||||
vlans:
|
||||
- mgmt
|
||||
- pub
|
||||
|
|
|
@ -1,151 +0,0 @@
|
|||
{# http://h20628.www2.hp.com/km-ext/kmcsdirect/emr_na-c02586144-1.pdf #}
|
||||
|
||||
{%- macro increment(dct, key, inc=1) -%}
|
||||
{% if dct.update({key: dct[key] + inc}) %} {% endif %}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- import_yaml "netmasks.yaml" as netmasks -%}
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
spawn telnet {{ pillar['hosts-inet']['mgmt'][hostname] }}
|
||||
expect "Password:"
|
||||
send "{{ switch['password'] }}\r"
|
||||
expect ">"
|
||||
send "system-view\r"
|
||||
expect "]"
|
||||
|
||||
send "sysname {{ hostname }}\r"
|
||||
expect "]"
|
||||
|
||||
send "user-interface vty 0 4\r"
|
||||
expect "ui-vty0-4]"
|
||||
send "screen-length 0\r"
|
||||
expect "ui-vty0-4]"
|
||||
send "user privilege level 3\r"
|
||||
expect "ui-vty0-4]"
|
||||
send "set authentication password simple {{ switch['password'] }}\r"
|
||||
expect "ui-vty0-4]"
|
||||
send "quit\r"
|
||||
expect "{{ hostname }}]"
|
||||
|
||||
send "local-user admin\r"
|
||||
expect -- "-luser-admin]"
|
||||
send "password simple {{ switch['password'] }}\r"
|
||||
expect -- "-luser-admin]"
|
||||
send "quit\r"
|
||||
expect "{{ hostname }}]"
|
||||
|
||||
{# Enable logging #}
|
||||
send "info-center enable\r"
|
||||
expect "]"
|
||||
send "info-center loghost {{logging}} channel loghost facility local6\r"
|
||||
expect "]"
|
||||
send "info-center source default channel loghost log level informational\r"
|
||||
expect "]"
|
||||
|
||||
|
||||
{%- for name, vlan in pillar['vlans'].items() %}
|
||||
send "vlan {{ vlan }}\r"
|
||||
expect -- "-vlan{{ vlan }}]"
|
||||
send "name {{ name }}\r"
|
||||
expect -- "-vlan{{ vlan }}]"
|
||||
|
||||
{%- if name == 'mgmt' %}
|
||||
{# Actually only used for mgmt_vlan, switches are not routers #}
|
||||
send "interface Vlan-interface {{ vlan }}\r"
|
||||
expect "]"
|
||||
{%- set net_hosts = pillar['hosts-inet'].get(name) %}
|
||||
{%- set ipaddr = net_hosts and net_hosts.get(hostname) %}
|
||||
{%- if ipaddr %}
|
||||
send "ip address {{ ipaddr }} {{ netmasks[pillar['subnets-inet'][name].split('/')[1]] }}\r"
|
||||
expect "]"
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
send "quit\r"
|
||||
expect "{{ hostname }}]"
|
||||
{%- endfor %}
|
||||
|
||||
{%- for name, conf in switch['ports'].items() %}
|
||||
{%- if conf['mode'] == 'trunk' or conf['mode'] == 'bond' %}
|
||||
{%- if conf['mode'] == 'bond' %}
|
||||
send "link-aggregation group {{ conf['group'] }} mode static\r"
|
||||
expect {
|
||||
"This aggregation will be modified to static mode. Continue ?" {
|
||||
send "Y\r"
|
||||
}
|
||||
"]" {}
|
||||
}
|
||||
send "link-aggregation group {{ conf['group'] }} description {{name}}\r"
|
||||
expect "]"
|
||||
{%- endif %}
|
||||
{%- for port in conf['ports'] %}
|
||||
send "interface {{ port }}\r"
|
||||
expect "]"
|
||||
send "undo stp edged-port\r"
|
||||
expect "]"
|
||||
{%- if conf['mode'] == 'bond' %}
|
||||
send "lacp enable\r"
|
||||
expect "]"
|
||||
send "undo port link-aggregation group\r"
|
||||
expect "]"
|
||||
send "port link-aggregation group {{ conf['group'] }}\r"
|
||||
{%- else %}
|
||||
send "undo lacp enable\r"
|
||||
{%- endif %}
|
||||
expect "]"
|
||||
send "jumboframe enable\r"
|
||||
expect "]"
|
||||
{%- if conf.get('vlans') %}
|
||||
send "port link-type trunk\r"
|
||||
expect "]"
|
||||
# Set dummy default vlan
|
||||
send "port trunk pvid vlan 4094\r"
|
||||
expect "]"
|
||||
# Deconfigure all but mgmt vlan
|
||||
send "undo port trunk permit vlan 2 to 4094\r"
|
||||
expect "]"
|
||||
{%- for vlan_name in conf['vlans'] %}
|
||||
send "port trunk permit vlan {{ pillar['vlans'][vlan_name] }}\r"
|
||||
expect "]"
|
||||
{%- endfor %}
|
||||
{%- else %}
|
||||
send "port link-type access\r"
|
||||
expect "]"
|
||||
send "port access vlan {{ pillar['vlans'][conf['access']] }}\r"
|
||||
expect "]"
|
||||
{%- endif %}
|
||||
send "quit\r"
|
||||
expect "{{ hostname }}]"
|
||||
{%- endfor %}
|
||||
|
||||
{%- elif conf['mode'] == 'access' %}
|
||||
{%- for port in conf['ports'] %}
|
||||
send "interface {{ port }}\r"
|
||||
expect "]"
|
||||
send "undo port link-aggregation group\r"
|
||||
expect "]"
|
||||
send "port link-type access\r"
|
||||
expect "]"
|
||||
{%- if name == 'mgmt' %}
|
||||
send "undo port access vlan\r"
|
||||
expect "]"
|
||||
{%- else %}
|
||||
send "port access vlan {{ pillar['vlans'][name] }}\r"
|
||||
expect "]"
|
||||
{%- endif %}
|
||||
send "quit\r"
|
||||
expect "{{ hostname }}]"
|
||||
{%- endfor %}
|
||||
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
|
||||
send "save main\r"
|
||||
expect "Y/N]"
|
||||
send "YES\r"
|
||||
expect "press the enter key):"
|
||||
send "\r"
|
||||
expect "]"
|
||||
send "quit\r"
|
||||
expect ">"
|
||||
send "quit\r"
|
|
@ -1,129 +0,0 @@
|
|||
{# http://ftp.hp.com/pub/networking/software/2600-2800-4100-6108-MgmtConfig-Oct2005-59906023.pdf #}
|
||||
{%- import_yaml "netmasks.yaml" as netmasks -%}
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
spawn telnet {{ pillar['hosts-inet']['mgmt'][hostname] }}
|
||||
expect "Press any key to continue"
|
||||
send "\r"
|
||||
expect "assword: "
|
||||
send "{{ switch['password'] }}\r"
|
||||
expect "#"
|
||||
send "configure terminal\r"
|
||||
expect "(config)# "
|
||||
|
||||
send "hostname {{ hostname }}\r"
|
||||
expect "(config)# "
|
||||
send "snmp-server location \"{{ switch['location'] }}\"\r"
|
||||
expect "(config)# "
|
||||
send "snmp-server contact \"astro@spaceboyz.net\"\r"
|
||||
expect "(config)# "
|
||||
send "password manager\r"
|
||||
expect "New password for Manager: "
|
||||
send "{{ switch['password'] }}\r"
|
||||
expect "Please retype new password for Manager: "
|
||||
send "{{ switch['password'] }}\r"
|
||||
expect "(config)# "
|
||||
|
||||
# TODO: ssh, password
|
||||
|
||||
{# Enable Logging #}
|
||||
send "logging {{logging}}\r"
|
||||
expect "(config)# "
|
||||
send "logging facility local6\r"
|
||||
expect "(config)# "
|
||||
|
||||
# todo ntp
|
||||
# timesync sntp
|
||||
# ip timep manual {#ntp#} interval 10
|
||||
|
||||
{%- for name, vlan in pillar['vlans'].items() %}
|
||||
send "vlan {{ vlan }}\r"
|
||||
expect "(vlan-{{ vlan }})#"
|
||||
|
||||
send "name {{ name }}\r"
|
||||
expect "(vlan-{{ vlan }})#"
|
||||
|
||||
send "jumbo\r"
|
||||
expect "(vlan-{{ vlan }})#"
|
||||
|
||||
{# Actually only used for mgmt_vlan, switches are not routers #}
|
||||
{%- set net_hosts = pillar['hosts-inet'].get(name) %}
|
||||
{%- set ipaddr = net_hosts and net_hosts.get(hostname) %}
|
||||
{%- if ipaddr %}
|
||||
send "ip address {{ ipaddr }} {{ netmasks[pillar['subnets-inet'][name].split('/')[1]] }}\r"
|
||||
expect "(vlan-{{ vlan }})#"
|
||||
{%- endif %}
|
||||
|
||||
send "exit\r"
|
||||
expect "(config)# "
|
||||
|
||||
{%- if name == 'mgmt' %}
|
||||
send "management-vlan {{ vlan }}\r"
|
||||
expect "(config)# "
|
||||
{%- else %}
|
||||
# If not mgmt, reset all VLAN mappings
|
||||
send "no vlan {{ vlan }} tagged all\r"
|
||||
expect "(config)# "
|
||||
send "no vlan {{ vlan }} untagged all\r"
|
||||
expect "(config)# "
|
||||
{%- endif %}
|
||||
|
||||
{%- endfor %}
|
||||
|
||||
{%- for name, conf in switch['ports'].items() %}
|
||||
{%- if conf['mode'] == 'bond' %}
|
||||
|
||||
{%- if not conf.get('lacp', True) %}
|
||||
send "trunk {{ conf['ports'] }} trk{{ conf['group'] }} trunk\r"
|
||||
expect "(config)# "
|
||||
|
||||
{%- else %}
|
||||
send "interface {{ conf['ports'] }} lacp active\r"
|
||||
expect "(config)# "
|
||||
send "trunk {{ conf['ports'] }} trk{{ conf['group'] }} lacp\r"
|
||||
expect "(config)# "
|
||||
{%- endif %}
|
||||
|
||||
{%- for vlan_name in conf['vlans'] %}
|
||||
send "vlan {{ pillar['vlans'][vlan_name] }} tagged trk{{ conf['group'] }}\r"
|
||||
expect "(config)# "
|
||||
{%- endfor %}
|
||||
|
||||
{%- elif conf['mode'] == 'trunk' %}
|
||||
send "no trunk {{ conf['ports'] }}\r"
|
||||
expect "(config)# "
|
||||
send "no interface {{ conf['ports'] }} lacp\r"
|
||||
expect "(config)# "
|
||||
|
||||
{%- for vlan_name in conf['vlans'] %}
|
||||
send "vlan {{ pillar['vlans'][vlan_name] }} tagged {{ conf['ports'] }}\r"
|
||||
expect "(config)# "
|
||||
{%- endfor %}
|
||||
|
||||
{%- elif conf['mode'] == 'access' %}
|
||||
|
||||
send "no trunk {{ conf['ports'] }}\r"
|
||||
expect "(config)# "
|
||||
|
||||
send "vlan {{ pillar['vlans'][name] }} untagged {{ conf['ports'] }}\r"
|
||||
expect "(config)# "
|
||||
|
||||
{%- endif %}
|
||||
|
||||
{%- if conf.get('nostp') %}
|
||||
send "spanning-tree {{ conf['ports'] }} bpdu-filter\r"
|
||||
expect "(config)# "
|
||||
{%- endif %}
|
||||
|
||||
{%- endfor %}
|
||||
send "exit\r"
|
||||
expect "{{ hostname }}# "
|
||||
|
||||
send "write memory\r"
|
||||
expect "{{ hostname }}# "
|
||||
send "exit\r"
|
||||
expect "{{ hostname }}> "
|
||||
send "exit\r"
|
||||
expect "Do you want to log out "
|
||||
expect "y/n]? "
|
||||
send "y"
|
|
@ -1,115 +0,0 @@
|
|||
{# http://static.tp-link.com/res/down/doc/TL-SG3210(UN)_V2.0_CLI_.pdf #}
|
||||
{%- import_yaml "netmasks.yaml" as netmasks -%}
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
#spawn cu -s 38400 -l /dev/ttyUSB0
|
||||
#stty raw -echo
|
||||
spawn telnet {{ pillar['hosts-inet']['mgmt'][hostname] }}
|
||||
expect "Password:"
|
||||
send "{{ switch['password'] }}\r"
|
||||
expect ">"
|
||||
send "\r"
|
||||
expect ">"
|
||||
send "enable\r"
|
||||
expect "Password:"
|
||||
send "{{ switch['password'] }}\r"
|
||||
expect "#"
|
||||
send "configure\r"
|
||||
expect "(config)#"
|
||||
|
||||
send "enable secret 0 {{ switch['password'] }}\r"
|
||||
expect "(config)#"
|
||||
#send "enable password 0 {{ switch['password'] }}\r"
|
||||
#expect "(config)#"
|
||||
send "service password-encryption\r"
|
||||
expect "(config)#"
|
||||
send "user name admin privilege admin secret 0 {{ switch['password'] }}\r"
|
||||
expect "(config)#"
|
||||
|
||||
send "hostname \"{{ hostname }}\"\r"
|
||||
expect "(config)#"
|
||||
send "location \"{{ switch['location'] }}\"\r"
|
||||
expect "(config)#"
|
||||
|
||||
send "logging host index 1 {{logging}} 6\r"
|
||||
expect "(config)#"
|
||||
|
||||
{%- set mgmt_vlan = pillar['vlans']['mgmt'] %}
|
||||
send "ip management-vlan {{ mgmt_vlan }}\r"
|
||||
expect "(config)#"
|
||||
send "ip ssh server\r"
|
||||
expect "(config)#"
|
||||
send "telnet enable\r"
|
||||
expect "(config)#"
|
||||
send "line vty 0 15\r"
|
||||
expect "(config-line)#"
|
||||
send "password 0 {{ switch['password'] }}\r"
|
||||
expect "(config-line)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
|
||||
{%- for name, vlan in pillar['vlans'].items() %}
|
||||
{%- if name != 'mgmt' %}
|
||||
send "vlan {{ vlan }}\r"
|
||||
expect "(config-vlan)#"
|
||||
send "name \"{{ name }}\"\r"
|
||||
expect "(config-vlan)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
{%- endif %}
|
||||
|
||||
{# Actually only used for mgmt_vlan, switches are not routers #}
|
||||
send "interface vlan {{ vlan }}\r"
|
||||
expect "(config-if)#"
|
||||
{%- set net_hosts = pillar['hosts-inet'].get(name) %}
|
||||
{%- set ipaddr = net_hosts and net_hosts.get(hostname) %}
|
||||
{%- if ipaddr %}
|
||||
send "ip address {{ ipaddr }} {{ netmasks[pillar['subnets-inet'][name].split('/')[1]] }}\r"
|
||||
expect "(config-if)#"
|
||||
{%- endif %}
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
{%- endfor %}
|
||||
|
||||
{%- set group = 0 %}
|
||||
{%- for name, conf in switch['ports'].items() %}
|
||||
{%- if conf['mode'] == 'trunk' or conf['mode'] == 'bond' %}
|
||||
send "interface range gigabitEthernet 1/0/{{ conf['ports'] }}\r"
|
||||
expect "(config-if-range)#"
|
||||
send "switchport mode trunk\r"
|
||||
expect "(config-if-range)#"
|
||||
{%- set group = group + 1 %}
|
||||
send "channel-group {{ group }} mode passive\r"
|
||||
expect "(config-if-range)#"
|
||||
#send "port-channel load-balance src-dst-ip\r"
|
||||
#expect "(config-if-range)#"
|
||||
{%- set vlan_ids = [] %}
|
||||
{%- for name in conf['vlans'] %}
|
||||
{%- if vlan_ids.append('' ~ pillar['vlans'][name]) %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
send "switchport trunk allowed vlan {{ ','.join(vlan_ids) }}\r"
|
||||
expect "(config-if-range)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
{%- elif conf['mode'] == 'access' %}
|
||||
{%- for port in conf['ports'] %}
|
||||
send "interface range gigabitEthernet 1/0/{{ port }}\r"
|
||||
expect "(config-if-range)#"
|
||||
send "switchport mode access\r"
|
||||
expect "(config-if-range)#"
|
||||
send "switchport access vlan {{ pillar['vlans'][name] }}\r"
|
||||
expect "(config-if-range)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
|
||||
send "exit\r"
|
||||
expect "#"
|
||||
send "copy running-config startup-config\r"
|
||||
expect "#"
|
||||
send "exit\r"
|
||||
expect ">"
|
||||
send "exit\r"
|
|
@ -1,104 +0,0 @@
|
|||
{# https://www.crc.id.au/real-console-on-linksys-srw2024-switch/ #}
|
||||
{%- import_yaml "netmasks.yaml" as netmasks -%}
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
spawn telnet {{ pillar['hosts-inet']['mgmt'][hostname] }}
|
||||
expect "Password:"
|
||||
send "admin\t{{ switch['password'] }}\r"
|
||||
|
||||
# ^z
|
||||
send "\x1A"
|
||||
expect ">"
|
||||
send "lcli\r"
|
||||
|
||||
expect "User Name:"
|
||||
send "admin\r"
|
||||
expect "Password:"
|
||||
send "{{ switch['password'] }}\r"
|
||||
|
||||
expect "# "
|
||||
send "configure\r"
|
||||
expect "(config)# "
|
||||
send "hostname {{ hostname }}\r"
|
||||
expect "(config)# "
|
||||
send "management vlan 4094\r"
|
||||
expect "(config)# "
|
||||
send "vlan database\r"
|
||||
expect "(config-vlan)# "
|
||||
{%- for name, vlan in pillar['vlans'].items() %}
|
||||
send "vlan {{ vlan }}\r"
|
||||
expect "(config-vlan)#"
|
||||
{%- endfor %}
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
{%- for name, vlan in pillar['vlans'].items() %}
|
||||
send "interface vlan {{ vlan }}\r"
|
||||
expect "(config-if)#"
|
||||
send "name {{ name }}\r"
|
||||
expect "(config-if)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
{%- endfor %}
|
||||
|
||||
{%- for name, conf in switch['ports'].items() %}
|
||||
|
||||
{%- if conf['mode'] == 'trunk' %}
|
||||
{%- for port in conf['ports'] %}
|
||||
send "interface ethernet {{ port }}\r"
|
||||
expect "(config-if)#"
|
||||
send "no channel-group\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport mode trunk\r"
|
||||
expect "(config-if)#"
|
||||
{%- set vlan_ids = [] %}
|
||||
{%- for name in conf['vlans'] %}
|
||||
{%- if vlan_ids.append('' ~ pillar['vlans'][name]) %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
send "switchport trunk allowed vlan add {{ ','.join(vlan_ids) }}\r"
|
||||
expect "(config-if)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
{%- endfor %}
|
||||
|
||||
{%- elif conf['mode'] == 'bond' %}
|
||||
send "interface range ethernet {{ ','.join(conf['ports']) }}\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport trunk allowed vlan remove all\r"
|
||||
expect "(config-if)#"
|
||||
send "channel-group {{ conf['group'] }} mode auto\r"
|
||||
expect "(config-if)#"
|
||||
send "interface port-channel {{ conf['group'] }}\r"
|
||||
expect "(config-if)#"
|
||||
send "exit\r"
|
||||
|
||||
send "interface port-channel {{ conf['group'] }}\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport mode trunk\r"
|
||||
expect "(config-if)#"
|
||||
{%- set vlan_ids = [] %}
|
||||
{%- for name in conf['vlans'] %}
|
||||
{%- if vlan_ids.append('' ~ pillar['vlans'][name]) %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
send "switchport trunk allowed vlan add {{ ','.join(vlan_ids) }}\r"
|
||||
expect "(config-if)#"
|
||||
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
|
||||
{%- elif conf['mode'] == 'access' %}
|
||||
{%- for port in conf['ports'] %}
|
||||
send "interface ethernet {{ port }}\r"
|
||||
expect "(config-if)#"
|
||||
send "no channel-group\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport mode access\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport access vlan {{ pillar['vlans'][name] }}\r"
|
||||
expect "(config-if)#"
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
Loading…
Reference in New Issue