)]}'
{"neutron/agent/l3/router_info.py":[{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"15aace4c23b746cbcf38fa2e16573dd3473f37c0","unresolved":false,"context_lines":[{"line_number":197,"context_line":"    def _set_arp_proxy(self, port, operation):"},{"line_number":198,"context_line":"        if \u0027id\u0027 in port:"},{"line_number":199,"context_line":"            id \u003d port[\u0027id\u0027]"},{"line_number":200,"context_line":"            qr_name \u003d \u0027qr-\u0027 + id[:11]"},{"line_number":201,"context_line":"            ip_wrapper \u003d ip_lib.IPWrapper(namespace\u003dself.ns_name)"},{"line_number":202,"context_line":"            cmd \u003d [\u0027sysctl\u0027, \u0027-w\u0027, \u0027net.ipv4.conf.%s.proxy_arp\u003d%d\u0027 % (qr_name, operation)]"},{"line_number":203,"context_line":"            ip_wrapper.netns.execute(cmd, check_exit_code\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_a2320df0","line":200,"range":{"start_line":200,"start_character":34,"end_line":200,"end_character":36},"updated":"2020-07-29 07:44:49.000000000","message":"please avoid magic numbers","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"53be8e656d5de533cff34d7f931851c89a6844cc","unresolved":false,"context_lines":[{"line_number":199,"context_line":"            id \u003d port[\u0027id\u0027]"},{"line_number":200,"context_line":"            qr_name \u003d \u0027qr-\u0027 + id[:11]"},{"line_number":201,"context_line":"            ip_wrapper \u003d ip_lib.IPWrapper(namespace\u003dself.ns_name)"},{"line_number":202,"context_line":"            cmd \u003d [\u0027sysctl\u0027, \u0027-w\u0027, \u0027net.ipv4.conf.%s.proxy_arp\u003d%d\u0027 % (qr_name, operation)]"},{"line_number":203,"context_line":"            ip_wrapper.netns.execute(cmd, check_exit_code\u003dFalse)"},{"line_number":204,"context_line":"            cmd \u003d [\u0027sysctl\u0027, \u0027-w\u0027, \u0027net.ipv4.conf.%s.proxy_arp_pvlan\u003d%d\u0027 % (qr_name, operation)]"},{"line_number":205,"context_line":"            ip_wrapper.netns.execute(cmd, check_exit_code\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_676647f0","line":202,"updated":"2020-07-29 04:34:24.000000000","message":"pep8: E501 line too long (90 \u003e 79 characters)","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"53be8e656d5de533cff34d7f931851c89a6844cc","unresolved":false,"context_lines":[{"line_number":201,"context_line":"            ip_wrapper \u003d ip_lib.IPWrapper(namespace\u003dself.ns_name)"},{"line_number":202,"context_line":"            cmd \u003d [\u0027sysctl\u0027, \u0027-w\u0027, \u0027net.ipv4.conf.%s.proxy_arp\u003d%d\u0027 % (qr_name, operation)]"},{"line_number":203,"context_line":"            ip_wrapper.netns.execute(cmd, check_exit_code\u003dFalse)"},{"line_number":204,"context_line":"            cmd \u003d [\u0027sysctl\u0027, \u0027-w\u0027, \u0027net.ipv4.conf.%s.proxy_arp_pvlan\u003d%d\u0027 % (qr_name, operation)]"},{"line_number":205,"context_line":"            ip_wrapper.netns.execute(cmd, check_exit_code\u003dFalse)"},{"line_number":206,"context_line":"            LOG.debug(\u0027setting arp proxy, cmd:%s\u0027, cmd)"},{"line_number":207,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_c763d3db","line":204,"updated":"2020-07-29 04:34:24.000000000","message":"pep8: E501 line too long (96 \u003e 79 characters)","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"15aace4c23b746cbcf38fa2e16573dd3473f37c0","unresolved":false,"context_lines":[{"line_number":203,"context_line":"            ip_wrapper.netns.execute(cmd, check_exit_code\u003dFalse)"},{"line_number":204,"context_line":"            cmd \u003d [\u0027sysctl\u0027, \u0027-w\u0027, \u0027net.ipv4.conf.%s.proxy_arp_pvlan\u003d%d\u0027 % (qr_name, operation)]"},{"line_number":205,"context_line":"            ip_wrapper.netns.execute(cmd, check_exit_code\u003dFalse)"},{"line_number":206,"context_line":"            LOG.debug(\u0027setting arp proxy, cmd:%s\u0027, cmd)"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"    def set_arp_proxy_for_ecmp(self, destination, operation):"},{"line_number":209,"context_line":"        # operation \u003d 1 : open arp proxy"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_a247ad4b","line":206,"range":{"start_line":206,"start_character":12,"end_line":206,"end_character":55},"updated":"2020-07-29 07:44:49.000000000","message":"should this be logged before actual setting?","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"53be8e656d5de533cff34d7f931851c89a6844cc","unresolved":false,"context_lines":[{"line_number":219,"context_line":"                        self._set_arp_proxy(port, operation)"},{"line_number":220,"context_line":""},{"line_number":221,"context_line":""},{"line_number":222,"context_line":"    def is_remove_route_ecmp(self, old_routes, remove_route):"},{"line_number":223,"context_line":"        route_list \u003d []"},{"line_number":224,"context_line":"        LOG.debug(\u0027old_routes: %s\u0027,old_routes)"},{"line_number":225,"context_line":"        for route in old_routes:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_a7605fd0","line":222,"updated":"2020-07-29 04:34:24.000000000","message":"pep8: E303 too many blank lines (2)","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"53be8e656d5de533cff34d7f931851c89a6844cc","unresolved":false,"context_lines":[{"line_number":221,"context_line":""},{"line_number":222,"context_line":"    def is_remove_route_ecmp(self, old_routes, remove_route):"},{"line_number":223,"context_line":"        route_list \u003d []"},{"line_number":224,"context_line":"        LOG.debug(\u0027old_routes: %s\u0027,old_routes)"},{"line_number":225,"context_line":"        for route in old_routes:"},{"line_number":226,"context_line":"            if route[\u0027destination\u0027] \u003d\u003d remove_route[\u0027destination\u0027]:"},{"line_number":227,"context_line":"                route_list.append(route)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_079b0bc9","line":224,"updated":"2020-07-29 04:34:24.000000000","message":"pep8: E231 missing whitespace after \u0027,\u0027","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"15aace4c23b746cbcf38fa2e16573dd3473f37c0","unresolved":false,"context_lines":[{"line_number":225,"context_line":"        for route in old_routes:"},{"line_number":226,"context_line":"            if route[\u0027destination\u0027] \u003d\u003d remove_route[\u0027destination\u0027]:"},{"line_number":227,"context_line":"                route_list.append(route)"},{"line_number":228,"context_line":"        LOG.debug(\u0027route_list: %s\u0027, route_list)"},{"line_number":229,"context_line":"        if len(route_list) \u003d\u003d 0:"},{"line_number":230,"context_line":"            return False"},{"line_number":231,"context_line":"        if len(route_list) \u003d\u003d 1:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_62f595cb","line":228,"range":{"start_line":228,"start_character":18,"end_line":228,"end_character":34},"updated":"2020-07-29 07:44:49.000000000","message":"please make log messages more meaningful","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"15aace4c23b746cbcf38fa2e16573dd3473f37c0","unresolved":false,"context_lines":[{"line_number":226,"context_line":"            if route[\u0027destination\u0027] \u003d\u003d remove_route[\u0027destination\u0027]:"},{"line_number":227,"context_line":"                route_list.append(route)"},{"line_number":228,"context_line":"        LOG.debug(\u0027route_list: %s\u0027, route_list)"},{"line_number":229,"context_line":"        if len(route_list) \u003d\u003d 0:"},{"line_number":230,"context_line":"            return False"},{"line_number":231,"context_line":"        if len(route_list) \u003d\u003d 1:"},{"line_number":232,"context_line":"            return False"},{"line_number":233,"context_line":"        if len(route_list) \u003d\u003d 2:"},{"line_number":234,"context_line":"            for r in route_list:"},{"line_number":235,"context_line":"                if r[\u0027nexthop\u0027] !\u003d remove_route[\u0027nexthop\u0027]:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_c21c616c","line":232,"range":{"start_line":229,"start_character":8,"end_line":232,"end_character":24},"updated":"2020-07-29 07:44:49.000000000","message":"just return False after #242","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"15aace4c23b746cbcf38fa2e16573dd3473f37c0","unresolved":false,"context_lines":[{"line_number":248,"context_line":"            if route[\u0027destination\u0027] \u003d\u003d new_route[\u0027destination\u0027]:"},{"line_number":249,"context_line":"                route_list.append(route)"},{"line_number":250,"context_line":"        LOG.debug(\u0027route_list: %s\u0027, route_list)"},{"line_number":251,"context_line":"        if len(route_list) \u003d\u003d 0:"},{"line_number":252,"context_line":"            return False"},{"line_number":253,"context_line":"        if len(route_list) \u003e\u003d 1:"},{"line_number":254,"context_line":"            route_list.append(new_route)"},{"line_number":255,"context_line":"            self.update_routing_table_ecmp(\u0027replace\u0027, route_list)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_22d1dd55","line":252,"range":{"start_line":251,"start_character":8,"end_line":252,"end_character":24},"updated":"2020-07-29 07:44:49.000000000","message":"just return False in the end","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"15aace4c23b746cbcf38fa2e16573dd3473f37c0","unresolved":false,"context_lines":[{"line_number":250,"context_line":"        LOG.debug(\u0027route_list: %s\u0027, route_list)"},{"line_number":251,"context_line":"        if len(route_list) \u003d\u003d 0:"},{"line_number":252,"context_line":"            return False"},{"line_number":253,"context_line":"        if len(route_list) \u003e\u003d 1:"},{"line_number":254,"context_line":"            route_list.append(new_route)"},{"line_number":255,"context_line":"            self.update_routing_table_ecmp(\u0027replace\u0027, route_list)"},{"line_number":256,"context_line":"            self.set_arp_proxy_for_ecmp(new_route[\u0027destination\u0027], 1)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_62c2b587","line":253,"range":{"start_line":253,"start_character":8,"end_line":253,"end_character":31},"updated":"2020-07-29 07:44:49.000000000","message":"if route_list:","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"15aace4c23b746cbcf38fa2e16573dd3473f37c0","unresolved":false,"context_lines":[{"line_number":259,"context_line":"    def routes_updated(self, old_routes, new_routes):"},{"line_number":260,"context_line":"        adds, removes \u003d helpers.diff_list_of_dict(old_routes,"},{"line_number":261,"context_line":"                                                  new_routes)"},{"line_number":262,"context_line":"        LOG.debug(\"ALL OLD ROUTES:%s\", old_routes)"},{"line_number":263,"context_line":"        for route in removes:"},{"line_number":264,"context_line":"            # judge is modifying an ECMP route or not"},{"line_number":265,"context_line":"            # if not, just delete it"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_87243bc8","line":262,"range":{"start_line":262,"start_character":19,"end_line":262,"end_character":33},"updated":"2020-07-29 07:44:49.000000000","message":"why all CAPS? Would it be useful to log new routes as well?","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"15aace4c23b746cbcf38fa2e16573dd3473f37c0","unresolved":false,"context_lines":[{"line_number":261,"context_line":"                                                  new_routes)"},{"line_number":262,"context_line":"        LOG.debug(\"ALL OLD ROUTES:%s\", old_routes)"},{"line_number":263,"context_line":"        for route in removes:"},{"line_number":264,"context_line":"            # judge is modifying an ECMP route or not"},{"line_number":265,"context_line":"            # if not, just delete it"},{"line_number":266,"context_line":"            # if it is, replace it"},{"line_number":267,"context_line":"            # update old_routes after modify"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_2740cf56","line":264,"range":{"start_line":264,"start_character":20,"end_line":264,"end_character":22},"updated":"2020-07-29 07:44:49.000000000","message":"if?","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"15aace4c23b746cbcf38fa2e16573dd3473f37c0","unresolved":false,"context_lines":[{"line_number":266,"context_line":"            # if it is, replace it"},{"line_number":267,"context_line":"            # update old_routes after modify"},{"line_number":268,"context_line":"            if self.is_remove_route_ecmp(old_routes, route):"},{"line_number":269,"context_line":"                LOG.debug(\"Removed an ECMP route\")"},{"line_number":270,"context_line":"                old_routes.remove(route)"},{"line_number":271,"context_line":"                continue"},{"line_number":272,"context_line":"            LOG.debug(\"Removed route entry is \u0027%s\u0027\", route)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_02d2d95c","line":269,"range":{"start_line":269,"start_character":26,"end_line":269,"end_character":50},"updated":"2020-07-29 07:44:49.000000000","message":"may log exact route as well","commit_id":"f0fd70db8d596342a87cae3bec42cab8a815337e"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"b24fd52da65e31a834ed11fbf5c9d31229a866af","unresolved":false,"context_lines":[{"line_number":199,"context_line":""},{"line_number":200,"context_line":"    def _set_arp_proxy(self, port, operation):"},{"line_number":201,"context_line":"        if \u0027id\u0027 in port:"},{"line_number":202,"context_line":"            port_id \u003d port[\u0027id\u0027]"},{"line_number":203,"context_line":"            qr_name \u003d \u0027qr-\u0027 + port_id[:ROUTER_PORT_NAME_OFFSET]"},{"line_number":204,"context_line":"            LOG.debug(\u0027Setting ARP proxy on %s\u0027, qr_name)"},{"line_number":205,"context_line":"            ip_wrapper \u003d ip_lib.IPWrapper(namespace\u003dself.ns_name)"},{"line_number":206,"context_line":"            cmd \u003d [\u0027sysctl\u0027, \u0027-w\u0027, \u0027net.ipv4.conf.%s.proxy_arp\u003d%d\u0027 %"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f560f44_70391bf0","line":203,"range":{"start_line":202,"start_character":12,"end_line":203,"end_character":63},"updated":"2020-08-11 06:30:21.000000000","message":"Please use `get_internal_device_name` intead of this.","commit_id":"fc0190075b7ff2dc5a79b1c236f66ccfc85a5518"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"1816c80507aa61ceef7ac8804d69f713f0612bb0","unresolved":false,"context_lines":[{"line_number":199,"context_line":""},{"line_number":200,"context_line":"    def _set_arp_proxy(self, port, operation):"},{"line_number":201,"context_line":"        if \u0027id\u0027 in port:"},{"line_number":202,"context_line":"            port_id \u003d port[\u0027id\u0027]"},{"line_number":203,"context_line":"            qr_name \u003d \u0027qr-\u0027 + port_id[:ROUTER_PORT_NAME_OFFSET]"},{"line_number":204,"context_line":"            LOG.debug(\u0027Setting ARP proxy on %s\u0027, qr_name)"},{"line_number":205,"context_line":"            ip_wrapper \u003d ip_lib.IPWrapper(namespace\u003dself.ns_name)"},{"line_number":206,"context_line":"            cmd \u003d [\u0027sysctl\u0027, \u0027-w\u0027, \u0027net.ipv4.conf.%s.proxy_arp\u003d%d\u0027 %"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f560f44_eb0c0296","line":203,"range":{"start_line":202,"start_character":12,"end_line":203,"end_character":63},"in_reply_to":"9f560f44_70391bf0","updated":"2020-08-13 01:58:01.000000000","message":"Done","commit_id":"fc0190075b7ff2dc5a79b1c236f66ccfc85a5518"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"b24fd52da65e31a834ed11fbf5c9d31229a866af","unresolved":false,"context_lines":[{"line_number":213,"context_line":"    def set_arp_proxy_for_ecmp(self, destination, operation):"},{"line_number":214,"context_line":"        ports \u003d self.internal_ports"},{"line_number":215,"context_line":"        dst_ip \u003d netaddr.IPNetwork(destination)"},{"line_number":216,"context_line":"        for port in ports:"},{"line_number":217,"context_line":"            if \u0027subnets\u0027 in port:"},{"line_number":218,"context_line":"                for subnet in port[\u0027subnets\u0027]:"},{"line_number":219,"context_line":"                    port_subnet \u003d [subnet[\u0027cidr\u0027]]"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f560f44_301cc376","line":216,"range":{"start_line":216,"start_character":20,"end_line":216,"end_character":25},"updated":"2020-08-11 06:30:21.000000000","message":"you could direct use the self.internal_ports","commit_id":"fc0190075b7ff2dc5a79b1c236f66ccfc85a5518"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"1816c80507aa61ceef7ac8804d69f713f0612bb0","unresolved":false,"context_lines":[{"line_number":213,"context_line":"    def set_arp_proxy_for_ecmp(self, destination, operation):"},{"line_number":214,"context_line":"        ports \u003d self.internal_ports"},{"line_number":215,"context_line":"        dst_ip \u003d netaddr.IPNetwork(destination)"},{"line_number":216,"context_line":"        for port in ports:"},{"line_number":217,"context_line":"            if \u0027subnets\u0027 in port:"},{"line_number":218,"context_line":"                for subnet in port[\u0027subnets\u0027]:"},{"line_number":219,"context_line":"                    port_subnet \u003d [subnet[\u0027cidr\u0027]]"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f560f44_cb113eaf","line":216,"range":{"start_line":216,"start_character":20,"end_line":216,"end_character":25},"in_reply_to":"9f560f44_301cc376","updated":"2020-08-13 01:58:01.000000000","message":"Done","commit_id":"fc0190075b7ff2dc5a79b1c236f66ccfc85a5518"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"b24fd52da65e31a834ed11fbf5c9d31229a866af","unresolved":false,"context_lines":[{"line_number":227,"context_line":"            if route[\u0027destination\u0027] \u003d\u003d remove_route[\u0027destination\u0027]:"},{"line_number":228,"context_line":"                route_list.append(route)"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"        if len(route_list) \u003d\u003d 2:"},{"line_number":231,"context_line":"            for r in route_list:"},{"line_number":232,"context_line":"                if r[\u0027nexthop\u0027] !\u003d remove_route[\u0027nexthop\u0027]:"},{"line_number":233,"context_line":"                    self.update_routing_table(\u0027replace\u0027, r)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f560f44_5015f747","line":230,"range":{"start_line":230,"start_character":30,"end_line":230,"end_character":31},"updated":"2020-08-11 06:30:21.000000000","message":"I\u0027m confused why this number 2 can be used to determine the route actions.","commit_id":"fc0190075b7ff2dc5a79b1c236f66ccfc85a5518"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"63e09ac84113a4f4e77fcecc2579e7209239bf64","unresolved":false,"context_lines":[{"line_number":227,"context_line":"            if route[\u0027destination\u0027] \u003d\u003d remove_route[\u0027destination\u0027]:"},{"line_number":228,"context_line":"                route_list.append(route)"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"        if len(route_list) \u003d\u003d 2:"},{"line_number":231,"context_line":"            for r in route_list:"},{"line_number":232,"context_line":"                if r[\u0027nexthop\u0027] !\u003d remove_route[\u0027nexthop\u0027]:"},{"line_number":233,"context_line":"                    self.update_routing_table(\u0027replace\u0027, r)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f560f44_2b9d76bb","line":230,"range":{"start_line":230,"start_character":30,"end_line":230,"end_character":31},"in_reply_to":"9f560f44_5015f747","updated":"2020-08-11 06:47:19.000000000","message":"+1, would be good to have a comment here","commit_id":"fc0190075b7ff2dc5a79b1c236f66ccfc85a5518"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"1816c80507aa61ceef7ac8804d69f713f0612bb0","unresolved":false,"context_lines":[{"line_number":227,"context_line":"            if route[\u0027destination\u0027] \u003d\u003d remove_route[\u0027destination\u0027]:"},{"line_number":228,"context_line":"                route_list.append(route)"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"        if len(route_list) \u003d\u003d 2:"},{"line_number":231,"context_line":"            for r in route_list:"},{"line_number":232,"context_line":"                if r[\u0027nexthop\u0027] !\u003d remove_route[\u0027nexthop\u0027]:"},{"line_number":233,"context_line":"                    self.update_routing_table(\u0027replace\u0027, r)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f560f44_0b233607","line":230,"range":{"start_line":230,"start_character":30,"end_line":230,"end_character":31},"in_reply_to":"9f560f44_5015f747","updated":"2020-08-13 01:58:01.000000000","message":"Done","commit_id":"fc0190075b7ff2dc5a79b1c236f66ccfc85a5518"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"951d4bc74848f28679fc4deb2203d087ad53faff","unresolved":false,"context_lines":[{"line_number":187,"context_line":"        self._update_routing_table(operation, route, self.ns_name)"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"    def update_routing_table_ecmp(self, operation, route_list):"},{"line_number":190,"context_line":"        cmd \u003d [\u0027ip\u0027, \u0027route\u0027, operation, \u0027to\u0027, route_list[0][\u0027destination\u0027]]"},{"line_number":191,"context_line":"        for route in route_list:"},{"line_number":192,"context_line":"            cmd.append(\u0027nexthop\u0027)"},{"line_number":193,"context_line":"            cmd.append(\u0027via\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f560f44_7939bfa1","line":190,"range":{"start_line":190,"start_character":7,"end_line":190,"end_character":76},"updated":"2020-08-17 13:28:19.000000000","message":"The spec is saying that this will be applied by pyroute2 lib?\nhttps://review.opendev.org/#/c/729532/28/specs/victoria/l3-router-support-ecmp.rst@239","commit_id":"a0ac69600faf65609fd7c2bf2c433542b72d072d"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"fdff8db4fcb2f08dda513f7c82d92af7ab7d7b55","unresolved":false,"context_lines":[{"line_number":187,"context_line":"        self._update_routing_table(operation, route, self.ns_name)"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"    def update_routing_table_ecmp(self, operation, route_list):"},{"line_number":190,"context_line":"        cmd \u003d [\u0027ip\u0027, \u0027route\u0027, operation, \u0027to\u0027, route_list[0][\u0027destination\u0027]]"},{"line_number":191,"context_line":"        for route in route_list:"},{"line_number":192,"context_line":"            cmd.append(\u0027nexthop\u0027)"},{"line_number":193,"context_line":"            cmd.append(\u0027via\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f560f44_2616f6a8","line":190,"range":{"start_line":190,"start_character":7,"end_line":190,"end_character":76},"in_reply_to":"9f560f44_7939bfa1","updated":"2020-08-18 10:27:57.000000000","message":"\u003e The spec is saying that this will be applied by pyroute2 lib?\n`ip_lib.add_ip_route` does not support `multipath` parameter,\nI will just use pyroute2 here directly.","commit_id":"a0ac69600faf65609fd7c2bf2c433542b72d072d"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"194ea989f45969a1d9853c1951fe7b13fcb3ba9a","unresolved":false,"context_lines":[{"line_number":187,"context_line":"        self._update_routing_table(operation, route, self.ns_name)"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"    def update_routing_table_ecmp(self, operation, route_list):"},{"line_number":190,"context_line":"        cmd \u003d [\u0027ip\u0027, \u0027route\u0027, operation, \u0027to\u0027, route_list[0][\u0027destination\u0027]]"},{"line_number":191,"context_line":"        for route in route_list:"},{"line_number":192,"context_line":"            cmd.append(\u0027nexthop\u0027)"},{"line_number":193,"context_line":"            cmd.append(\u0027via\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f560f44_f71b0ec7","line":190,"range":{"start_line":190,"start_character":7,"end_line":190,"end_character":76},"in_reply_to":"9f560f44_7939bfa1","updated":"2020-08-18 03:22:54.000000000","message":"I wrote pyroute2 lib in spec because Slawek said \"we are using pyroute2 now\", but I found that this file is still using ip_lib, (`ip_lib.add_ip_route` use pyroute2 insdie)","commit_id":"a0ac69600faf65609fd7c2bf2c433542b72d072d"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"951d4bc74848f28679fc4deb2203d087ad53faff","unresolved":false,"context_lines":[{"line_number":192,"context_line":"            cmd.append(\u0027nexthop\u0027)"},{"line_number":193,"context_line":"            cmd.append(\u0027via\u0027)"},{"line_number":194,"context_line":"            cmd.append(route[\u0027nexthop\u0027])"},{"line_number":195,"context_line":"        LOG.debug(\u0027ECMP cmd: %s\u0027, cmd)"},{"line_number":196,"context_line":"        ip_wrapper \u003d ip_lib.IPWrapper(namespace\u003dself.ns_name)"},{"line_number":197,"context_line":"        ip_wrapper.netns.execute(cmd, check_exit_code\u003dFalse)"},{"line_number":198,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9f560f44_ee7067dd","line":195,"range":{"start_line":195,"start_character":8,"end_line":195,"end_character":38},"updated":"2020-08-17 13:28:19.000000000","message":"The `execute` method already has a \u0027cmd\u0027 debug log.","commit_id":"a0ac69600faf65609fd7c2bf2c433542b72d072d"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"951d4bc74848f28679fc4deb2203d087ad53faff","unresolved":false,"context_lines":[{"line_number":197,"context_line":"        ip_wrapper.netns.execute(cmd, check_exit_code\u003dFalse)"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"    def _set_arp_proxy(self, port, operation):"},{"line_number":200,"context_line":"        if \u0027id\u0027 in port:"},{"line_number":201,"context_line":"            qr_name \u003d self.get_internal_device_name(port[\u0027id\u0027])"},{"line_number":202,"context_line":"            LOG.debug(\u0027Setting ARP proxy on %s\u0027, qr_name)"},{"line_number":203,"context_line":"            ip_wrapper \u003d ip_lib.IPWrapper(namespace\u003dself.ns_name)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f560f44_eeab471b","line":200,"range":{"start_line":200,"start_character":8,"end_line":200,"end_character":24},"updated":"2020-08-17 13:28:19.000000000","message":"When a port (info) does not contain an ID ? How could it happen?","commit_id":"a0ac69600faf65609fd7c2bf2c433542b72d072d"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"951d4bc74848f28679fc4deb2203d087ad53faff","unresolved":false,"context_lines":[{"line_number":211,"context_line":"    def set_arp_proxy_for_ecmp(self, destination, operation):"},{"line_number":212,"context_line":"        dst_ip \u003d netaddr.IPNetwork(destination)"},{"line_number":213,"context_line":"        for port in self.internal_ports:"},{"line_number":214,"context_line":"            if \u0027subnets\u0027 in port:"},{"line_number":215,"context_line":"                for subnet in port[\u0027subnets\u0027]:"},{"line_number":216,"context_line":"                    port_subnet \u003d [subnet[\u0027cidr\u0027]]"},{"line_number":217,"context_line":"                    ip_set \u003d netaddr.IPSet(port_subnet)"},{"line_number":218,"context_line":"                    if dst_ip in ip_set:"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f560f44_4e2eb3a5","line":215,"range":{"start_line":214,"start_character":12,"end_line":215,"end_character":46},"updated":"2020-08-17 13:28:19.000000000","message":"`subnets` should be a fixed attribute of the port.","commit_id":"a0ac69600faf65609fd7c2bf2c433542b72d072d"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"951d4bc74848f28679fc4deb2203d087ad53faff","unresolved":false,"context_lines":[{"line_number":215,"context_line":"                for subnet in port[\u0027subnets\u0027]:"},{"line_number":216,"context_line":"                    port_subnet \u003d [subnet[\u0027cidr\u0027]]"},{"line_number":217,"context_line":"                    ip_set \u003d netaddr.IPSet(port_subnet)"},{"line_number":218,"context_line":"                    if dst_ip in ip_set:"},{"line_number":219,"context_line":"                        self._set_arp_proxy(port, operation)"},{"line_number":220,"context_line":""},{"line_number":221,"context_line":"    def is_remove_route_ecmp(self, old_routes, remove_route):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f560f44_19aec3e6","line":218,"range":{"start_line":218,"start_character":20,"end_line":218,"end_character":40},"updated":"2020-08-17 13:28:19.000000000","message":"` destination in netaddr.IPNetwork(subnet[\u0027cidr\u0027]) ` should be enough:\n\n\u003e\u003e\u003e import netaddr\n\u003e\u003e\u003e \"192.168.1.0\" in netaddr.IPNetwork(\u0027192.168.1.0/24\u0027)\nTrue\n\u003e\u003e\u003e \"192.168.2.0\" in netaddr.IPNetwork(\u0027192.168.1.0/24\u0027)\nFalse","commit_id":"a0ac69600faf65609fd7c2bf2c433542b72d072d"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"194ea989f45969a1d9853c1951fe7b13fcb3ba9a","unresolved":false,"context_lines":[{"line_number":215,"context_line":"                for subnet in port[\u0027subnets\u0027]:"},{"line_number":216,"context_line":"                    port_subnet \u003d [subnet[\u0027cidr\u0027]]"},{"line_number":217,"context_line":"                    ip_set \u003d netaddr.IPSet(port_subnet)"},{"line_number":218,"context_line":"                    if dst_ip in ip_set:"},{"line_number":219,"context_line":"                        self._set_arp_proxy(port, operation)"},{"line_number":220,"context_line":""},{"line_number":221,"context_line":"    def is_remove_route_ecmp(self, old_routes, remove_route):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f560f44_578e3a27","line":218,"range":{"start_line":218,"start_character":20,"end_line":218,"end_character":40},"in_reply_to":"9f560f44_19aec3e6","updated":"2020-08-18 03:22:54.000000000","message":"`dstination` has a subnet prefix, like: \u0027192.168.1.1/32\u0027,\n\u003e\u003e\u003e \u0027192.168.0.1/32\u0027 in netaddr.IPNetwork(\u0027192.168.0.0/24\u0027)\nValueError: IPAddress() does not support netmasks or subnet prefixes","commit_id":"a0ac69600faf65609fd7c2bf2c433542b72d072d"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"951d4bc74848f28679fc4deb2203d087ad53faff","unresolved":false,"context_lines":[{"line_number":263,"context_line":"    def routes_updated(self, old_routes, new_routes):"},{"line_number":264,"context_line":"        adds, removes \u003d helpers.diff_list_of_dict(old_routes,"},{"line_number":265,"context_line":"                                                  new_routes)"},{"line_number":266,"context_line":"        for route in removes:"},{"line_number":267,"context_line":"            # Judge if modifying an ECMP route or not, if not,"},{"line_number":268,"context_line":"            # just delete it, if it is, replace it"},{"line_number":269,"context_line":"            # update old_routes after modify"},{"line_number":270,"context_line":"            if not self.is_remove_route_ecmp(old_routes, route):"},{"line_number":271,"context_line":"                LOG.debug(\"Removed route entry is \u0027%s\u0027\", route)"},{"line_number":272,"context_line":"                self.update_routing_table(\u0027delete\u0027, route)"},{"line_number":273,"context_line":"            old_routes.remove(route)"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"        for route in adds:"},{"line_number":276,"context_line":"            if not self.is_add_route_ecmp(old_routes, route):"},{"line_number":277,"context_line":"                LOG.debug(\"Added route entry is \u0027%s\u0027\", route)"},{"line_number":278,"context_line":"                # replace success even if there is no existing route"},{"line_number":279,"context_line":"                self.update_routing_table(\u0027replace\u0027, route)"},{"line_number":280,"context_line":"            old_routes.append(route)"},{"line_number":281,"context_line":""},{"line_number":282,"context_line":"    def get_floating_ips(self):"},{"line_number":283,"context_line":"        \"\"\"Filter Floating IPs to be hosted on this agent.\"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"9f560f44_398c677e","line":280,"range":{"start_line":266,"start_character":0,"end_line":280,"end_character":36},"updated":"2020-08-17 13:28:19.000000000","message":"I\u0027m lost in these refactors, conditions and updatings...","commit_id":"a0ac69600faf65609fd7c2bf2c433542b72d072d"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"194ea989f45969a1d9853c1951fe7b13fcb3ba9a","unresolved":false,"context_lines":[{"line_number":263,"context_line":"    def routes_updated(self, old_routes, new_routes):"},{"line_number":264,"context_line":"        adds, removes \u003d helpers.diff_list_of_dict(old_routes,"},{"line_number":265,"context_line":"                                                  new_routes)"},{"line_number":266,"context_line":"        for route in removes:"},{"line_number":267,"context_line":"            # Judge if modifying an ECMP route or not, if not,"},{"line_number":268,"context_line":"            # just delete it, if it is, replace it"},{"line_number":269,"context_line":"            # update old_routes after modify"},{"line_number":270,"context_line":"            if not self.is_remove_route_ecmp(old_routes, route):"},{"line_number":271,"context_line":"                LOG.debug(\"Removed route entry is \u0027%s\u0027\", route)"},{"line_number":272,"context_line":"                self.update_routing_table(\u0027delete\u0027, route)"},{"line_number":273,"context_line":"            old_routes.remove(route)"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"        for route in adds:"},{"line_number":276,"context_line":"            if not self.is_add_route_ecmp(old_routes, route):"},{"line_number":277,"context_line":"                LOG.debug(\"Added route entry is \u0027%s\u0027\", route)"},{"line_number":278,"context_line":"                # replace success even if there is no existing route"},{"line_number":279,"context_line":"                self.update_routing_table(\u0027replace\u0027, route)"},{"line_number":280,"context_line":"            old_routes.append(route)"},{"line_number":281,"context_line":""},{"line_number":282,"context_line":"    def get_floating_ips(self):"},{"line_number":283,"context_line":"        \"\"\"Filter Floating IPs to be hosted on this agent.\"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"9f560f44_97457273","line":280,"range":{"start_line":266,"start_character":0,"end_line":280,"end_character":36},"in_reply_to":"9f560f44_398c677e","updated":"2020-08-18 03:22:54.000000000","message":"Let me try to explain this:\n1.The original logic was to add fristly and then delete, and for a destination address, if there is an added route, then the route with the same destination address is deleted from the \u0027removes\u0027. We can\u0027t do that now since same dst route is supported, so we need to remove `removes` before adding `adds`.\n2. I need to compare the added route(or delete route) with the existing routes to determine if I need to execute the ECMP route operation function, so I update the old routes for each cycle(Line 273,280).\n3. I determine in the loop whether the modification involves ECMP(Line 270,276), if not, the original logic (Line 272,279) is still executed.","commit_id":"a0ac69600faf65609fd7c2bf2c433542b72d072d"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"eef94848eac8a9f9294a13670150f06254b38157","unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"import netaddr"},{"line_number":19,"context_line":"import pyroute2"},{"line_number":20,"context_line":"from neutron_lib import constants as lib_constants"},{"line_number":21,"context_line":"from neutron_lib.exceptions import l3 as l3_exc"},{"line_number":22,"context_line":"from neutron_lib.utils import helpers"},{"line_number":23,"context_line":"from oslo_log import log as logging"}],"source_content_type":"text/x-python","patch_set":6,"id":"9f560f44_9ba0cbf6","line":20,"updated":"2020-08-20 12:40:52.000000000","message":"pep8: H306: imports not in alphabetical order (pyroute2, neutron_lib.constants)","commit_id":"21154db12afe20ea4ac4d1c96b21ff28fd5e66d2"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"948cfee7faec8f364c1e70fa23c41931cb3c0c87","unresolved":false,"context_lines":[{"line_number":190,"context_line":"        multipath \u003d [dict(gateway\u003droute[\u0027nexthop\u0027])"},{"line_number":191,"context_line":"                     for route in route_list]"},{"line_number":192,"context_line":"        try:"},{"line_number":193,"context_line":"            ip_lib.add_ip_route(self.ns_name, route_list[0][\u0027destination\u0027],"},{"line_number":194,"context_line":"                                multipath\u003dmultipath)"},{"line_number":195,"context_line":"        except (RuntimeError, OSError, pyroute2_exc.NetlinkError):"},{"line_number":196,"context_line":"            pass"},{"line_number":197,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"9f560f44_4932bff3","line":194,"range":{"start_line":193,"start_character":12,"end_line":194,"end_character":52},"updated":"2020-08-24 09:12:13.000000000","message":"Explaination: I modified the `ip_lib.add_ip_route` method to support \u0027multipath\u0027, and add_ip_route will use pyroute2 inside of it.","commit_id":"26dffb7d0d03cd3ed318e42a07185fba19855fb2"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"fffbf1de03315f0006820fe4a11da1d47fd9ec8d","unresolved":true,"context_lines":[{"line_number":42,"context_line":"ADDRESS_SCOPE_MARK_ID_MIN \u003d 1024"},{"line_number":43,"context_line":"ADDRESS_SCOPE_MARK_ID_MAX \u003d 2048"},{"line_number":44,"context_line":"DEFAULT_ADDRESS_SCOPE \u003d \"noscope\""},{"line_number":45,"context_line":"ARP_PROXY_OPEN \u003d 1"},{"line_number":46,"context_line":"ARP_PROXY_OFF \u003d 0"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"class BaseRouterInfo(object, metaclass\u003dabc.ABCMeta):"},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"80ac1f39_bdb5af0a","line":47,"range":{"start_line":45,"start_character":0,"end_line":47,"end_character":0},"updated":"2021-03-15 04:52:28.000000000","message":"Where is the usage of these two constants value?","commit_id":"63e20c75ebfe74e3ec9bf1f865462f9af8c40f34"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"75c9b889ef3c20921d5683b72da0dbadcd9b2031","unresolved":false,"context_lines":[{"line_number":42,"context_line":"ADDRESS_SCOPE_MARK_ID_MIN \u003d 1024"},{"line_number":43,"context_line":"ADDRESS_SCOPE_MARK_ID_MAX \u003d 2048"},{"line_number":44,"context_line":"DEFAULT_ADDRESS_SCOPE \u003d \"noscope\""},{"line_number":45,"context_line":"ARP_PROXY_OPEN \u003d 1"},{"line_number":46,"context_line":"ARP_PROXY_OFF \u003d 0"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"class BaseRouterInfo(object, metaclass\u003dabc.ABCMeta):"},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"ef712919_a5078b69","line":47,"range":{"start_line":45,"start_character":0,"end_line":47,"end_character":0},"in_reply_to":"80ac1f39_bdb5af0a","updated":"2021-03-15 08:18:39.000000000","message":"I will remove this two lines","commit_id":"63e20c75ebfe74e3ec9bf1f865462f9af8c40f34"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"8757a467777ad70d1bab867fd2bdb04e93aaa66f","unresolved":true,"context_lines":[{"line_number":197,"context_line":"        except (RuntimeError, OSError, pyroute2_exc.NetlinkError):"},{"line_number":198,"context_line":"            pass"},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"    def is_remove_route_ecmp(self, old_routes, remove_route):"},{"line_number":201,"context_line":"        route_list \u003d []"},{"line_number":202,"context_line":"        for route in old_routes:"},{"line_number":203,"context_line":"            if route[\u0027destination\u0027] \u003d\u003d remove_route[\u0027destination\u0027]:"}],"source_content_type":"text/x-python","patch_set":13,"id":"c4f31c6c_461d8014","line":200,"updated":"2021-03-22 08:51:30.000000000","message":"This method is not just checking if route is ecmp route or not, but it will also modify routing table in some cases which may be confusing IMO","commit_id":"f23afa42406184b53454979dff565910871b4664"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"0bb0e46c4b49c48b8fa72d2b72c4da91d192fddc","unresolved":true,"context_lines":[{"line_number":197,"context_line":"        except (RuntimeError, OSError, pyroute2_exc.NetlinkError):"},{"line_number":198,"context_line":"            pass"},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"    def is_remove_route_ecmp(self, old_routes, remove_route):"},{"line_number":201,"context_line":"        route_list \u003d []"},{"line_number":202,"context_line":"        for route in old_routes:"},{"line_number":203,"context_line":"            if route[\u0027destination\u0027] \u003d\u003d remove_route[\u0027destination\u0027]:"}],"source_content_type":"text/x-python","patch_set":13,"id":"33c104c9_c10822c2","line":200,"in_reply_to":"c4f31c6c_461d8014","updated":"2021-05-26 10:21:48.000000000","message":"I\u0027ll rename it","commit_id":"f23afa42406184b53454979dff565910871b4664"}],"neutron/agent/linux/ip_lib.py":[{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"8757a467777ad70d1bab867fd2bdb04e93aaa66f","unresolved":true,"context_lines":[{"line_number":1541,"context_line":"        metric \u003d (get_attr(route, \u0027RTA_PRIORITY\u0027) or"},{"line_number":1542,"context_line":"                  IP_ROUTE_METRIC_DEFAULT[ip_version])"},{"line_number":1543,"context_line":"        proto \u003d get_proto(route[\u0027proto\u0027])"},{"line_number":1544,"context_line":"        multi_path \u003d get_attr(route, \u0027RTA_MULTIPATH\u0027)"},{"line_number":1545,"context_line":"        next_hops \u003d None"},{"line_number":1546,"context_line":"        if multi_path:"},{"line_number":1547,"context_line":"            next_hops \u003d [attr[1] for entry in multi_path"}],"source_content_type":"text/x-python","patch_set":13,"id":"da3e305e_bb4a24d8","line":1544,"range":{"start_line":1544,"start_character":8,"end_line":1544,"end_character":18},"updated":"2021-03-22 08:51:30.000000000","message":"nit: why above it\u0027s \"multipath\" and here \"multi_path\"? Maybe better would be to name it here \"rta_multipath\"?","commit_id":"f23afa42406184b53454979dff565910871b4664"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"0bb0e46c4b49c48b8fa72d2b72c4da91d192fddc","unresolved":false,"context_lines":[{"line_number":1541,"context_line":"        metric \u003d (get_attr(route, \u0027RTA_PRIORITY\u0027) or"},{"line_number":1542,"context_line":"                  IP_ROUTE_METRIC_DEFAULT[ip_version])"},{"line_number":1543,"context_line":"        proto \u003d get_proto(route[\u0027proto\u0027])"},{"line_number":1544,"context_line":"        multi_path \u003d get_attr(route, \u0027RTA_MULTIPATH\u0027)"},{"line_number":1545,"context_line":"        next_hops \u003d None"},{"line_number":1546,"context_line":"        if multi_path:"},{"line_number":1547,"context_line":"            next_hops \u003d [attr[1] for entry in multi_path"}],"source_content_type":"text/x-python","patch_set":13,"id":"50cd5b54_0e000822","line":1544,"range":{"start_line":1544,"start_character":8,"end_line":1544,"end_character":18},"in_reply_to":"da3e305e_bb4a24d8","updated":"2021-05-26 10:21:48.000000000","message":"bug #1926476 has fixed the multipath function\nI\u0027ll just remove these modifications","commit_id":"f23afa42406184b53454979dff565910871b4664"}],"neutron/extensions/ecmp_routes.py":[{"author":{"_account_id":8313,"name":"Lajos Katona","display_name":"lajoskatona","email":"katonalala@gmail.com","username":"elajkat","status":"Ericsson Software Technology"},"change_message_id":"478dd3cc0f879f22aa7b8a8ff9f3ff689fe08ae8","unresolved":true,"context_lines":[{"line_number":14,"context_line":"from neutron_lib.api import extensions\r"},{"line_number":15,"context_line":"\r"},{"line_number":16,"context_line":"\r"},{"line_number":17,"context_line":"class Dns_integration_domain_keywords(extensions.APIExtensionDescriptor):\r"},{"line_number":18,"context_line":"    \"\"\"Extension class supporting configuration of dns domain with keywords.\"\"\"\r"},{"line_number":19,"context_line":"\r"},{"line_number":20,"context_line":"    api_definition \u003d apidef\r"}],"source_content_type":"text/x-python","patch_set":21,"id":"cfabf272_3cf5aa66","line":17,"range":{"start_line":17,"start_character":6,"end_line":17,"end_character":37},"updated":"2021-07-05 08:47:23.000000000","message":"I am sure that You need a new classname","commit_id":"3899db0452c0f6976e8a70d2364d7cc871ffbfa5"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"84c3fbfb911ddb4d59a91e4283623e28c1875518","unresolved":true,"context_lines":[{"line_number":14,"context_line":"from neutron_lib.api import extensions\r"},{"line_number":15,"context_line":"\r"},{"line_number":16,"context_line":"\r"},{"line_number":17,"context_line":"class Dns_integration_domain_keywords(extensions.APIExtensionDescriptor):\r"},{"line_number":18,"context_line":"    \"\"\"Extension class supporting configuration of dns domain with keywords.\"\"\"\r"},{"line_number":19,"context_line":"\r"},{"line_number":20,"context_line":"    api_definition \u003d apidef\r"}],"source_content_type":"text/x-python","patch_set":21,"id":"ffeb97d4_8a07d856","line":17,"range":{"start_line":17,"start_character":6,"end_line":17,"end_character":37},"in_reply_to":"a21ae6bf_0d6072c7","updated":"2021-07-06 02:06:58.000000000","message":"Awkward, sorry","commit_id":"3899db0452c0f6976e8a70d2364d7cc871ffbfa5"},{"author":{"_account_id":8313,"name":"Lajos Katona","display_name":"lajoskatona","email":"katonalala@gmail.com","username":"elajkat","status":"Ericsson Software Technology"},"change_message_id":"61f768fa178ef0130834503985cf6bf4be883021","unresolved":true,"context_lines":[{"line_number":14,"context_line":"from neutron_lib.api import extensions\r"},{"line_number":15,"context_line":"\r"},{"line_number":16,"context_line":"\r"},{"line_number":17,"context_line":"class Dns_integration_domain_keywords(extensions.APIExtensionDescriptor):\r"},{"line_number":18,"context_line":"    \"\"\"Extension class supporting configuration of dns domain with keywords.\"\"\"\r"},{"line_number":19,"context_line":"\r"},{"line_number":20,"context_line":"    api_definition \u003d apidef\r"}],"source_content_type":"text/x-python","patch_set":21,"id":"a21ae6bf_0d6072c7","line":17,"range":{"start_line":17,"start_character":6,"end_line":17,"end_character":37},"in_reply_to":"cfabf272_3cf5aa66","updated":"2021-07-05 08:49:44.000000000","message":"This seems to be a copy/paste error: https://opendev.org/openstack/neutron/src/branch/master/neutron/extensions/dns_integration_domain_keywords.py","commit_id":"3899db0452c0f6976e8a70d2364d7cc871ffbfa5"}],"neutron/tests/functional/agent/l3/test_dvr_router.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"c34ae6ae3f21714b87393decf4c4146ff662cddf","unresolved":false,"context_lines":[{"line_number":2159,"context_line":"                entry[\u0027next_hops\u0027].sort()"},{"line_number":2160,"context_line":"        self.assertIn(expected_route[0], actual_routes)"},{"line_number":2161,"context_line":"        self._delete_router(self.agent, router1.router_id)"},{"line_number":2162,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"9f560f44_a9843b0c","line":2162,"updated":"2020-09-09 12:07:17.000000000","message":"pep8: W391 blank line at end of file","commit_id":"f15cb637c5cd57d1a1187aa96bab5acd743903ba"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"8757a467777ad70d1bab867fd2bdb04e93aaa66f","unresolved":true,"context_lines":[{"line_number":2207,"context_line":"            if entry[\u0027next_hops\u0027]:"},{"line_number":2208,"context_line":"                entry[\u0027next_hops\u0027].sort()"},{"line_number":2209,"context_line":"        self.assertIn(expected_route[0], actual_routes)"},{"line_number":2210,"context_line":"        self._delete_router(self.agent, router1.router_id)"}],"source_content_type":"text/x-python","patch_set":13,"id":"13c70f6f_74a20062","line":2210,"updated":"2021-03-22 08:51:30.000000000","message":"do we need to call this _delete_router() here?","commit_id":"f23afa42406184b53454979dff565910871b4664"},{"author":{"_account_id":31814,"name":"XiaoYu Zhu","email":"z503755743@gmail.com","username":"z503755743"},"change_message_id":"0bb0e46c4b49c48b8fa72d2b72c4da91d192fddc","unresolved":false,"context_lines":[{"line_number":2207,"context_line":"            if entry[\u0027next_hops\u0027]:"},{"line_number":2208,"context_line":"                entry[\u0027next_hops\u0027].sort()"},{"line_number":2209,"context_line":"        self.assertIn(expected_route[0], actual_routes)"},{"line_number":2210,"context_line":"        self._delete_router(self.agent, router1.router_id)"}],"source_content_type":"text/x-python","patch_set":13,"id":"bc82d7d8_11075791","line":2210,"in_reply_to":"13c70f6f_74a20062","updated":"2021-05-26 10:21:48.000000000","message":"no 😊","commit_id":"f23afa42406184b53454979dff565910871b4664"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"82a0f695a68b5fdc452d01f0602084c1aa7e8bbf","unresolved":true,"context_lines":[{"line_number":2213,"context_line":"                    via_list \u003d [{\u0027via\u0027: hop[\u0027via\u0027]}"},{"line_number":2214,"context_line":"                                for hop in entry[\u0027via\u0027]]"},{"line_number":2215,"context_line":"                    entry[\u0027via\u0027] \u003d sorted(via_list, key\u003dlambda i: i[\u0027via\u0027])"},{"line_number":2216,"context_line":"        self.assertIn(expected_route[0], actual_routes)"}],"source_content_type":"text/x-python","patch_set":22,"id":"1e6b33bb_5d88e986","line":2216,"updated":"2021-07-07 07:22:50.000000000","message":"Maybe You could extend that test so it would:\n\n1. Add 3 routes to the same destination,\n2. check if all is set (as it is now)\n3. Remove one of the routes\n4. Check that 2 others are still there\n5. Remove second one,\n6. Check that one route is still there\n\nWdyt?","commit_id":"dcd33a4949814f66fe09eacc508942e0b2a29b3d"}],"neutron/tests/unit/agent/l3/test_router_info.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"1fc4972eb299ef19d45afeeb9972209f467ef9ac","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from neutron.conf.agent.l3 import config as l3_config"},{"line_number":23,"context_line":"from neutron.tests import base"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"from pyroute2 import NetNS"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"_uuid \u003d uuidutils.generate_uuid"},{"line_number":28,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9f560f44_02955d33","line":25,"updated":"2020-08-21 11:38:25.000000000","message":"pep8: F401 \u0027pyroute2.NetNS\u0027 imported but unused","commit_id":"826f4ec98bce0b27934c2a29af2bb599917676c4"}],"releasenotes/notes/ecmp-routes-771ff34beafee370.yaml":[{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"82a0f695a68b5fdc452d01f0602084c1aa7e8bbf","unresolved":true,"context_lines":[{"line_number":1,"context_line":"---\r"},{"line_number":2,"context_line":"features:\r"},{"line_number":3,"context_line":"  - |\r"},{"line_number":4,"context_line":"    ECMP is a kind of routing technology which allows traffic to reach the\r"},{"line_number":5,"context_line":"    same destination via multiple different links. With this change, neutron\r"},{"line_number":6,"context_line":"    will consolidate multiple routes with the same destination address into\r"},{"line_number":7,"context_line":"    a single ECMP route. For more information see bug\r"},{"line_number":8,"context_line":"    `1880532 \u003chttps://bugs.launchpad.net/neutron/+bug/1880532\u003e`_.\r"}],"source_content_type":"text/x-yaml","patch_set":22,"id":"8a37b161_a7136ab4","line":5,"range":{"start_line":4,"start_character":4,"end_line":5,"end_character":50},"updated":"2021-07-07 07:22:50.000000000","message":"I\u0027m not sure if we need to explain in our release notes what ECMP is. Maybe You can just say that \"Neutron supports ECMP routes now\" and link to some page where ECMP is explained.","commit_id":"dcd33a4949814f66fe09eacc508942e0b2a29b3d"}]}
