From eb6a54d70b9d64a1c25f740072518955bfb3a15d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Paulon?= Date: Tue, 29 Sep 2020 23:55:14 +0200 Subject: [PATCH] now it fully works with re2o --- generate-conf.py | 131 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 127 insertions(+), 4 deletions(-) diff --git a/generate-conf.py b/generate-conf.py index f47752f..4717208 100644 --- a/generate-conf.py +++ b/generate-conf.py @@ -178,11 +178,119 @@ def gen_conf(master_config, switch_config, header): return conf_from_dict(config_dict) def gen_conf_re2o(re2o_config, header): - print(re2o_config.keys()) - raise RuntimeError() + mgmt_utils = re2o_config.get("switchs_management_utils") + ipv4_managers = dict() + for m in mgmt_utils.get("subnet"): + print(m) + ipv4_managers[m.get("network")] = { "ip": m.get("network"), "subnet": m.get("netmask")} + ipv6_managers = dict() + # FUCK YOU ! subnet6 c'est pas une liste de subnets mais un seul subnet + m = mgmt_utils.get("subnet6") + ipv6_managers[m.get("network")] = { "ip": m.get("network"), "subnet": m.get("netmask")} + vlans = dict() + dhcp_snooping_vlans = list() + dhcpv6_snooping_vlans = list() + arp_protect = { "vlans": list() } + for vlan in re2o_config.get("vlans"): + vlan_id = vlan["vlan_id"] + vlans[vlan_id] = vlan + range_tagged = list() + range_untagged = list() + # on récupère les ports tag et untagged + for port in re2o_config.get("ports"): + port_profile = port["get_port_profile"] + for v in port_profile["vlan_tagged"]: + print(v) + if v["vlan_id"] == vlan_id: + range_tagged.append(port["port"]) + # i n'y a qu'un seul vlan untagged + v = port_profile["vlan_untagged"] + if v is not None and v["vlan_id"] == vlan_id: + range_untagged.append(port["port"]) + vlans[vlan_id]["tagged"] = syntax_from_range(range_tagged) + vlans[vlan_id]["untagged"] = syntax_from_range(range_untagged) + # on rajoute les ips sur les vlans où il y en a + for address, iface in re2o_config.get("interfaces_subnet", dict()).items(): + # ouais y'a une autre liste là, don't ask + for i in iface: + if i["vlan_id"] == vlan_id: + if vlans[vlan_id].get("ip") is None: + vlans[vlan_id]["ip"] = dict() + vlans[vlan_id]["ip"]["addr"] = address + vlans[vlan_id]["ip"]["subnet"] = i["netmask"] + for address, iface in re2o_config.get("interfaces6_subnet", dict()).items(): + if iface["vlan_id"] == vlan_id: + if vlans[vlan_id].get("ip") is None: + vlans[vlan_id]["ip"] = dict() + vlans[vlan_id]["ip"]["addr6"] = address + vlans[vlan_id]["ip"]["subnet6"] = iface["netmask_cidr"] + # on ajoute les vlans qui ont besoin du dhcp snooping + if vlan["dhcp_snooping"]: + dhcp_snooping_vlans.append(vlan_id) + if vlan["dhcpv6_snooping"]: + dhcpv6_snooping_vlans.append(vlan_id) + if vlan["arp_protect"]: + arp_protect["vlans"].append(vlan_id) + vlans[vlan_id]["ipv6_mld"] = vlan["mld"] + # on récupère les informations intéressantes sur les ports + mac_based_ports = list() + ra_guard_ports = list() + interfaces = list() + loop_protect = { "ports": list()} + for port in re2o_config.get("ports"): + port_profile = port["get_port_profile"] + if port_profile["ra_guard"]: + ra_guard_ports.append(port["port"]) + if port_profile["loop_protect"]: + loop_protect["ports"].append(port["port"]) + iface = { + "name": port["pretty_name"], + "number": port["port"], + "dhcp_trust": not port_profile["dhcp_snooping"], + "dhcpv6_trust": not port_profile["dhcpv6_snooping"], + "flowcontrol": port_profile["flow_control"], + "arp_trust": not port_profile["arp_protect"], + } + if port_profile["radius_type"] == "MAC-radius": + mac_based_ports.append(port["port"]) + iface["mac_based"] = True + iface["addr_limit"] = port_profile["mac_limit"] + iface["logoff"] = master_config.get("radius_logoff") + interfaces.append(iface) + loop_protect["ports"] = syntax_from_range(loop_protect["ports"]) + arp_protect["vlans"] = syntax_from_range(arp_protect["vlans"], vlan_syntax=True) + interfaces.sort(key=lambda x: x["number"]) + radius_key = re2o_config.get("get_radius_key_value") + radius_servers = [ {"ip": i, "secret": radius_key } for i in mgmt_utils["radius_servers"]["ipv4"] + mgmt_utils["radius_servers"]["ipv6"]] config_dict = { - "header": header + "header": header, + "location": re2o_config.get("switchbay").get("name"), + "hostname": re2o_config.get("short_name"), + "dhcp_servers": mgmt_utils.get("dhcp_servers").get("ipv4"), + "dhcpv6_servers": mgmt_utils.get("dhcp_servers").get("ipv6"), + "ipv4_managers": ipv4_managers, + "ipv6_managers": ipv6_managers, + "vlans": vlans, + "dhcp_snooping_vlans": syntax_from_range(dhcp_snooping_vlans, vlan_syntax=True), + "dhcpv6_snooping_vlans": syntax_from_range(dhcpv6_snooping_vlans, vlan_syntax=True), + "logging": mgmt_utils["log_servers"]["ipv4"] + mgmt_utils["log_servers"]["ipv6"], + "sntp": mgmt_utils["ntp_servers"]["ipv4"] + mgmt_utils["ntp_servers"]["ipv6"], + "dns": mgmt_utils["dns_recursive_servers"]["ipv4"] + mgmt_utils["dns_recursive_servers"]["ipv6"], + "radius_servers": radius_servers, + "snmp_user": master_config.get("snmp_user"), + "unauth_redirect": master_config.get("unauth_redirect"), + "mac_based_ports": syntax_from_range(mac_based_ports), + "ra_guard_ports": syntax_from_range(ra_guard_ports), + "loop_protect": loop_protect, + "arp_protect": arp_protect, + "interfaces": interfaces, + "FUCK": ['interfaces_subnet', 'ports', 'ipv6', 'ipv4', 'get_radius_key_value', 'interfaces6_subnet', 'list_modules'] } + pprint(re2o_config) +# pprint(re2o_config.get("interfaces_subnet")) +# pprint(re2o_config.get("list_modules")) +# raise RuntimeError() + return conf_from_dict(config_dict) def connect_as_self(base_url, username=None): @@ -204,7 +312,7 @@ def connect_as_self(base_url, username=None): def get_switch_from_results(results, switch_name): for s in results: - if s.get("short_name"): + if s.get("short_name") == switch_name: return s return None @@ -212,11 +320,19 @@ def get_switch_from_re2o(re2o_instance, switch_name, re2o_user): base_url = "{}/api/".format(re2o_instance) token = connect_as_self(base_url, re2o_user) headers = {"Authorization": "Token " + token} + # On récupère la config du bon switch r = requests.get(base_url + "switchs/ports-config", headers=headers) sw_config = get_switch_from_results(r.json()["results"], switch_name) while r.json().get("next") and s is None: r = requests.get(r.json().get("next"), headers=headers) sw_config = get_switch_from_results(r.json()["results"], switch_name) + # on récupère les infos globales pour dhcp, managers etc. + r = requests.get(base_url + "preferences/optionaltopologie", headers=headers) + sw_config.update(r.json()) + # on récupère la liste des vlans + r = requests.get(base_url + "machines/vlan", headers=headers) + pprint(r.json().get("results")) + sw_config.update({"vlans": r.json().get("results")}) return sw_config if __name__ == "__main__": @@ -298,3 +414,10 @@ if __name__ == "__main__": session = connect_to_switch(switch_address, user="crans", key=master_config.get("ssh_private_key")) sftp_write_file(session, "/tmp/conf_tmp", "cfg/startup-config") logging.info("Deployement done for {}".format(args.switch_name)) + + +# on retire ces deux lignes qui sont hardcodées dans les templates crans +# c'est deux adresses de multicast au pif, wtf ? +# https://gitlab.crans.org/nounous/scripts/-/commit/af2d158ff1a99dee2f032a81bf14de4144d2b82f +#-filter multicast 01005e-0000fb drop 1-52 +#-filter multicast 333300-0000fb drop 1-52