From 8104b3b021ea72946911f9b3d74a024ce0594a15 Mon Sep 17 00:00:00 2001 From: Hong-Chang <62316052+Hong-Chang@users.noreply.github.com> Date: Thu, 31 Dec 2020 16:48:41 -0800 Subject: [PATCH] Send networkpolicy data from operator to daemon (#338) --- mizar/common/rpc.py | 216 ++++++++++++++++++++++ mizar/networkpolicy/networkpolicy_util.py | 11 +- mizar/obj/endpoint.py | 125 ++++++++++++- 3 files changed, 347 insertions(+), 5 deletions(-) diff --git a/mizar/common/rpc.py b/mizar/common/rpc.py index e5df5fe2..3e597d28 100644 --- a/mizar/common/rpc.py +++ b/mizar/common/rpc.py @@ -48,6 +48,18 @@ def __init__(self, ip, mac, itf='eth0', benchmark=False): self.trn_cli_update_port = f'''{self.trn_cli} update-port -i {self.phy_itf} -j''' self.trn_cli_load_pipeline_stage = f'''{self.trn_cli} load-pipeline-stage -i {self.phy_itf} -j''' self.trn_cli_unload_pipeline_stage = f'''{self.trn_cli} unload-pipeline-stage -i {self.phy_itf} -j''' + self.trn_cli_update_network_policy_ingress = f'''{self.trn_cli} update-network-policy-ingress -i {self.phy_itf} -j''' + self.trn_cli_update_network_policy_egress = f'''{self.trn_cli} update-network-policy-egress -j''' + self.trn_cli_update_network_policy_protocol_port_ingress = f'''{self.trn_cli} update-network-policy-protocol-port-ingress -i {self.phy_itf} -j''' + self.trn_cli_update_network_policy_protocol_port_egress = f'''{self.trn_cli} update-network-policy-protocol-port-egress -j''' + self.trn_cli_delete_network_policy_ingress = f'''{self.trn_cli} delete-network-policy-ingress -i {self.phy_itf} -j''' + self.trn_cli_delete_network_policy_egress = f'''{self.trn_cli} delete-network-policy-egress -j''' + self.trn_cli_delete_network_policy_protocol_port_ingress = f'''{self.trn_cli} delete-network-policy-protocol-port-ingress -i {self.phy_itf} -j''' + self.trn_cli_delete_network_policy_protocol_port_egress = f'''{self.trn_cli} delete-network-policy-protocol-port-egress -j''' + self.trn_cli_update_network_policy_enforcement_map_ingress = f'''{self.trn_cli} update-network-policy-enforcement-map-ingress -i {self.phy_itf} -j''' + self.trn_cli_update_network_policy_enforcement_map_egress = f'''{self.trn_cli} update-network-policy-enforcement-map-egress -i {self.phy_itf} -j''' + self.trn_cli_delete_network_policy_enforcement_map_ingress = f'''{self.trn_cli} delete-network-policy-enforcement-map-ingress -i {self.phy_itf} -j''' + self.trn_cli_delete_network_policy_enforcement_map_egress = f'''{self.trn_cli} delete-network-policy-enforcement-map-egress -i {self.phy_itf} -j''' self.trn_cli_load_transit_agent_xdp = f'''{self.trn_cli} load-agent-xdp''' self.trn_cli_unload_transit_agent_xdp = f'''{self.trn_cli} unload-agent-xdp''' @@ -301,3 +313,207 @@ def delete_net(self, net): logger.info("delete_net: {}".format(cmd)) returncode, text = run_cmd(cmd) logger.info("delete_net returns {} {}".format(returncode, text)) + + def update_network_policy_ingress(self, cidr_networkpolicy_list): + if len(cidr_networkpolicy_list) == 0: + return + conf_list = [] + for cidr_networkpolicy in cidr_networkpolicy_list: + conf = { + "tunnel_id": cidr_networkpolicy.vni, + "local_ip": cidr_networkpolicy.local_ip, + "cidr_prefixlen": str(cidr_networkpolicy.cidr_length), + "cidr_ip": cidr_networkpolicy.cidr, + "cidr_type": cidr_networkpolicy.get_cidr_type_int(), + "bit_value": str(cidr_networkpolicy.policy_bit_value), + } + conf_list.append(conf) + jsonconf = json.dumps(conf_list) + cmd = f'''{self.trn_cli_update_network_policy_ingress} \'{jsonconf}\'''' + logger.info("update_network_policy_ingress: {}".format(cmd)) + returncode, text = run_cmd(cmd) + logger.info("update_network_policy_ingress returns {} {}".format(returncode, text)) + + def update_network_policy_egress(self, ep, cidr_networkpolicy_list): + if len(cidr_networkpolicy_list) == 0: + return + itf = ep.get_veth_peer() + conf_list = [] + for cidr_networkpolicy in cidr_networkpolicy_list: + conf = { + "tunnel_id": cidr_networkpolicy.vni, + "local_ip": cidr_networkpolicy.local_ip, + "cidr_prefixlen": str(cidr_networkpolicy.cidr_length), + "cidr_ip": cidr_networkpolicy.cidr, + "cidr_type": cidr_networkpolicy.get_cidr_type_int(), + "bit_value": str(cidr_networkpolicy.policy_bit_value), + } + conf_list.append(conf) + jsonconf = json.dumps(conf_list) + cmd = f'''{self.trn_cli_update_network_policy_egress} \'{jsonconf}\' -i \'{itf}\'''' + logger.info("update_network_policy_egress: {}".format(cmd)) + returncode, text = run_cmd(cmd) + logger.info("update_network_policy_egress returns {} {}".format(returncode, text)) + + def delete_network_policy_ingress(self, cidr_networkpolicy_list): + if len(cidr_networkpolicy_list) == 0: + return + conf_list = [] + for cidr_networkpolicy in cidr_networkpolicy_list: + conf = { + "tunnel_id": cidr_networkpolicy.vni, + "local_ip": cidr_networkpolicy.local_ip, + "cidr_prefixlen": str(cidr_networkpolicy.cidr_length), + "cidr_ip": cidr_networkpolicy.cidr, + "cidr_type": cidr_networkpolicy.get_cidr_type_int(), + "bit_value": str(cidr_networkpolicy.policy_bit_value), + } + conf_list.append(conf) + jsonconf = json.dumps(conf_list) + cmd = f'''{self.trn_cli_delete_network_policy_ingress} \'{jsonconf}\'''' + logger.info("delete_network_policy_ingress: {}".format(cmd)) + returncode, text = run_cmd(cmd) + logger.info("delete_network_policy_ingress returns {} {}".format(returncode, text)) + + def delete_network_policy_egress(self, ep, cidr_networkpolicy_list): + if len(cidr_networkpolicy_list) == 0: + return + itf = ep.get_veth_peer() + conf_list = [] + for cidr_networkpolicy in cidr_networkpolicy_list: + conf = { + "tunnel_id": cidr_networkpolicy.vni, + "local_ip": cidr_networkpolicy.local_ip, + "cidr_prefixlen": str(cidr_networkpolicy.cidr_length), + "cidr_ip": cidr_networkpolicy.cidr, + "cidr_type": cidr_networkpolicy.get_cidr_type_int(), + "bit_value": str(cidr_networkpolicy.policy_bit_value), + } + conf_list.append(conf) + jsonconf = json.dumps(conf_list) + cmd = f'''{self.trn_cli_delete_network_policy_egress} \'{jsonconf}\' -i \'{itf}\'''' + logger.info("delete_network_policy_egress: {}".format(cmd)) + returncode, text = run_cmd(cmd) + logger.info("delete_network_policy_egress returns {} {}".format(returncode, text)) + + def update_network_policy_protocol_port_ingress(self, port_networkpolicy_list): + if len(port_networkpolicy_list) == 0: + return + conf_list = [] + for port_networkpolicy in port_networkpolicy_list: + conf = { + "tunnel_id": port_networkpolicy.vni, + "local_ip": port_networkpolicy.local_ip, + "protocol": port_networkpolicy.get_protocol_int(), + "port": port_networkpolicy.port, + "bit_value": str(port_networkpolicy.policy_bit_value), + } + conf_list.append(conf) + jsonconf = json.dumps(conf_list) + cmd = f'''{self.trn_cli_update_network_policy_protocol_port_ingress} \'{jsonconf}\'''' + logger.info("update_network_policy_protocol_port_ingress: {}".format(cmd)) + returncode, text = run_cmd(cmd) + logger.info("update_network_policy_protocol_port_ingress returns {} {}".format(returncode, text)) + + def update_network_policy_protocol_port_egress(self, ep, port_networkpolicy_list): + if len(port_networkpolicy_list) == 0: + return + itf = ep.get_veth_peer() + conf_list = [] + for port_networkpolicy in port_networkpolicy_list: + conf = { + "tunnel_id": port_networkpolicy.vni, + "local_ip": port_networkpolicy.local_ip, + "protocol": port_networkpolicy.get_protocol_int(), + "port": port_networkpolicy.port, + "bit_value": str(port_networkpolicy.policy_bit_value), + } + conf_list.append(conf) + jsonconf = json.dumps(conf_list) + cmd = f'''{self.trn_cli_update_network_policy_protocol_port_egress} \'{jsonconf}\' -i \'{itf}\'''' + logger.info("update_network_policy_protocol_port_egress: {}".format(cmd)) + returncode, text = run_cmd(cmd) + logger.info("update_network_policy_protocol_port_egress returns {} {}".format(returncode, text)) + + def delete_network_policy_protocol_port_ingress(self, port_networkpolicy_list): + if len(port_networkpolicy_list) == 0: + return + conf_list = [] + for port_networkpolicy in port_networkpolicy_list: + conf = { + "tunnel_id": port_networkpolicy.vni, + "local_ip": port_networkpolicy.local_ip, + "protocol": port_networkpolicy.get_protocol_int(), + "port": port_networkpolicy.port, + "bit_value": str(port_networkpolicy.policy_bit_value), + } + conf_list.append(conf) + jsonconf = json.dumps(conf_list) + cmd = f'''{self.trn_cli_delete_network_policy_protocol_port_ingress} \'{jsonconf}\'''' + logger.info("delete_network_policy_protocol_port_ingress: {}".format(cmd)) + returncode, text = run_cmd(cmd) + logger.info("delete_network_policy_protocol_port_ingress returns {} {}".format(returncode, text)) + + def delete_network_policy_protocol_port_egress(self, ep, port_networkpolicy_list): + if len(port_networkpolicy_list) == 0: + return + itf = ep.get_veth_peer() + conf_list = [] + for port_networkpolicy in port_networkpolicy_list: + conf = { + "tunnel_id": port_networkpolicy.vni, + "local_ip": port_networkpolicy.local_ip, + "protocol": port_networkpolicy.get_protocol_int(), + "port": port_networkpolicy.port, + "bit_value": str(port_networkpolicy.policy_bit_value), + } + conf_list.append(conf) + jsonconf = json.dumps(conf_list) + cmd = f'''{self.trn_cli_delete_network_policy_protocol_port_egress} \'{jsonconf}\' -i \'{itf}\'''' + logger.info("delete_network_policy_protocol_port_egress: {}".format(cmd)) + returncode, text = run_cmd(cmd) + logger.info("delete_network_policy_protocol_port_egress returns {} {}".format(returncode, text)) + + def update_network_policy_enforcement_map_ingress(self, endpointEnforced): + jsonconf = { + "tunnel_id": endpointEnforced.vni, + "ip": endpointEnforced.ip, + } + jsonconf = json.dumps(jsonconf) + cmd = f'''{self.trn_cli_update_network_policy_enforcement_map_ingress} \'{jsonconf}\'''' + logger.info("update_network_policy_enforcement_map_ingress: {}".format(cmd)) + returncode, text = run_cmd(cmd) + logger.info("update_network_policy_enforcement_map_ingress returns {} {}".format(returncode, text)) + + def update_network_policy_enforcement_map_egress(self, endpointEnforced): + jsonconf = { + "tunnel_id": endpointEnforced.vni, + "ip": endpointEnforced.ip, + } + jsonconf = json.dumps(jsonconf) + cmd = f'''{self.trn_cli_update_network_policy_enforcement_map_egress} \'{jsonconf}\'''' + logger.info("update_network_policy_enforcement_map_egress: {}".format(cmd)) + returncode, text = run_cmd(cmd) + logger.info("update_network_policy_enforcement_map_egress returns {} {}".format(returncode, text)) + + def delete_network_policy_enforcement_map_ingress(self, endpointEnforced): + jsonconf = { + "tunnel_id": endpointEnforced.vni, + "ip": endpointEnforced.ip, + } + jsonconf = json.dumps(jsonconf) + cmd = f'''{self.trn_cli_delete_network_policy_enforcement_map_ingress} \'{jsonconf}\'''' + logger.info("delete_network_policy_enforcement_map_ingress: {}".format(cmd)) + returncode, text = run_cmd(cmd) + logger.info("delete_network_policy_enforcement_map_ingress returns {} {}".format(returncode, text)) + + def delete_network_policy_enforcement_map_egress(self, endpointEnforced): + jsonconf = { + "tunnel_id": endpointEnforced.vni, + "ip": endpointEnforced.ip, + } + jsonconf = json.dumps(jsonconf) + cmd = f'''{self.trn_cli_delete_network_policy_enforcement_map_egress} \'{jsonconf}\'''' + logger.info("delete_network_policy_enforcement_map_egress: {}".format(cmd)) + returncode, text = run_cmd(cmd) + logger.info("delete_network_policy_enforcement_map_egress returns {} {}".format(returncode, text)) diff --git a/mizar/networkpolicy/networkpolicy_util.py b/mizar/networkpolicy/networkpolicy_util.py index 41e6e34f..619e19b5 100644 --- a/mizar/networkpolicy/networkpolicy_util.py +++ b/mizar/networkpolicy/networkpolicy_util.py @@ -59,7 +59,16 @@ def handle_networkpolicy_create_update(self, name, pod_label_dict, policy_types) "egress": data_for_networkpolicy_egress, } logger.info("data_for_networkpolicy: {}".format(data_for_networkpolicy)) - #TODO Send data from operator to daemon + old_data_for_networkpolicy = ep.get_data_for_networkpolicy() + if len(old_data_for_networkpolicy) > 0: + if len(old_data_for_networkpolicy["old"]) > 0 and old_data_for_networkpolicy["old"]["ingress"] == data_for_networkpolicy_ingress and old_data_for_networkpolicy["old"]["egress"] == data_for_networkpolicy_egress: + continue + + old_data_for_networkpolicy["old"] = {} + data_for_networkpolicy["old"] = old_data_for_networkpolicy + + ep.set_data_for_networkpolicy(data_for_networkpolicy) + ep.update_networkpolicy_per_endpoint(data_for_networkpolicy) def generate_data_for_networkpolicy_ingress(self, ep): data = self.init_data_for_networkpolicy() diff --git a/mizar/obj/endpoint.py b/mizar/obj/endpoint.py index 887653b6..77263840 100644 --- a/mizar/obj/endpoint.py +++ b/mizar/obj/endpoint.py @@ -24,6 +24,7 @@ from mizar.common.rpc import TrnRpc from mizar.common.constants import * from mizar.common.common import * +from mizar.obj.data_networkpolicy import * logger = logging.getLogger() @@ -334,25 +335,35 @@ def get_egress_networkpolicies(self): def add_ingress_networkpolicy(self, ingress_networkpolicy_name): self.ingress_networkpolicies.append(ingress_networkpolicy_name) self.ingress_networkpolicies.sort() - #TODO update networkpolicy enforcement map ingress + if len(self.ingress_networkpolicies) == 1: + self.update_network_policy_enforcement_map_ingress() self.store_update_obj() def add_egress_networkpolicy(self, egress_networkpolicy_name): self.egress_networkpolicies.append(egress_networkpolicy_name) self.egress_networkpolicies.sort() - #TODO update networkpolicy enforcement map egress + if len(self.egress_networkpolicies) == 1: + self.update_network_policy_enforcement_map_egress() self.store_update_obj() def remove_ingress_networkpolicy(self, ingress_networkpolicy_name): self.ingress_networkpolicies.remove(ingress_networkpolicy_name) - #TODO delete networkpolicy enforcement map ingress + if len(self.ingress_networkpolicies) == 0: + self.delete_network_policy_enforcement_map_ingress() self.store_update_obj() def remove_egress_networkpolicy(self, egress_networkpolicy_name): self.egress_networkpolicies.remove(egress_networkpolicy_name) - #TODO delete networkpolicy enforcement map egress + if len(self.egress_networkpolicies) == 0: + self.delete_network_policy_enforcement_map_egress() self.store_update_obj() + def get_data_for_networkpolicy(self): + return self.data_for_networkpolicy + + def set_data_for_networkpolicy(self, data_for_networkpolicy): + self.data_for_networkpolicy = data_for_networkpolicy + def load_transit_agent(self): self.rpc.load_transit_agent_xdp(self.veth_peer) @@ -364,3 +375,109 @@ def update_agent_substrate(self, ep, bouncer): def delete_agent_substrate(self, ep, bouncer): self.rpc.delete_agent_substrate_ep(ep, bouncer.ip) + + def update_networkpolicy_per_endpoint(self, data): + if len(data["old"]) > 0: + self.delete_network_policy_ingress("no_except", data["old"]["ingress"]["cidr_table_no_except"]) + self.delete_network_policy_ingress("with_except", data["old"]["ingress"]["cidr_table_with_except"]) + self.delete_network_policy_ingress("except", data["old"]["ingress"]["cidr_table_except"]) + self.delete_network_policy_egress("no_except", data["old"]["egress"]["cidr_table_no_except"]) + self.delete_network_policy_egress("with_except", data["old"]["egress"]["cidr_table_with_except"]) + self.delete_network_policy_egress("except", data["old"]["egress"]["cidr_table_except"]) + + self.delete_network_policy_protocol_port_ingress(data["old"]["ingress"]["port_table"]) + self.delete_network_policy_protocol_port_egress(data["old"]["egress"]["port_table"]) + + self.update_network_policy_ingress("no_except", data["ingress"]["cidr_table_no_except"]) + self.update_network_policy_ingress("with_except", data["ingress"]["cidr_table_with_except"]) + self.update_network_policy_ingress("except", data["ingress"]["cidr_table_except"]) + self.update_network_policy_egress("no_except", data["egress"]["cidr_table_no_except"]) + self.update_network_policy_egress("with_except", data["egress"]["cidr_table_with_except"]) + self.update_network_policy_egress("except", data["egress"]["cidr_table_except"]) + + self.update_network_policy_protocol_port_ingress(data["ingress"]["port_table"]) + self.update_network_policy_protocol_port_egress(data["egress"]["port_table"]) + + def update_network_policy_ingress(self, cidr_type, cidr_table): + cidr_networkpolicy_list = [] + for item in cidr_table: + cidr_networkpolicy = CidrNetworkPolicy( + item["vni"], item["local_ip"], item["cidr"], item["cidr_length"], item["bit_value"], + cidr_type) + cidr_networkpolicy_list.append(cidr_networkpolicy) + self.rpc.update_network_policy_ingress(cidr_networkpolicy_list) + + def update_network_policy_egress(self, cidr_type, cidr_table): + cidr_networkpolicy_list = [] + for item in cidr_table: + cidr_networkpolicy = CidrNetworkPolicy( + item["vni"], item["local_ip"], item["cidr"], item["cidr_length"], item["bit_value"], + cidr_type) + cidr_networkpolicy_list.append(cidr_networkpolicy) + self.rpc.update_network_policy_egress(self, cidr_networkpolicy_list) + + def update_network_policy_protocol_port_ingress(self, port_table): + cidr_networkpolicy_list = [] + for item in port_table: + cidr_networkpolicy = PortNetworkPolicy( + item["vni"], item["local_ip"], item["protocol"], item["port"], item["bit_value"]) + cidr_networkpolicy_list.append(cidr_networkpolicy) + self.rpc.update_network_policy_protocol_port_ingress(cidr_networkpolicy_list) + + def update_network_policy_protocol_port_egress(self, port_table): + cidr_networkpolicy_list = [] + for item in port_table: + cidr_networkpolicy = PortNetworkPolicy( + item["vni"], item["local_ip"], item["protocol"], item["port"], item["bit_value"]) + cidr_networkpolicy_list.append(cidr_networkpolicy) + self.rpc.update_network_policy_protocol_port_egress(self, cidr_networkpolicy_list) + + def delete_network_policy_ingress(self, cidr_type, cidr_table): + cidr_networkpolicy_list = [] + for item in cidr_table: + cidr_networkpolicy = CidrNetworkPolicy( + item["vni"], item["local_ip"], item["cidr"], item["cidr_length"], item["bit_value"], + cidr_type) + cidr_networkpolicy_list.append(cidr_networkpolicy) + self.rpc.delete_network_policy_ingress(cidr_networkpolicy_list) + + def delete_network_policy_egress(self, cidr_type, cidr_table): + cidr_networkpolicy_list = [] + for item in cidr_table: + cidr_networkpolicy = CidrNetworkPolicy( + item["vni"], item["local_ip"], item["cidr"], item["cidr_length"], item["bit_value"], + cidr_type) + cidr_networkpolicy_list.append(cidr_networkpolicy) + self.rpc.delete_network_policy_egress(self, cidr_networkpolicy_list) + + def delete_network_policy_protocol_port_ingress(self, port_table): + cidr_networkpolicy_list = [] + for item in port_table: + cidr_networkpolicy = PortNetworkPolicy( + item["vni"], item["local_ip"], item["protocol"], item["port"], item["bit_value"]) + cidr_networkpolicy_list.append(cidr_networkpolicy) + self.rpc.delete_network_policy_protocol_port_ingress(cidr_networkpolicy_list) + + def delete_network_policy_protocol_port_egress(self, port_table): + cidr_networkpolicy_list = [] + for item in port_table: + cidr_networkpolicy = PortNetworkPolicy( + item["vni"], item["local_ip"], item["protocol"], item["port"], item["bit_value"]) + cidr_networkpolicy_list.append(cidr_networkpolicy) + self.rpc.delete_network_policy_protocol_port_egress(self, cidr_networkpolicy_list) + + def update_network_policy_enforcement_map_ingress(self): + endpointEnforced = EndpointEnforced(self.vni, self.ip) + self.rpc.update_network_policy_enforcement_map_ingress(endpointEnforced) + + def update_network_policy_enforcement_map_egress(self): + endpointEnforced = EndpointEnforced(self.vni, self.ip) + self.rpc.update_network_policy_enforcement_map_egress(endpointEnforced) + + def delete_network_policy_enforcement_map_ingress(self): + endpointEnforced = EndpointEnforced(self.vni, self.ip) + self.rpc.delete_network_policy_enforcement_map_ingress(endpointEnforced) + + def delete_network_policy_enforcement_map_egress(self): + endpointEnforced = EndpointEnforced(self.vni, self.ip) + self.rpc.delete_network_policy_enforcement_map_egress(endpointEnforced)