)]}'
{"etc/policy.json":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":52,"context_line":"    \"get_service_type\": \"rule:regular_user\","},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    \"update_extra_route\": \"rule:regular_user\","},{"line_number":55,"context_line":"    \"get_extra_route\": \"rule:regular_user\""},{"line_number":56,"context_line":"}"}],"source_content_type":"application/json","patch_set":9,"id":"AAAAM3%2F%2FMbs%3D","line":55,"updated":"2013-02-04 07:06:35.000000000","message":"Why do we need these policies? I think \"default\" policy (admin_or_owner) is a reasonable policy for them.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":52,"context_line":"    \"get_service_type\": \"rule:regular_user\","},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    \"update_extra_route\": \"rule:regular_user\","},{"line_number":55,"context_line":"    \"get_extra_route\": \"rule:regular_user\""},{"line_number":56,"context_line":"}"}],"source_content_type":"application/json","patch_set":9,"id":"AAAAM3%2F%2FLSE%3D","line":55,"in_reply_to":"AAAAM3%2F%2FMbs%3D","updated":"2013-02-04 20:59:49.000000000","message":"This is because of extra route didn\u0027t have tenant_id.\nBut it looks confusing, so I will add tenant_id here.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"}],"quantum/agent/l3_agent.py":[{"author":{"_account_id":490,"name":"Sumit Naiksatam","email":"sumitnaiksatam@gmail.com","username":"snaiksat"},"change_message_id":"b3a094d6c3c0f46a511027dcd90a83921ef644c2","unresolved":false,"context_lines":[{"line_number":32,"context_line":"from quantum.agent.linux import iptables_manager"},{"line_number":33,"context_line":"from quantum.agent.linux import utils"},{"line_number":34,"context_line":"from quantum.common import constants as l3_constants"},{"line_number":35,"context_line":"from quantum.common import utils as common_utils"},{"line_number":36,"context_line":"from quantum.common import topics"},{"line_number":37,"context_line":"from quantum import context"},{"line_number":38,"context_line":"from quantum import manager"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FfYY%3D","line":35,"updated":"2013-01-18 19:57:02.000000000","message":"Minor nit: should this import be placed after the next one?","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":32,"context_line":"from quantum.agent.linux import iptables_manager"},{"line_number":33,"context_line":"from quantum.agent.linux import utils"},{"line_number":34,"context_line":"from quantum.common import constants as l3_constants"},{"line_number":35,"context_line":"from quantum.common import utils as common_utils"},{"line_number":36,"context_line":"from quantum.common import topics"},{"line_number":37,"context_line":"from quantum import context"},{"line_number":38,"context_line":"from quantum import manager"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FdFE%3D","line":35,"in_reply_to":"AAAAM3%2F%2FfYY%3D","updated":"2013-01-22 08:27:04.000000000","message":"Done","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"04dd2d83201c28c7a123ab54ceb678b8af388cc8","unresolved":false,"context_lines":[{"line_number":634,"context_line":"                                                       new_routes)"},{"line_number":635,"context_line":"        for hashed_route in adds:"},{"line_number":636,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"},{"line_number":637,"context_line":"            LOG.debug(\"adding routing value is \u0027%s\u0027\" % route)"},{"line_number":638,"context_line":"            self._update_routing_table(ri, \u0027add\u0027, route)"},{"line_number":639,"context_line":"        for hashed_route in removes:"},{"line_number":640,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2Fe1g%3D","line":637,"updated":"2013-01-19 11:49:19.000000000","message":"LOG.debug(_(\"Adding routing value is \u0027%s\u0027\"), route)","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":634,"context_line":"                                                       new_routes)"},{"line_number":635,"context_line":"        for hashed_route in adds:"},{"line_number":636,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"},{"line_number":637,"context_line":"            LOG.debug(\"adding routing value is \u0027%s\u0027\" % route)"},{"line_number":638,"context_line":"            self._update_routing_table(ri, \u0027add\u0027, route)"},{"line_number":639,"context_line":"        for hashed_route in removes:"},{"line_number":640,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FdFA%3D","line":637,"in_reply_to":"AAAAM3%2F%2Fe1g%3D","updated":"2013-01-22 08:27:04.000000000","message":"Done","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"04dd2d83201c28c7a123ab54ceb678b8af388cc8","unresolved":false,"context_lines":[{"line_number":638,"context_line":"            self._update_routing_table(ri, \u0027add\u0027, route)"},{"line_number":639,"context_line":"        for hashed_route in removes:"},{"line_number":640,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"},{"line_number":641,"context_line":"            LOG.debug(\"removing routing value is \u0027%s\u0027\" % route)"},{"line_number":642,"context_line":"            self._update_routing_table(ri, \u0027del\u0027, route)"},{"line_number":643,"context_line":"        ri.routes \u003d new_routes"},{"line_number":644,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2Fe1c%3D","line":641,"updated":"2013-01-19 11:49:19.000000000","message":"LOG.debug(_(\"Removing routing value is \u0027%s\u0027\"), route)","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":638,"context_line":"            self._update_routing_table(ri, \u0027add\u0027, route)"},{"line_number":639,"context_line":"        for hashed_route in removes:"},{"line_number":640,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"},{"line_number":641,"context_line":"            LOG.debug(\"removing routing value is \u0027%s\u0027\" % route)"},{"line_number":642,"context_line":"            self._update_routing_table(ri, \u0027del\u0027, route)"},{"line_number":643,"context_line":"        ri.routes \u003d new_routes"},{"line_number":644,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FdE4%3D","line":641,"in_reply_to":"AAAAM3%2F%2Fe1c%3D","updated":"2013-01-22 08:27:04.000000000","message":"Done","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":617,"context_line":"        else:"},{"line_number":618,"context_line":"            net_type \u003d \u0027-net\u0027"},{"line_number":619,"context_line":"            address \u003d route[\u0027destination\u0027]"},{"line_number":620,"context_line":"        cmd \u003d [\u0027route\u0027, operation, net_type, address,"},{"line_number":621,"context_line":"               \u0027gw\u0027, route[\u0027nexthop\u0027]]"},{"line_number":622,"context_line":"        if self.conf.use_namespaces:"},{"line_number":623,"context_line":"            ip_wrapper \u003d ip_lib.IPWrapper(self.conf.root_helper,"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAM3%2F%2Fch4%3D","line":620,"updated":"2013-01-22 08:56:57.000000000","message":"why not use the ip route commands?\n\nwe have a library for those.","commit_id":"5683bf0f92617b65a4f5ba2bb0c1c2cc8b0c6090"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":617,"context_line":"        else:"},{"line_number":618,"context_line":"            net_type \u003d \u0027-net\u0027"},{"line_number":619,"context_line":"            address \u003d route[\u0027destination\u0027]"},{"line_number":620,"context_line":"        cmd \u003d [\u0027route\u0027, operation, net_type, address,"},{"line_number":621,"context_line":"               \u0027gw\u0027, route[\u0027nexthop\u0027]]"},{"line_number":622,"context_line":"        if self.conf.use_namespaces:"},{"line_number":623,"context_line":"            ip_wrapper \u003d ip_lib.IPWrapper(self.conf.root_helper,"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAM3%2F%2FZR0%3D","line":620,"in_reply_to":"AAAAM3%2F%2Fch4%3D","updated":"2013-01-24 06:58:11.000000000","message":"the lib looks didn\u0027t support routing config in namespace. ( also route configuration ) \nL400 didn\u0027t use the lib.\nI agree we should support this in the lib, but it looks not small change, so we should do it in different patch set.","commit_id":"5683bf0f92617b65a4f5ba2bb0c1c2cc8b0c6090"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":634,"context_line":"                                                       new_routes)"},{"line_number":635,"context_line":"        for hashed_route in adds:"},{"line_number":636,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"},{"line_number":637,"context_line":"            LOG.debug(\"Adding routing value is \u0027%s\u0027\" % route)"},{"line_number":638,"context_line":"            self._update_routing_table(ri, \u0027add\u0027, route)"},{"line_number":639,"context_line":"        for hashed_route in removes:"},{"line_number":640,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAM3%2F%2Fch0%3D","line":637,"updated":"2013-01-22 08:56:57.000000000","message":"i18n","commit_id":"5683bf0f92617b65a4f5ba2bb0c1c2cc8b0c6090"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":634,"context_line":"                                                       new_routes)"},{"line_number":635,"context_line":"        for hashed_route in adds:"},{"line_number":636,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"},{"line_number":637,"context_line":"            LOG.debug(\"Adding routing value is \u0027%s\u0027\" % route)"},{"line_number":638,"context_line":"            self._update_routing_table(ri, \u0027add\u0027, route)"},{"line_number":639,"context_line":"        for hashed_route in removes:"},{"line_number":640,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAM3%2F%2FZRw%3D","line":637,"in_reply_to":"AAAAM3%2F%2Fch0%3D","updated":"2013-01-24 06:58:11.000000000","message":"Done","commit_id":"5683bf0f92617b65a4f5ba2bb0c1c2cc8b0c6090"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":638,"context_line":"            self._update_routing_table(ri, \u0027add\u0027, route)"},{"line_number":639,"context_line":"        for hashed_route in removes:"},{"line_number":640,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"},{"line_number":641,"context_line":"            LOG.debug(\"Removing routing value is \u0027%s\u0027\" % route)"},{"line_number":642,"context_line":"            self._update_routing_table(ri, \u0027del\u0027, route)"},{"line_number":643,"context_line":"        ri.routes \u003d new_routes"},{"line_number":644,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAM3%2F%2Fchw%3D","line":641,"updated":"2013-01-22 08:56:57.000000000","message":"i18n","commit_id":"5683bf0f92617b65a4f5ba2bb0c1c2cc8b0c6090"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":638,"context_line":"            self._update_routing_table(ri, \u0027add\u0027, route)"},{"line_number":639,"context_line":"        for hashed_route in removes:"},{"line_number":640,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"},{"line_number":641,"context_line":"            LOG.debug(\"Removing routing value is \u0027%s\u0027\" % route)"},{"line_number":642,"context_line":"            self._update_routing_table(ri, \u0027del\u0027, route)"},{"line_number":643,"context_line":"        ri.routes \u003d new_routes"},{"line_number":644,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAM3%2F%2FZRs%3D","line":641,"in_reply_to":"AAAAM3%2F%2Fchw%3D","updated":"2013-01-24 06:58:11.000000000","message":"Done","commit_id":"5683bf0f92617b65a4f5ba2bb0c1c2cc8b0c6090"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":618,"context_line":""},{"line_number":619,"context_line":"    def _update_routing_table(self, ri, operation, route):"},{"line_number":620,"context_line":"        cidr \u003d route[\u0027destination\u0027].split(\u0027/\u0027)"},{"line_number":621,"context_line":"        if cidr[1] \u003d\u003d \"32\":"},{"line_number":622,"context_line":"            net_type \u003d \u0027-host\u0027"},{"line_number":623,"context_line":"            address \u003d cidr[0]"},{"line_number":624,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMX4%3D","line":621,"updated":"2013-02-04 07:06:35.000000000","message":"Do we need a unit test for this?","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":618,"context_line":""},{"line_number":619,"context_line":"    def _update_routing_table(self, ri, operation, route):"},{"line_number":620,"context_line":"        cidr \u003d route[\u0027destination\u0027].split(\u0027/\u0027)"},{"line_number":621,"context_line":"        if cidr[1] \u003d\u003d \"32\":"},{"line_number":622,"context_line":"            net_type \u003d \u0027-host\u0027"},{"line_number":623,"context_line":"            address \u003d cidr[0]"},{"line_number":624,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLO0%3D","line":621,"in_reply_to":"AAAAM3%2F%2FMX4%3D","updated":"2013-02-04 20:59:49.000000000","message":"It is tested in https://review.openstack.org/#/c/19882/9/quantum/tests/unit/test_l3_agent.py","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":625,"context_line":"            net_type \u003d \u0027-net\u0027"},{"line_number":626,"context_line":"            address \u003d route[\u0027destination\u0027]"},{"line_number":627,"context_line":"        cmd \u003d [\u0027route\u0027, operation, net_type, address,"},{"line_number":628,"context_line":"               \u0027gw\u0027, route[\u0027nexthop\u0027]]"},{"line_number":629,"context_line":"        if self.conf.use_namespaces:"},{"line_number":630,"context_line":"            ip_wrapper \u003d ip_lib.IPWrapper(self.conf.root_helper,"},{"line_number":631,"context_line":"                                          namespace\u003dri.ns_name())"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMXs%3D","line":628,"updated":"2013-02-04 07:06:35.000000000","message":"The linux specific command should be implemented in agent/linux/ip_lib.py. IpRouteCommand is a good place.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":625,"context_line":"            net_type \u003d \u0027-net\u0027"},{"line_number":626,"context_line":"            address \u003d route[\u0027destination\u0027]"},{"line_number":627,"context_line":"        cmd \u003d [\u0027route\u0027, operation, net_type, address,"},{"line_number":628,"context_line":"               \u0027gw\u0027, route[\u0027nexthop\u0027]]"},{"line_number":629,"context_line":"        if self.conf.use_namespaces:"},{"line_number":630,"context_line":"            ip_wrapper \u003d ip_lib.IPWrapper(self.conf.root_helper,"},{"line_number":631,"context_line":"                                          namespace\u003dri.ns_name())"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLOo%3D","line":628,"in_reply_to":"AAAAM3%2F%2FMXs%3D","updated":"2013-02-04 20:59:49.000000000","message":"the lib looks didn\u0027t support routing config in namespace. ( also route configuration ) L400 didn\u0027t use the lib. I agree we should support this in the lib, but it looks not small change, so we should do it in different patch set.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":641,"context_line":"                                                       new_routes)"},{"line_number":642,"context_line":"        for hashed_route in adds:"},{"line_number":643,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"},{"line_number":644,"context_line":"            LOG.debug(_(\"Adding routing value is \u0027%s\u0027\"), route)"},{"line_number":645,"context_line":"            self._update_routing_table(ri, \u0027add\u0027, route)"},{"line_number":646,"context_line":"        for hashed_route in removes:"},{"line_number":647,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMXw%3D","line":644,"updated":"2013-02-04 07:06:35.000000000","message":"Adding routing value -\u003e Added routing entry","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":641,"context_line":"                                                       new_routes)"},{"line_number":642,"context_line":"        for hashed_route in adds:"},{"line_number":643,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"},{"line_number":644,"context_line":"            LOG.debug(_(\"Adding routing value is \u0027%s\u0027\"), route)"},{"line_number":645,"context_line":"            self._update_routing_table(ri, \u0027add\u0027, route)"},{"line_number":646,"context_line":"        for hashed_route in removes:"},{"line_number":647,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLOc%3D","line":644,"in_reply_to":"AAAAM3%2F%2FMXw%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":645,"context_line":"            self._update_routing_table(ri, \u0027add\u0027, route)"},{"line_number":646,"context_line":"        for hashed_route in removes:"},{"line_number":647,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"},{"line_number":648,"context_line":"            LOG.debug(_(\"Removing routing value is \u0027%s\u0027\"), route)"},{"line_number":649,"context_line":"            self._update_routing_table(ri, \u0027del\u0027, route)"},{"line_number":650,"context_line":"        ri.routes \u003d new_routes"},{"line_number":651,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMXk%3D","line":648,"updated":"2013-02-04 07:06:35.000000000","message":"Ditto","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":645,"context_line":"            self._update_routing_table(ri, \u0027add\u0027, route)"},{"line_number":646,"context_line":"        for hashed_route in removes:"},{"line_number":647,"context_line":"            route \u003d common_utils.unhash_dict(hashed_route)"},{"line_number":648,"context_line":"            LOG.debug(_(\"Removing routing value is \u0027%s\u0027\"), route)"},{"line_number":649,"context_line":"            self._update_routing_table(ri, \u0027del\u0027, route)"},{"line_number":650,"context_line":"        ri.routes \u003d new_routes"},{"line_number":651,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLOY%3D","line":648,"in_reply_to":"AAAAM3%2F%2FMXk%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"unresolved":false,"context_lines":[{"line_number":633,"context_line":"        else:"},{"line_number":634,"context_line":"            utils.execute(cmd, check_exit_code\u003dFalse,"},{"line_number":635,"context_line":"                          root_helper\u003dself.conf.root_helper)"},{"line_number":636,"context_line":""},{"line_number":637,"context_line":"    def routes_updated(self, ri):"},{"line_number":638,"context_line":"        new_routes \u003d ri.router[\u0027routes\u0027]"},{"line_number":639,"context_line":"        old_routes \u003d ri.routes"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2FGmU%3D","line":636,"updated":"2013-02-07 02:16:06.000000000","message":"How about enhancing ip_lib.IpRouteCommand?","commit_id":"4438e2215f415bf9b70f990425531cb665d41dce"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":633,"context_line":"        else:"},{"line_number":634,"context_line":"            utils.execute(cmd, check_exit_code\u003dFalse,"},{"line_number":635,"context_line":"                          root_helper\u003dself.conf.root_helper)"},{"line_number":636,"context_line":""},{"line_number":637,"context_line":"    def routes_updated(self, ri):"},{"line_number":638,"context_line":"        new_routes \u003d ri.router[\u0027routes\u0027]"},{"line_number":639,"context_line":"        old_routes \u003d ri.routes"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2B%2BIc%3D","line":636,"in_reply_to":"AAAAM3%2F%2FGmU%3D","updated":"2013-02-12 21:28:30.000000000","message":"I agree, however i wanna work on this on another patch because there are similar issue in the l3-agent code","commit_id":"4438e2215f415bf9b70f990425531cb665d41dce"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"unresolved":false,"context_lines":[{"line_number":646,"context_line":"        for hashed_route in removes:"},{"line_number":647,"context_line":"            route \u003d common_utils.str2dict(hashed_route)"},{"line_number":648,"context_line":"            LOG.debug(_(\"Removed route entry is \u0027%s\u0027\"), route)"},{"line_number":649,"context_line":"            self._update_routing_table(ri, \u0027del\u0027, route)"},{"line_number":650,"context_line":"        ri.routes \u003d new_routes"},{"line_number":651,"context_line":""},{"line_number":652,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2FGlI%3D","line":649,"updated":"2013-02-07 02:16:06.000000000","message":"Deleting route should be done before adding route.\nE.g. what if user tries to replace route with same cidr?\nProbably it wouldn\u0027t be so serious, though.","commit_id":"4438e2215f415bf9b70f990425531cb665d41dce"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"unresolved":false,"context_lines":[{"line_number":646,"context_line":"        for hashed_route in removes:"},{"line_number":647,"context_line":"            route \u003d common_utils.str2dict(hashed_route)"},{"line_number":648,"context_line":"            LOG.debug(_(\"Removed route entry is \u0027%s\u0027\"), route)"},{"line_number":649,"context_line":"            self._update_routing_table(ri, \u0027del\u0027, route)"},{"line_number":650,"context_line":"        ri.routes \u003d new_routes"},{"line_number":651,"context_line":""},{"line_number":652,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2B9hg%3D","line":649,"in_reply_to":"AAAAM3%2F%2B%2BIU%3D","updated":"2013-02-13 05:32:01.000000000","message":"Hmm, \u0027ip route replace\u0027 should be used instead of add?\nAnd removes would be removes - adds.","commit_id":"4438e2215f415bf9b70f990425531cb665d41dce"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":646,"context_line":"        for hashed_route in removes:"},{"line_number":647,"context_line":"            route \u003d common_utils.str2dict(hashed_route)"},{"line_number":648,"context_line":"            LOG.debug(_(\"Removed route entry is \u0027%s\u0027\"), route)"},{"line_number":649,"context_line":"            self._update_routing_table(ri, \u0027del\u0027, route)"},{"line_number":650,"context_line":"        ri.routes \u003d new_routes"},{"line_number":651,"context_line":""},{"line_number":652,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2B8Nk%3D","line":649,"in_reply_to":"AAAAM3%2F%2B9hg%3D","updated":"2013-02-13 20:00:24.000000000","message":"I agree. \nI\u0027ll work on it on next patchset","commit_id":"4438e2215f415bf9b70f990425531cb665d41dce"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":646,"context_line":"        for hashed_route in removes:"},{"line_number":647,"context_line":"            route \u003d common_utils.str2dict(hashed_route)"},{"line_number":648,"context_line":"            LOG.debug(_(\"Removed route entry is \u0027%s\u0027\"), route)"},{"line_number":649,"context_line":"            self._update_routing_table(ri, \u0027del\u0027, route)"},{"line_number":650,"context_line":"        ri.routes \u003d new_routes"},{"line_number":651,"context_line":""},{"line_number":652,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2B%2BIU%3D","line":649,"in_reply_to":"AAAAM3%2F%2FGlI%3D","updated":"2013-02-12 21:28:30.000000000","message":"In order to keep connection, we should do add at first at nexthop migration.","commit_id":"4438e2215f415bf9b70f990425531cb665d41dce"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":623,"context_line":"    def after_start(self):"},{"line_number":624,"context_line":"        LOG.info(_(\"L3 agent started\"))"},{"line_number":625,"context_line":""},{"line_number":626,"context_line":"    def _update_routing_table(self, ri, operation, route):"},{"line_number":627,"context_line":"        cmd \u003d [\u0027ip\u0027, \u0027route\u0027, operation, \u0027to\u0027, route[\u0027destination\u0027],"},{"line_number":628,"context_line":"               \u0027via\u0027, route[\u0027nexthop\u0027]]"},{"line_number":629,"context_line":"        #TODO(nati) move this code to iplib"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxVI%3D","line":626,"updated":"2013-02-19 16:26:23.000000000","message":"is this meant to add and remove routes?","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":623,"context_line":"    def after_start(self):"},{"line_number":624,"context_line":"        LOG.info(_(\"L3 agent started\"))"},{"line_number":625,"context_line":""},{"line_number":626,"context_line":"    def _update_routing_table(self, ri, operation, route):"},{"line_number":627,"context_line":"        cmd \u003d [\u0027ip\u0027, \u0027route\u0027, operation, \u0027to\u0027, route[\u0027destination\u0027],"},{"line_number":628,"context_line":"               \u0027via\u0027, route[\u0027nexthop\u0027]]"},{"line_number":629,"context_line":"        #TODO(nati) move this code to iplib"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxTk%3D","line":626,"in_reply_to":"AAAAM3%2F%2BxVI%3D","updated":"2013-02-19 16:45:29.000000000","message":"Yes. it is decided with operation","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"unresolved":false,"context_lines":[{"line_number":645,"context_line":"            # remove replaced route from deleted route"},{"line_number":646,"context_line":"            for del_route in removes:"},{"line_number":647,"context_line":"                if route[\u0027destination\u0027] \u003d\u003d del_route[\u0027destination\u0027]:"},{"line_number":648,"context_line":"                    removes.remove(del_route)"},{"line_number":649,"context_line":"            #replace success even if there is no existing route"},{"line_number":650,"context_line":"            self._update_routing_table(ri, \u0027replace\u0027, route)"},{"line_number":651,"context_line":"        for route in removes:"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2ByKo%3D","line":648,"updated":"2013-02-19 11:12:00.000000000","message":"minor comment.\nremove \u003d [del_route for del_route in removes if del_route[\u0027destination\u0027] not in [reoute[\u0027destination\u0027] for route in adds]]\nafter for clause would be more direct and efficient.","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":645,"context_line":"            # remove replaced route from deleted route"},{"line_number":646,"context_line":"            for del_route in removes:"},{"line_number":647,"context_line":"                if route[\u0027destination\u0027] \u003d\u003d del_route[\u0027destination\u0027]:"},{"line_number":648,"context_line":"                    removes.remove(del_route)"},{"line_number":649,"context_line":"            #replace success even if there is no existing route"},{"line_number":650,"context_line":"            self._update_routing_table(ri, \u0027replace\u0027, route)"},{"line_number":651,"context_line":"        for route in removes:"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2Bxhw%3D","line":648,"in_reply_to":"AAAAM3%2F%2ByKo%3D","updated":"2013-02-19 15:34:36.000000000","message":"IMO, we should avoid to use complicated list comprehensions for readability.","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":638,"context_line":"    def routes_updated(self, ri):"},{"line_number":639,"context_line":"        new_routes \u003d ri.router[\u0027routes\u0027]"},{"line_number":640,"context_line":"        old_routes \u003d ri.routes"},{"line_number":641,"context_line":"        adds, removes \u003d common_utils.diff_list_of_dict(old_routes,"},{"line_number":642,"context_line":"                                                       new_routes)"},{"line_number":643,"context_line":"        for route in adds:"},{"line_number":644,"context_line":"            LOG.debug(_(\"Added route entry is \u0027%s\u0027\"), route)"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2BxCg%3D","line":641,"updated":"2013-02-19 17:57:17.000000000","message":"from what i understand in the code below if there are common routes for the add and delete then they will be added.\nIs there anyway that the method above can have the add include the intersection. this will save the additional loop below","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":638,"context_line":"    def routes_updated(self, ri):"},{"line_number":639,"context_line":"        new_routes \u003d ri.router[\u0027routes\u0027]"},{"line_number":640,"context_line":"        old_routes \u003d ri.routes"},{"line_number":641,"context_line":"        adds, removes \u003d common_utils.diff_list_of_dict(old_routes,"},{"line_number":642,"context_line":"                                                       new_routes)"},{"line_number":643,"context_line":"        for route in adds:"},{"line_number":644,"context_line":"            LOG.debug(_(\"Added route entry is \u0027%s\u0027\"), route)"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2Bw6M%3D","line":641,"in_reply_to":"AAAAM3%2F%2BxCg%3D","updated":"2013-02-19 18:33:42.000000000","message":"Thank you for your this comment.\nActually, this is not intersection.\na route has a nexthop and a destination. \ndiff_list_of_dict uses both of that.\nThere are routes who has same destination in adds and removes.\nFor that one, we should replace it.","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"}],"quantum/api/v2/attributes.py":[{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":194,"context_line":"        msg \u003d _(\"Invalid data format for hostroute: \u0027%s\u0027\") % data"},{"line_number":195,"context_line":"        LOG.debug(msg)"},{"line_number":196,"context_line":"        return msg"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"    expected_keys \u003d [\u0027destination\u0027, \u0027nexthop\u0027]"},{"line_number":199,"context_line":"    hostroutes \u003d []"},{"line_number":200,"context_line":"    for hostroute in data:"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxWI%3D","side":"PARENT","line":197,"updated":"2013-02-19 16:26:23.000000000","message":"please return the line","commit_id":"aaa80ea649697192bc022d831da9ddc4d6559344"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":194,"context_line":"        msg \u003d _(\"Invalid data format for hostroute: \u0027%s\u0027\") % data"},{"line_number":195,"context_line":"        LOG.debug(msg)"},{"line_number":196,"context_line":"        return msg"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"    expected_keys \u003d [\u0027destination\u0027, \u0027nexthop\u0027]"},{"line_number":199,"context_line":"    hostroutes \u003d []"},{"line_number":200,"context_line":"    for hostroute in data:"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxTc%3D","side":"PARENT","line":197,"in_reply_to":"AAAAM3%2F%2BxWI%3D","updated":"2013-02-19 16:45:29.000000000","message":"Done","commit_id":"aaa80ea649697192bc022d831da9ddc4d6559344"}],"quantum/api/v2/base.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"04dd2d83201c28c7a123ab54ceb678b8af388cc8","unresolved":false,"context_lines":[{"line_number":38,"context_line":"             netaddr.AddrFormatError: webob.exc.HTTPBadRequest,"},{"line_number":39,"context_line":"             AttributeError: webob.exc.HTTPBadRequest,"},{"line_number":40,"context_line":"             ValueError: webob.exc.HTTPBadRequest,"},{"line_number":41,"context_line":"             exceptions.RouterHostRoutesExhausted: webob.exc.HTTPBadRequest,"},{"line_number":42,"context_line":"             exceptions.RouterHostIPAddressDup: webob.exc.HTTPConflict,"},{"line_number":43,"context_line":"             }"},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FevQ%3D","line":41,"updated":"2013-01-19 18:10:50.000000000","message":"RouterHostRoutesExhausted is sub-class of BadRequest. BadRequest already mapped at line 35, so needn\u0027t map it at here","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":38,"context_line":"             netaddr.AddrFormatError: webob.exc.HTTPBadRequest,"},{"line_number":39,"context_line":"             AttributeError: webob.exc.HTTPBadRequest,"},{"line_number":40,"context_line":"             ValueError: webob.exc.HTTPBadRequest,"},{"line_number":41,"context_line":"             exceptions.RouterHostRoutesExhausted: webob.exc.HTTPBadRequest,"},{"line_number":42,"context_line":"             exceptions.RouterHostIPAddressDup: webob.exc.HTTPConflict,"},{"line_number":43,"context_line":"             }"},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FdE0%3D","line":41,"in_reply_to":"AAAAM3%2F%2FevQ%3D","updated":"2013-01-22 08:27:04.000000000","message":"Done","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"04dd2d83201c28c7a123ab54ceb678b8af388cc8","unresolved":false,"context_lines":[{"line_number":39,"context_line":"             AttributeError: webob.exc.HTTPBadRequest,"},{"line_number":40,"context_line":"             ValueError: webob.exc.HTTPBadRequest,"},{"line_number":41,"context_line":"             exceptions.RouterHostRoutesExhausted: webob.exc.HTTPBadRequest,"},{"line_number":42,"context_line":"             exceptions.RouterHostIPAddressDup: webob.exc.HTTPConflict,"},{"line_number":43,"context_line":"             }"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"QUOTAS \u003d quota.QUOTAS"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FevM%3D","line":42,"updated":"2013-01-19 18:10:50.000000000","message":"Same as above, but I found RouterHostIPAddressDup is sub-class of BadRequest","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":39,"context_line":"             AttributeError: webob.exc.HTTPBadRequest,"},{"line_number":40,"context_line":"             ValueError: webob.exc.HTTPBadRequest,"},{"line_number":41,"context_line":"             exceptions.RouterHostRoutesExhausted: webob.exc.HTTPBadRequest,"},{"line_number":42,"context_line":"             exceptions.RouterHostIPAddressDup: webob.exc.HTTPConflict,"},{"line_number":43,"context_line":"             }"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"QUOTAS \u003d quota.QUOTAS"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FdEw%3D","line":42,"in_reply_to":"AAAAM3%2F%2FevM%3D","updated":"2013-01-22 08:27:04.000000000","message":"Done","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"}],"quantum/api/v2/resource.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":75,"context_line":"            args \u003d route_args[1].copy()"},{"line_number":76,"context_line":"        else:"},{"line_number":77,"context_line":"            args \u003d {}"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        # NOTE(jkoelker) by now the controller is already found, remove"},{"line_number":80,"context_line":"        #                it from the args if it is in the matchdict"},{"line_number":81,"context_line":"        args.pop(\u0027controller\u0027, None)"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMbo%3D","side":"PARENT","line":78,"updated":"2013-02-04 07:06:35.000000000","message":"This is not related to this patch.","commit_id":"8db82533e1f04dc0cc570bab1b873d33985bf7ed"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":75,"context_line":"            args \u003d route_args[1].copy()"},{"line_number":76,"context_line":"        else:"},{"line_number":77,"context_line":"            args \u003d {}"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        # NOTE(jkoelker) by now the controller is already found, remove"},{"line_number":80,"context_line":"        #                it from the args if it is in the matchdict"},{"line_number":81,"context_line":"        args.pop(\u0027controller\u0027, None)"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLRs%3D","side":"PARENT","line":78,"in_reply_to":"AAAAM3%2F%2FMbo%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"8db82533e1f04dc0cc570bab1b873d33985bf7ed"}],"quantum/common/exceptions.py":[{"author":{"_account_id":490,"name":"Sumit Naiksatam","email":"sumitnaiksatam@gmail.com","username":"snaiksat"},"change_message_id":"b3a094d6c3c0f46a511027dcd90a83921ef644c2","unresolved":false,"context_lines":[{"line_number":129,"context_line":""},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"class RouterHostIPAddressDup(BadRequest):"},{"line_number":132,"context_line":"    message \u003d _(\"The %(part)s %(ip)s duplicated in host_routes.\")"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"class DNSNameServersExhausted(BadRequest):"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FfYI%3D","line":132,"updated":"2013-01-18 19:57:02.000000000","message":"Minor nit: missing \"is\".\n\nAlso, host_routes -\u003e host routes","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":129,"context_line":""},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"class RouterHostIPAddressDup(BadRequest):"},{"line_number":132,"context_line":"    message \u003d _(\"The %(part)s %(ip)s duplicated in host_routes.\")"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"class DNSNameServersExhausted(BadRequest):"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FdEg%3D","line":132,"in_reply_to":"AAAAM3%2F%2FfYI%3D","updated":"2013-01-22 08:27:04.000000000","message":"Done","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"}],"quantum/common/utils.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"04dd2d83201c28c7a123ab54ceb678b8af388cc8","unresolved":false,"context_lines":[{"line_number":164,"context_line":"    return set(a) \u003d\u003d set(b)"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"def str_uuid():"},{"line_number":168,"context_line":"    \"\"\"Return a uuid as a string\"\"\""},{"line_number":169,"context_line":"    return str(uuid.uuid4())"},{"line_number":170,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FevI%3D","line":167,"updated":"2013-01-19 18:10:50.000000000","message":"Is this used by other code?","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":164,"context_line":"    return set(a) \u003d\u003d set(b)"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"def str_uuid():"},{"line_number":168,"context_line":"    \"\"\"Return a uuid as a string\"\"\""},{"line_number":169,"context_line":"    return str(uuid.uuid4())"},{"line_number":170,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FdEc%3D","line":167,"in_reply_to":"AAAAM3%2F%2FevI%3D","updated":"2013-01-22 08:27:04.000000000","message":"May be merge mistake. removed","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":164,"context_line":"    return set(a) \u003d\u003d set(b)"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"def hash_dict(dic):"},{"line_number":168,"context_line":"    keys \u003d dic.keys()"},{"line_number":169,"context_line":"    keys.sort()"},{"line_number":170,"context_line":"    return \u0027,\u0027.join([\"%s\u003d%s\" % (key, dic[key]) for key in keys])"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMaI%3D","line":167,"updated":"2013-02-04 07:06:35.000000000","message":"hash and dict have the same meaning.\n\"dict2str\" is more descriptive to me. See below for details.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":164,"context_line":"    return set(a) \u003d\u003d set(b)"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"def hash_dict(dic):"},{"line_number":168,"context_line":"    keys \u003d dic.keys()"},{"line_number":169,"context_line":"    keys.sort()"},{"line_number":170,"context_line":"    return \u0027,\u0027.join([\"%s\u003d%s\" % (key, dic[key]) for key in keys])"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLRM%3D","line":167,"in_reply_to":"AAAAM3%2F%2FMaI%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":170,"context_line":"    return \u0027,\u0027.join([\"%s\u003d%s\" % (key, dic[key]) for key in keys])"},{"line_number":171,"context_line":""},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"def unhash_dict(string):"},{"line_number":174,"context_line":"    unhashed \u003d {}"},{"line_number":175,"context_line":"    for keyvalue in string.split(\u0027,\u0027):"},{"line_number":176,"context_line":"        (key, value) \u003d keyvalue.split(\u0027\u003d\u0027)"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMaQ%3D","line":173,"updated":"2013-02-04 07:06:35.000000000","message":"The method name needs more consideration....\nThe similar method in python-quantumclient is \u0027str2dict\u0027. (quantumclient/common/utils)","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":170,"context_line":"    return \u0027,\u0027.join([\"%s\u003d%s\" % (key, dic[key]) for key in keys])"},{"line_number":171,"context_line":""},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"def unhash_dict(string):"},{"line_number":174,"context_line":"    unhashed \u003d {}"},{"line_number":175,"context_line":"    for keyvalue in string.split(\u0027,\u0027):"},{"line_number":176,"context_line":"        (key, value) \u003d keyvalue.split(\u0027\u003d\u0027)"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLRQ%3D","line":173,"in_reply_to":"AAAAM3%2F%2FMaQ%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":172,"context_line":""},{"line_number":173,"context_line":"def unhash_dict(string):"},{"line_number":174,"context_line":"    unhashed \u003d {}"},{"line_number":175,"context_line":"    for keyvalue in string.split(\u0027,\u0027):"},{"line_number":176,"context_line":"        (key, value) \u003d keyvalue.split(\u0027\u003d\u0027)"},{"line_number":177,"context_line":"        unhashed[key] \u003d value"},{"line_number":178,"context_line":"    return unhashed"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMaY%3D","line":175,"updated":"2013-02-04 07:06:35.000000000","message":"split(\u0027,\u0027, 1) would be better","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":172,"context_line":""},{"line_number":173,"context_line":"def unhash_dict(string):"},{"line_number":174,"context_line":"    unhashed \u003d {}"},{"line_number":175,"context_line":"    for keyvalue in string.split(\u0027,\u0027):"},{"line_number":176,"context_line":"        (key, value) \u003d keyvalue.split(\u0027\u003d\u0027)"},{"line_number":177,"context_line":"        unhashed[key] \u003d value"},{"line_number":178,"context_line":"    return unhashed"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLRU%3D","line":175,"in_reply_to":"AAAAM3%2F%2FMaY%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"unresolved":false,"context_lines":[{"line_number":183,"context_line":"    old_set \u003d set([dict2str(l) for l in old_list])"},{"line_number":184,"context_line":"    added \u003d new_set - old_set"},{"line_number":185,"context_line":"    removed \u003d old_set - new_set"},{"line_number":186,"context_line":"    return added, removed"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2FGnA%3D","line":186,"updated":"2013-02-07 02:16:06.000000000","message":"It seems all the callers of this function apply str2dict.\nSo how about returning the result of str2dict?","commit_id":"4438e2215f415bf9b70f990425531cb665d41dce"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":183,"context_line":"    old_set \u003d set([dict2str(l) for l in old_list])"},{"line_number":184,"context_line":"    added \u003d new_set - old_set"},{"line_number":185,"context_line":"    removed \u003d old_set - new_set"},{"line_number":186,"context_line":"    return added, removed"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2B%2BG0%3D","line":186,"in_reply_to":"AAAAM3%2F%2FGnA%3D","updated":"2013-02-12 21:28:30.000000000","message":"good point! done","commit_id":"4438e2215f415bf9b70f990425531cb665d41dce"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"unresolved":false,"context_lines":[{"line_number":164,"context_line":"    return set(a) \u003d\u003d set(b)"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"def dict2str(dic):"},{"line_number":168,"context_line":"    keys \u003d dic.keys()"},{"line_number":169,"context_line":"    keys.sort()"},{"line_number":170,"context_line":"    return \u0027,\u0027.join([\"%s\u003d%s\" % (key, dic[key]) for key in keys])"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAM3%2F%2B7fc%3D","line":167,"updated":"2013-02-14 02:36:30.000000000","message":"Minor commnet.\nhow about\nreturn \u0027,\u0027.join(\"%s\u003d%s\" % (key, val) for key, val in sorted(d.iteritems()))","commit_id":"e22c4e039abe36f48dab68dd1025a8b7bcdbdd76"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":164,"context_line":"    return set(a) \u003d\u003d set(b)"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"def dict2str(dic):"},{"line_number":168,"context_line":"    keys \u003d dic.keys()"},{"line_number":169,"context_line":"    keys.sort()"},{"line_number":170,"context_line":"    return \u0027,\u0027.join([\"%s\u003d%s\" % (key, dic[key]) for key in keys])"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAM3%2F%2B7R0%3D","line":167,"in_reply_to":"AAAAM3%2F%2B7fc%3D","updated":"2013-02-14 06:17:37.000000000","message":"Done","commit_id":"e22c4e039abe36f48dab68dd1025a8b7bcdbdd76"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"unresolved":false,"context_lines":[{"line_number":170,"context_line":"    return \u0027,\u0027.join([\"%s\u003d%s\" % (key, dic[key]) for key in keys])"},{"line_number":171,"context_line":""},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"def str2dict(string):"},{"line_number":174,"context_line":"    res_dict \u003d {}"},{"line_number":175,"context_line":"    for keyvalue in string.split(\u0027,\u0027, 1):"},{"line_number":176,"context_line":"        (key, value) \u003d keyvalue.split(\u0027\u003d\u0027)"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAM3%2F%2B7e4%3D","line":173,"updated":"2013-02-14 02:36:30.000000000","message":"Minor comment.\nHow about return dict(keyvalue.split(\u0027\u003d\u0027, 1) for keyvalue in string.split(\u0027,\u0027))","commit_id":"e22c4e039abe36f48dab68dd1025a8b7bcdbdd76"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":170,"context_line":"    return \u0027,\u0027.join([\"%s\u003d%s\" % (key, dic[key]) for key in keys])"},{"line_number":171,"context_line":""},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"def str2dict(string):"},{"line_number":174,"context_line":"    res_dict \u003d {}"},{"line_number":175,"context_line":"    for keyvalue in string.split(\u0027,\u0027, 1):"},{"line_number":176,"context_line":"        (key, value) \u003d keyvalue.split(\u0027\u003d\u0027)"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAM3%2F%2B7Rw%3D","line":173,"in_reply_to":"AAAAM3%2F%2B7e4%3D","updated":"2013-02-14 06:17:37.000000000","message":"Done","commit_id":"e22c4e039abe36f48dab68dd1025a8b7bcdbdd76"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":180,"context_line":"def diff_list_of_dict(old_list, new_list):"},{"line_number":181,"context_line":"    new_set \u003d set([dict2str(l) for l in new_list])"},{"line_number":182,"context_line":"    old_set \u003d set([dict2str(l) for l in old_list])"},{"line_number":183,"context_line":"    added \u003d new_set - old_set"},{"line_number":184,"context_line":"    removed \u003d old_set - new_set"},{"line_number":185,"context_line":"    return [str2dict(a) for a in added], [str2dict(r) for r in removed]"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2BxCc%3D","line":183,"updated":"2013-02-19 17:57:17.000000000","message":"this should also have the intersection:\nnew_set - old_set + (new_set \u0026 old_set)","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":180,"context_line":"def diff_list_of_dict(old_list, new_list):"},{"line_number":181,"context_line":"    new_set \u003d set([dict2str(l) for l in new_list])"},{"line_number":182,"context_line":"    old_set \u003d set([dict2str(l) for l in old_list])"},{"line_number":183,"context_line":"    added \u003d new_set - old_set"},{"line_number":184,"context_line":"    removed \u003d old_set - new_set"},{"line_number":185,"context_line":"    return [str2dict(a) for a in added], [str2dict(r) for r in removed]"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2Bw6E%3D","line":183,"in_reply_to":"AAAAM3%2F%2BxCc%3D","updated":"2013-02-19 18:33:42.000000000","message":"replied in the l3-agent code","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":181,"context_line":"    new_set \u003d set([dict2str(l) for l in new_list])"},{"line_number":182,"context_line":"    old_set \u003d set([dict2str(l) for l in old_list])"},{"line_number":183,"context_line":"    added \u003d new_set - old_set"},{"line_number":184,"context_line":"    removed \u003d old_set - new_set"},{"line_number":185,"context_line":"    return [str2dict(a) for a in added], [str2dict(r) for r in removed]"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2BxCI%3D","line":184,"updated":"2013-02-19 17:57:17.000000000","message":"old_set - new_set + (new_set \u0026 old_set)","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":181,"context_line":"    new_set \u003d set([dict2str(l) for l in new_list])"},{"line_number":182,"context_line":"    old_set \u003d set([dict2str(l) for l in old_list])"},{"line_number":183,"context_line":"    added \u003d new_set - old_set"},{"line_number":184,"context_line":"    removed \u003d old_set - new_set"},{"line_number":185,"context_line":"    return [str2dict(a) for a in added], [str2dict(r) for r in removed]"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2Bw6I%3D","line":184,"in_reply_to":"AAAAM3%2F%2BxCI%3D","updated":"2013-02-19 18:33:42.000000000","message":"replied in the l3-agent code","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"}],"quantum/db/extraroute_db.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Copyright 2012, Nachi Ueno, NTT MCL, Inc."},{"line_number":4,"context_line":"# All Rights Reserved."},{"line_number":5,"context_line":"#"},{"line_number":6,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMbc%3D","line":3,"updated":"2013-02-04 07:06:35.000000000","message":"2013","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Copyright 2012, Nachi Ueno, NTT MCL, Inc."},{"line_number":4,"context_line":"# All Rights Reserved."},{"line_number":5,"context_line":"#"},{"line_number":6,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLRI%3D","line":3,"in_reply_to":"AAAAM3%2F%2FMbc%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":72,"context_line":"    def _validate_routes_nexthop(self, context, ports, routes, nexthop):"},{"line_number":73,"context_line":"        #Note(nati): Nexthop should be connected,"},{"line_number":74,"context_line":"        # so we need to check nexthop is"},{"line_number":75,"context_line":"        # in the cidrs in port\u0027s subnets"},{"line_number":76,"context_line":"        cidrs \u003d []"},{"line_number":77,"context_line":"        for port in ports:"},{"line_number":78,"context_line":"            cidrs +\u003d [self._get_subnet(context,"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMW4%3D","line":75,"updated":"2013-02-04 07:06:35.000000000","message":"nexthop belongs to one of cidrs of the router ports","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":72,"context_line":"    def _validate_routes_nexthop(self, context, ports, routes, nexthop):"},{"line_number":73,"context_line":"        #Note(nati): Nexthop should be connected,"},{"line_number":74,"context_line":"        # so we need to check nexthop is"},{"line_number":75,"context_line":"        # in the cidrs in port\u0027s subnets"},{"line_number":76,"context_line":"        cidrs \u003d []"},{"line_number":77,"context_line":"        for port in ports:"},{"line_number":78,"context_line":"            cidrs +\u003d [self._get_subnet(context,"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLRA%3D","line":75,"in_reply_to":"AAAAM3%2F%2FMW4%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":80,"context_line":"                      for ip in port[\u0027fixed_ips\u0027]]"},{"line_number":81,"context_line":"        if not netaddr.all_matching_cidrs(nexthop, cidrs):"},{"line_number":82,"context_line":"            raise extraroute.InvalidRoutes(routes\u003droutes)"},{"line_number":83,"context_line":"        # in the cidrs in port\u0027s subnets"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"        #Note(nati) nexthop should not be same as fixed_ips"},{"line_number":86,"context_line":"        for port in ports:"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMW0%3D","line":83,"updated":"2013-02-04 07:06:35.000000000","message":"This comment can be removed.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":80,"context_line":"                      for ip in port[\u0027fixed_ips\u0027]]"},{"line_number":81,"context_line":"        if not netaddr.all_matching_cidrs(nexthop, cidrs):"},{"line_number":82,"context_line":"            raise extraroute.InvalidRoutes(routes\u003droutes)"},{"line_number":83,"context_line":"        # in the cidrs in port\u0027s subnets"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"        #Note(nati) nexthop should not be same as fixed_ips"},{"line_number":86,"context_line":"        for port in ports:"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLQ4%3D","line":83,"in_reply_to":"AAAAM3%2F%2FMW0%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":108,"context_line":"            context, router[\u0027id\u0027])"},{"line_number":109,"context_line":"        added, removed \u003d utils.diff_list_of_dict(old_routes,"},{"line_number":110,"context_line":"                                                 routes)"},{"line_number":111,"context_line":"        LOG.debug(\u0027Added routes is %s\u0027 % added)"},{"line_number":112,"context_line":"        for hashed_route in added:"},{"line_number":113,"context_line":"            route \u003d utils.unhash_dict(hashed_route)"},{"line_number":114,"context_line":"            router_routes \u003d RouterRoute("}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMWw%3D","line":111,"updated":"2013-02-04 07:06:35.000000000","message":"is -\u003e are?","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":108,"context_line":"            context, router[\u0027id\u0027])"},{"line_number":109,"context_line":"        added, removed \u003d utils.diff_list_of_dict(old_routes,"},{"line_number":110,"context_line":"                                                 routes)"},{"line_number":111,"context_line":"        LOG.debug(\u0027Added routes is %s\u0027 % added)"},{"line_number":112,"context_line":"        for hashed_route in added:"},{"line_number":113,"context_line":"            route \u003d utils.unhash_dict(hashed_route)"},{"line_number":114,"context_line":"            router_routes \u003d RouterRoute("}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLQs%3D","line":111,"in_reply_to":"AAAAM3%2F%2FMWw%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":115,"context_line":"                router_id\u003drouter[\u0027id\u0027],"},{"line_number":116,"context_line":"                destination\u003droute[\u0027destination\u0027],"},{"line_number":117,"context_line":"                nexthop\u003droute[\u0027nexthop\u0027])"},{"line_number":118,"context_line":"            context.session.add(router_routes)"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"        LOG.debug(\u0027Removed routes is %s\u0027 % removed)"},{"line_number":121,"context_line":"        for hashed_route in removed:"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMWg%3D","line":118,"updated":"2013-02-04 07:06:35.000000000","message":"Where is this session started?\nAll routes update should be done in one sub transaction.\n\nIn addition, there is no session query for add, but there is a query for delete. These should be symmetric.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":115,"context_line":"                router_id\u003drouter[\u0027id\u0027],"},{"line_number":116,"context_line":"                destination\u003droute[\u0027destination\u0027],"},{"line_number":117,"context_line":"                nexthop\u003droute[\u0027nexthop\u0027])"},{"line_number":118,"context_line":"            context.session.add(router_routes)"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"        LOG.debug(\u0027Removed routes is %s\u0027 % removed)"},{"line_number":121,"context_line":"        for hashed_route in removed:"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLQg%3D","line":118,"in_reply_to":"AAAAM3%2F%2FMWg%3D","updated":"2013-02-04 20:59:49.000000000","message":"caller of _update_extra_routes manage sessions.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":136,"context_line":"            context, router[\u0027id\u0027])"},{"line_number":137,"context_line":"        return self._fields(res, fields)"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    def get_extra_routes_by_router_id(self, context, id):"},{"line_number":140,"context_line":"        query \u003d context.session.query(RouterRoute)"},{"line_number":141,"context_line":"        query.filter(RouterRoute.router_id \u003d\u003d id)"},{"line_number":142,"context_line":"        extra_routes \u003d query.all()"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMWE%3D","line":139,"updated":"2013-02-04 07:06:35.000000000","message":"is this a public method?","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":136,"context_line":"            context, router[\u0027id\u0027])"},{"line_number":137,"context_line":"        return self._fields(res, fields)"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    def get_extra_routes_by_router_id(self, context, id):"},{"line_number":140,"context_line":"        query \u003d context.session.query(RouterRoute)"},{"line_number":141,"context_line":"        query.filter(RouterRoute.router_id \u003d\u003d id)"},{"line_number":142,"context_line":"        extra_routes \u003d query.all()"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLQU%3D","line":139,"in_reply_to":"AAAAM3%2F%2FMWE%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":447,"name":"dan wendlandt","email":"dan@nicira.com","username":"danwent"},"unresolved":false,"context_lines":[{"line_number":130,"context_line":"    def _make_extra_route_dict(self, extra_routes):"},{"line_number":131,"context_line":"        return [{\u0027destination\u0027: route[\u0027destination\u0027],"},{"line_number":132,"context_line":"                 \u0027nexthop\u0027: route[\u0027nexthop\u0027]}"},{"line_number":133,"context_line":"                for route in extra_routes]"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    def _make_extra_routes_dict(self, context, router, fields\u003dNone):"},{"line_number":136,"context_line":"        res \u003d {\u0027router_id\u0027: router[\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2FIqU%3D","line":133,"updated":"2013-02-06 00:06:39.000000000","message":"this returns a list, while name implies it returns a dict.\n\ndoes this mean WS api call actually returns a list, or is this converted into a dictionary somewhere?","commit_id":"dca18f93927f6d211f3f30a2b6ed9125be2e6a4a"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":130,"context_line":"    def _make_extra_route_dict(self, extra_routes):"},{"line_number":131,"context_line":"        return [{\u0027destination\u0027: route[\u0027destination\u0027],"},{"line_number":132,"context_line":"                 \u0027nexthop\u0027: route[\u0027nexthop\u0027]}"},{"line_number":133,"context_line":"                for route in extra_routes]"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    def _make_extra_routes_dict(self, context, router, fields\u003dNone):"},{"line_number":136,"context_line":"        res \u003d {\u0027router_id\u0027: router[\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2FInI%3D","line":133,"in_reply_to":"AAAAM3%2F%2FIqU%3D","updated":"2013-02-06 00:43:28.000000000","message":"Done","commit_id":"dca18f93927f6d211f3f30a2b6ed9125be2e6a4a"},{"author":{"_account_id":447,"name":"dan wendlandt","email":"dan@nicira.com","username":"danwent"},"unresolved":false,"context_lines":[{"line_number":132,"context_line":"                 \u0027nexthop\u0027: route[\u0027nexthop\u0027]}"},{"line_number":133,"context_line":"                for route in extra_routes]"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    def _make_extra_routes_dict(self, context, router, fields\u003dNone):"},{"line_number":136,"context_line":"        res \u003d {\u0027router_id\u0027: router[\u0027id\u0027],"},{"line_number":137,"context_line":"               \u0027tenant_id\u0027: router[\u0027tenant_id\u0027]}"},{"line_number":138,"context_line":"        res[\u0027routes\u0027] \u003d self._get_extra_routes_by_router_id("}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2FIqQ%3D","line":135,"updated":"2013-02-06 00:06:39.000000000","message":"same issue?","commit_id":"dca18f93927f6d211f3f30a2b6ed9125be2e6a4a"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":132,"context_line":"                 \u0027nexthop\u0027: route[\u0027nexthop\u0027]}"},{"line_number":133,"context_line":"                for route in extra_routes]"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    def _make_extra_routes_dict(self, context, router, fields\u003dNone):"},{"line_number":136,"context_line":"        res \u003d {\u0027router_id\u0027: router[\u0027id\u0027],"},{"line_number":137,"context_line":"               \u0027tenant_id\u0027: router[\u0027tenant_id\u0027]}"},{"line_number":138,"context_line":"        res[\u0027routes\u0027] \u003d self._get_extra_routes_by_router_id("}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2FInE%3D","line":135,"in_reply_to":"AAAAM3%2F%2FIqQ%3D","updated":"2013-02-06 00:43:28.000000000","message":"This one returns dict","commit_id":"dca18f93927f6d211f3f30a2b6ed9125be2e6a4a"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"unresolved":false,"context_lines":[{"line_number":161,"context_line":"                    context, router[\u0027id\u0027])"},{"line_number":162,"context_line":"        return routers"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"    def _confirm_router_interface_not_in_use(self, context, router_id,"},{"line_number":165,"context_line":"                                             subnet_id):"},{"line_number":166,"context_line":"        super(ExtraRoute_db_mixin, self)._confirm_router_interface_not_in_use("},{"line_number":167,"context_line":"            context, router_id, subnet_id)"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2FGkw%3D","line":164,"updated":"2013-02-07 02:16:06.000000000","message":"Who calls this method?","commit_id":"4438e2215f415bf9b70f990425531cb665d41dce"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":161,"context_line":"                    context, router[\u0027id\u0027])"},{"line_number":162,"context_line":"        return routers"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"    def _confirm_router_interface_not_in_use(self, context, router_id,"},{"line_number":165,"context_line":"                                             subnet_id):"},{"line_number":166,"context_line":"        super(ExtraRoute_db_mixin, self)._confirm_router_interface_not_in_use("},{"line_number":167,"context_line":"            context, router_id, subnet_id)"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2B%2BGQ%3D","line":164,"in_reply_to":"AAAAM3%2F%2FGkw%3D","updated":"2013-02-12 21:28:30.000000000","message":"super class","commit_id":"4438e2215f415bf9b70f990425531cb665d41dce"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"import netaddr"},{"line_number":19,"context_line":"import sqlalchemy as sa"},{"line_number":20,"context_line":"from oslo.config import cfg"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from quantum.common import utils"},{"line_number":23,"context_line":"from quantum.db import l3_db"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxVw%3D","line":20,"updated":"2013-02-19 16:26:23.000000000","message":"should be after line 18","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"import netaddr"},{"line_number":19,"context_line":"import sqlalchemy as sa"},{"line_number":20,"context_line":"from oslo.config import cfg"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from quantum.common import utils"},{"line_number":23,"context_line":"from quantum.db import l3_db"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxTQ%3D","line":20,"in_reply_to":"AAAAM3%2F%2BxVw%3D","updated":"2013-02-19 16:45:29.000000000","message":"Done","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":32,"context_line":"extra_route_opts \u003d ["},{"line_number":33,"context_line":"    #TODO(nati): use quota framework when it support quota for attributes"},{"line_number":34,"context_line":"    cfg.IntOpt(\u0027max_routes\u0027, default\u003d30,"},{"line_number":35,"context_line":"               help\u003d_(\"Max number of routes\")),"},{"line_number":36,"context_line":"]"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"cfg.CONF.register_opts(extra_route_opts)"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BxNo%3D","line":35,"updated":"2013-02-19 17:24:58.000000000","message":"Maximum number of","commit_id":"9449e3cd04fa6ee6232e580a0c612ac219e90ec6"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":32,"context_line":"extra_route_opts \u003d ["},{"line_number":33,"context_line":"    #TODO(nati): use quota framework when it support quota for attributes"},{"line_number":34,"context_line":"    cfg.IntOpt(\u0027max_routes\u0027, default\u003d30,"},{"line_number":35,"context_line":"               help\u003d_(\"Max number of routes\")),"},{"line_number":36,"context_line":"]"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"cfg.CONF.register_opts(extra_route_opts)"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BxEo%3D","line":35,"in_reply_to":"AAAAM3%2F%2BxNo%3D","updated":"2013-02-19 17:44:10.000000000","message":"Done","commit_id":"9449e3cd04fa6ee6232e580a0c612ac219e90ec6"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":46,"context_line":""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin):"},{"line_number":49,"context_line":"    \"\"\" Mixin class to add extra route configuration support on L3\"\"\""},{"line_number":50,"context_line":"    def update_router(self, context, id, router):"},{"line_number":51,"context_line":"        r \u003d router[\u0027router\u0027]"},{"line_number":52,"context_line":"        with context.session.begin(subtransactions\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BxNQ%3D","line":49,"updated":"2013-02-19 17:24:58.000000000","message":"add extra route configuration support -\u003e support extra route configuration\nL3 -\u003e router","commit_id":"9449e3cd04fa6ee6232e580a0c612ac219e90ec6"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":46,"context_line":""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin):"},{"line_number":49,"context_line":"    \"\"\" Mixin class to add extra route configuration support on L3\"\"\""},{"line_number":50,"context_line":"    def update_router(self, context, id, router):"},{"line_number":51,"context_line":"        r \u003d router[\u0027router\u0027]"},{"line_number":52,"context_line":"        with context.session.begin(subtransactions\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BxEc%3D","line":49,"in_reply_to":"AAAAM3%2F%2BxNQ%3D","updated":"2013-02-19 17:44:10.000000000","message":"Done","commit_id":"9449e3cd04fa6ee6232e580a0c612ac219e90ec6"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":161,"context_line":"                                             subnet_id):"},{"line_number":162,"context_line":"        super(ExtraRoute_db_mixin, self)._confirm_router_interface_not_in_use("},{"line_number":163,"context_line":"            context, router_id, subnet_id)"},{"line_number":164,"context_line":"        subnet_db \u003d self._get_subnet(context, subnet_id)"},{"line_number":165,"context_line":"        subnet_cidr \u003d netaddr.IPNetwork(subnet_db[\u0027cidr\u0027])"},{"line_number":166,"context_line":"        extra_routes \u003d self._get_extra_routes_by_router_id(context, router_id)"},{"line_number":167,"context_line":"        for route in extra_routes:"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BxH4%3D","line":164,"updated":"2013-02-19 17:24:58.000000000","message":"Don\u0027t we need to use context.elevated()? Please check it.","commit_id":"9449e3cd04fa6ee6232e580a0c612ac219e90ec6"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":161,"context_line":"                                             subnet_id):"},{"line_number":162,"context_line":"        super(ExtraRoute_db_mixin, self)._confirm_router_interface_not_in_use("},{"line_number":163,"context_line":"            context, router_id, subnet_id)"},{"line_number":164,"context_line":"        subnet_db \u003d self._get_subnet(context, subnet_id)"},{"line_number":165,"context_line":"        subnet_cidr \u003d netaddr.IPNetwork(subnet_db[\u0027cidr\u0027])"},{"line_number":166,"context_line":"        extra_routes \u003d self._get_extra_routes_by_router_id(context, router_id)"},{"line_number":167,"context_line":"        for route in extra_routes:"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BxEU%3D","line":164,"in_reply_to":"AAAAM3%2F%2BxH4%3D","updated":"2013-02-19 17:44:10.000000000","message":"all resources looks in the permission of users.\nsuper class (l3_db) is not using context.elevated.","commit_id":"9449e3cd04fa6ee6232e580a0c612ac219e90ec6"},{"author":{"_account_id":490,"name":"Sumit Naiksatam","email":"sumitnaiksatam@gmail.com","username":"snaiksat"},"unresolved":false,"context_lines":[{"line_number":77,"context_line":"                                       ip[\u0027subnet_id\u0027])[\u0027cidr\u0027]"},{"line_number":78,"context_line":"                      for ip in port[\u0027fixed_ips\u0027]]"},{"line_number":79,"context_line":"        if not netaddr.all_matching_cidrs(nexthop, cidrs):"},{"line_number":80,"context_line":"            raise extraroute.InvalidRoutes(routes\u003droutes)"},{"line_number":81,"context_line":"        #Note(nati) nexthop should not be same as fixed_ips"},{"line_number":82,"context_line":"        for port in ports:"},{"line_number":83,"context_line":"            for ip in port[\u0027fixed_ips\u0027]:"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAAM3%2F%2BwWg%3D","line":80,"updated":"2013-02-19 22:05:48.000000000","message":"As an enhancement it might be helpful to have a different exception here - InvalidNextHop.","commit_id":"5951ff5ca019af2d956fd5139a03ac150f164478"}],"quantum/db/l3_db.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"04dd2d83201c28c7a123ab54ceb678b8af388cc8","unresolved":false,"context_lines":[{"line_number":294,"context_line":"        old_routes \u003d self._make_router_route_dict(router)"},{"line_number":295,"context_line":"        added, removed \u003d utils.diff_list_of_dict(old_routes,"},{"line_number":296,"context_line":"                                                 routes)"},{"line_number":297,"context_line":"        LOG.debug(\u0027added routes is %s\u0027 % added)"},{"line_number":298,"context_line":"        for hashed_route in added:"},{"line_number":299,"context_line":"            route \u003d utils.unhash_dict(hashed_route)"},{"line_number":300,"context_line":"            router_routes \u003d RouterRoute("}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2Fe1M%3D","line":297,"updated":"2013-01-19 11:49:19.000000000","message":"LOG.debug(_(\u0027Added routes is %s\u0027), added)","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":294,"context_line":"        old_routes \u003d self._make_router_route_dict(router)"},{"line_number":295,"context_line":"        added, removed \u003d utils.diff_list_of_dict(old_routes,"},{"line_number":296,"context_line":"                                                 routes)"},{"line_number":297,"context_line":"        LOG.debug(\u0027added routes is %s\u0027 % added)"},{"line_number":298,"context_line":"        for hashed_route in added:"},{"line_number":299,"context_line":"            route \u003d utils.unhash_dict(hashed_route)"},{"line_number":300,"context_line":"            router_routes \u003d RouterRoute("}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FdCs%3D","line":297,"in_reply_to":"AAAAM3%2F%2Fe1M%3D","updated":"2013-01-22 08:27:04.000000000","message":"Done","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"04dd2d83201c28c7a123ab54ceb678b8af388cc8","unresolved":false,"context_lines":[{"line_number":303,"context_line":"                nexthop\u003droute[\u0027nexthop\u0027])"},{"line_number":304,"context_line":"            context.session.add(router_routes)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"        LOG.debug(\u0027removed routes is %s\u0027 % removed)"},{"line_number":307,"context_line":"        for hashed_route in removed:"},{"line_number":308,"context_line":"            route \u003d utils.unhash_dict(hashed_route)"},{"line_number":309,"context_line":"            del_context \u003d context.session.query(RouterRoute)"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2Fe1Q%3D","line":306,"updated":"2013-01-19 11:49:19.000000000","message":"LOG.debug(_(\u0027Removed routes is %s\u0027), removed)","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":303,"context_line":"                nexthop\u003droute[\u0027nexthop\u0027])"},{"line_number":304,"context_line":"            context.session.add(router_routes)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"        LOG.debug(\u0027removed routes is %s\u0027 % removed)"},{"line_number":307,"context_line":"        for hashed_route in removed:"},{"line_number":308,"context_line":"            route \u003d utils.unhash_dict(hashed_route)"},{"line_number":309,"context_line":"            del_context \u003d context.session.query(RouterRoute)"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2FdCo%3D","line":306,"in_reply_to":"AAAAM3%2F%2Fe1Q%3D","updated":"2013-01-22 08:27:04.000000000","message":"Done","commit_id":"f479f0b89f900490e79c4453ec4d984fe7a91a54"}],"quantum/db/migration/alembic_migrations/versions/1c33fa3cd1a1_extra_route_config.py":[{"author":{"_account_id":447,"name":"dan wendlandt","email":"dan@nicira.com","username":"danwent"},"unresolved":false,"context_lines":[{"line_number":33,"context_line":"    \u0027quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2\u0027,"},{"line_number":34,"context_line":"    \u0027quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2\u0027,"},{"line_number":35,"context_line":"    \u0027quantum.plugins.nec.nec_plugin.NECPluginV2\u0027,"},{"line_number":36,"context_line":"    \u0027quantum.plugins.ryu.ryu_quantum_plugin.RyuQuantumPluginV2\u0027"},{"line_number":37,"context_line":"]"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"from alembic import op"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2FIrQ%3D","line":36,"updated":"2013-02-06 00:06:39.000000000","message":"does meta plugin need to be here?","commit_id":"dca18f93927f6d211f3f30a2b6ed9125be2e6a4a"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":33,"context_line":"    \u0027quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2\u0027,"},{"line_number":34,"context_line":"    \u0027quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2\u0027,"},{"line_number":35,"context_line":"    \u0027quantum.plugins.nec.nec_plugin.NECPluginV2\u0027,"},{"line_number":36,"context_line":"    \u0027quantum.plugins.ryu.ryu_quantum_plugin.RyuQuantumPluginV2\u0027"},{"line_number":37,"context_line":"]"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"from alembic import op"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2FIm4%3D","line":36,"in_reply_to":"AAAAM3%2F%2FIrQ%3D","updated":"2013-02-06 00:43:28.000000000","message":"Done","commit_id":"dca18f93927f6d211f3f30a2b6ed9125be2e6a4a"}],"quantum/db/models_v2.py":[{"author":{"_account_id":447,"name":"dan wendlandt","email":"dan@nicira.com","username":"danwent"},"unresolved":false,"context_lines":[{"line_number":95,"context_line":"class Route(object):"},{"line_number":96,"context_line":"    \"\"\"mixin of a route.\"\"\""},{"line_number":97,"context_line":"    destination \u003d sa.Column(sa.String(64), nullable\u003dFalse, primary_key\u003dTrue)"},{"line_number":98,"context_line":"    nexthop \u003d sa.Column(sa.String(64), nullable\u003dFalse, primary_key\u003dTrue)"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"class SubnetRoute(model_base.BASEV2, Route):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2FIrA%3D","line":98,"updated":"2013-02-06 00:06:39.000000000","message":"i never noticed before that this field was not nullable.  How do we enable a \"null route\" (aka a blackhole route)?  That doesn\u0027t seem to be covered here, but can be quite useful.","commit_id":"dca18f93927f6d211f3f30a2b6ed9125be2e6a4a"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":95,"context_line":"class Route(object):"},{"line_number":96,"context_line":"    \"\"\"mixin of a route.\"\"\""},{"line_number":97,"context_line":"    destination \u003d sa.Column(sa.String(64), nullable\u003dFalse, primary_key\u003dTrue)"},{"line_number":98,"context_line":"    nexthop \u003d sa.Column(sa.String(64), nullable\u003dFalse, primary_key\u003dTrue)"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"class SubnetRoute(model_base.BASEV2, Route):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2FInM%3D","line":98,"in_reply_to":"AAAAM3%2F%2FIrA%3D","updated":"2013-02-06 00:43:28.000000000","message":"I agree, however this support should be in another patch since host_route on subnet may affect.","commit_id":"dca18f93927f6d211f3f30a2b6ed9125be2e6a4a"}],"quantum/extensions/extraroute.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Copyright 2012, Nachi Ueno, NTT MCL, Inc."},{"line_number":4,"context_line":"# All Rights Reserved."},{"line_number":5,"context_line":"#"},{"line_number":6,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMbg%3D","line":3,"updated":"2013-02-04 07:06:35.000000000","message":"2013","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"# Extra Routes Exceptions"},{"line_number":29,"context_line":"class InvalidRoutes(qexception.InvalidInput):"},{"line_number":30,"context_line":"    message \u003d _(\"Routes %(routes)s is invalid format\")"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class OperationNotSupported(qexception.InvalidInput):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMZA%3D","line":30,"updated":"2013-02-04 07:06:35.000000000","message":"\"Routes .. are\" or \"Route ... is\"","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"# Extra Routes Exceptions"},{"line_number":29,"context_line":"class InvalidRoutes(qexception.InvalidInput):"},{"line_number":30,"context_line":"    message \u003d _(\"Routes %(routes)s is invalid format\")"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class OperationNotSupported(qexception.InvalidInput):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLQI%3D","line":30,"in_reply_to":"AAAAM3%2F%2FMZA%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class OperationNotSupported(qexception.InvalidInput):"},{"line_number":34,"context_line":"    message \u003d _(\"Only Update is allowd\")"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"class RouterInterfaceInUseByRoute(qexception.InUse):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMY8%3D","line":34,"updated":"2013-02-04 07:06:35.000000000","message":"Update -\u003e update\nallowd -\u003e allowed","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class OperationNotSupported(qexception.InvalidInput):"},{"line_number":34,"context_line":"    message \u003d _(\"Only Update is allowd\")"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"class RouterInterfaceInUseByRoute(qexception.InUse):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLQE%3D","line":34,"in_reply_to":"AAAAM3%2F%2FMY8%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"class RoutesAlreadyExsists(qexception.InvalidInput):"},{"line_number":44,"context_line":"    message \u003d _(\"Routes have already exsists. Please update\")"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"class RoutesExhausted(qexception.BadRequest):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMY4%3D","line":44,"updated":"2013-02-04 07:06:35.000000000","message":"Should \"Routes\" singular or plural? To me, \"A route already exists\" is reasonable.\n\n\"Please update\" -\u003e \"Please update the existing one.\"","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"class RoutesAlreadyExsists(qexception.InvalidInput):"},{"line_number":44,"context_line":"    message \u003d _(\"Routes have already exsists. Please update\")"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"class RoutesExhausted(qexception.BadRequest):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLPw%3D","line":44,"in_reply_to":"AAAAM3%2F%2FMY4%3D","updated":"2013-02-04 20:59:49.000000000","message":"This method is not used now, so removed.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":52,"context_line":"RESOURCE_ATTRIBUTE_MAP \u003d {"},{"line_number":53,"context_line":"    \u0027extra-routes\u0027: {"},{"line_number":54,"context_line":"        # id should be router_id"},{"line_number":55,"context_line":"        \u0027id\u0027: {\u0027allow_post\u0027: False, \u0027allow_put\u0027: False,"},{"line_number":56,"context_line":"               \u0027validate\u0027: {\u0027type:uuid\u0027: None},"},{"line_number":57,"context_line":"               \u0027is_visible\u0027: True},"},{"line_number":58,"context_line":"        \u0027routes\u0027: {\u0027allow_post\u0027: True, \u0027allow_put\u0027: True,"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMYA%3D","line":55,"updated":"2013-02-04 07:06:35.000000000","message":"Is router_id a better name of the attribute?","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":52,"context_line":"RESOURCE_ATTRIBUTE_MAP \u003d {"},{"line_number":53,"context_line":"    \u0027extra-routes\u0027: {"},{"line_number":54,"context_line":"        # id should be router_id"},{"line_number":55,"context_line":"        \u0027id\u0027: {\u0027allow_post\u0027: False, \u0027allow_put\u0027: False,"},{"line_number":56,"context_line":"               \u0027validate\u0027: {\u0027type:uuid\u0027: None},"},{"line_number":57,"context_line":"               \u0027is_visible\u0027: True},"},{"line_number":58,"context_line":"        \u0027routes\u0027: {\u0027allow_post\u0027: True, \u0027allow_put\u0027: True,"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLPk%3D","line":55,"in_reply_to":"AAAAM3%2F%2FMYA%3D","updated":"2013-02-04 20:59:49.000000000","message":"done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    @classmethod"},{"line_number":68,"context_line":"    def get_name(cls):"},{"line_number":69,"context_line":"        return \"Quantum Extra Route Configration for L3\""},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    @classmethod"},{"line_number":72,"context_line":"    def get_alias(cls):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMY0%3D","line":69,"updated":"2013-02-04 07:06:35.000000000","message":"The name should be more simple.\nPlease check the return value of \"quantum ext-list\".","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    @classmethod"},{"line_number":76,"context_line":"    def get_description(cls):"},{"line_number":77,"context_line":"        return \"Extra routes configration for L3\""},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    @classmethod"},{"line_number":80,"context_line":"    def get_namespace(cls):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMYw%3D","line":77,"updated":"2013-02-04 07:06:35.000000000","message":"configration -\u003e configuration\nL3 -\u003e L3 router","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":97,"context_line":"        controller \u003d base.create_resource(collection_name,"},{"line_number":98,"context_line":"                                          resource_name,"},{"line_number":99,"context_line":"                                          plugin, params,"},{"line_number":100,"context_line":"                                          member_actions\u003dmember_actions)"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"        ex \u003d extensions.ResourceExtension(collection_name,"},{"line_number":103,"context_line":"                                          controller,"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMYs%3D","line":100,"updated":"2013-02-04 07:06:35.000000000","message":"member_actions is not required since this extension defines no extra actions.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":101,"context_line":""},{"line_number":102,"context_line":"        ex \u003d extensions.ResourceExtension(collection_name,"},{"line_number":103,"context_line":"                                          controller,"},{"line_number":104,"context_line":"                                          member_actions\u003dmember_actions)"},{"line_number":105,"context_line":"        exts.append(ex)"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        return exts"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMYo%3D","line":104,"updated":"2013-02-04 07:06:35.000000000","message":"Same as the above.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":101,"context_line":""},{"line_number":102,"context_line":"        ex \u003d extensions.ResourceExtension(collection_name,"},{"line_number":103,"context_line":"                                          controller,"},{"line_number":104,"context_line":"                                          member_actions\u003dmember_actions)"},{"line_number":105,"context_line":"        exts.append(ex)"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        return exts"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLPQ%3D","line":104,"in_reply_to":"AAAAM3%2F%2FMYo%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":104,"context_line":"                                          member_actions\u003dmember_actions)"},{"line_number":105,"context_line":"        exts.append(ex)"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        return exts"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"class ExtraRoutePluginBase(object):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMYk%3D","line":107,"updated":"2013-02-04 07:06:35.000000000","message":"just return \"[ex]\"","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":104,"context_line":"                                          member_actions\u003dmember_actions)"},{"line_number":105,"context_line":"        exts.append(ex)"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        return exts"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"class ExtraRoutePluginBase(object):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLPM%3D","line":107,"in_reply_to":"AAAAM3%2F%2FMYk%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":124,"context_line":"        raise OperationNotSupported()"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    @abstractmethod"},{"line_number":127,"context_line":"    def get_extra_routes(self, context, filters\u003dNone, fields\u003dNone):"},{"line_number":128,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMVs%3D","line":127,"updated":"2013-02-04 07:06:35.000000000","message":"I am not sure we need a list command to display all routes of all routers in a tenant.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":124,"context_line":"        raise OperationNotSupported()"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    @abstractmethod"},{"line_number":127,"context_line":"    def get_extra_routes(self, context, filters\u003dNone, fields\u003dNone):"},{"line_number":128,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLPE%3D","line":127,"in_reply_to":"AAAAM3%2F%2FMVs%3D","updated":"2013-02-04 20:59:49.000000000","message":"I removed this fucntion.","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":447,"name":"dan wendlandt","email":"dan@nicira.com","username":"danwent"},"unresolved":false,"context_lines":[{"line_number":57,"context_line":"        \u0027tenant_id\u0027: {\u0027allow_post\u0027: True, \u0027allow_put\u0027: False,"},{"line_number":58,"context_line":"                      \u0027required_by_policy\u0027: True,"},{"line_number":59,"context_line":"                      \u0027validate\u0027: {\u0027type:string\u0027: None},"},{"line_number":60,"context_line":"                      \u0027is_visible\u0027: True}"},{"line_number":61,"context_line":"    },"},{"line_number":62,"context_line":"}"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2FIsE%3D","line":60,"updated":"2013-02-06 00:06:39.000000000","message":"as we talked about on email, this should really be an attribute of a router itself.  I think you\u0027re just doing it this way because right now you can\u0027t guarantee that this extension loads after the existing L3 extension?   Do you agree that long term this extension should go away in favor of one that extends the router attribute itself?  I\u0027m not in favor of this patch if this is the proposed long-term model.","commit_id":"dca18f93927f6d211f3f30a2b6ed9125be2e6a4a"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":57,"context_line":"        \u0027tenant_id\u0027: {\u0027allow_post\u0027: True, \u0027allow_put\u0027: False,"},{"line_number":58,"context_line":"                      \u0027required_by_policy\u0027: True,"},{"line_number":59,"context_line":"                      \u0027validate\u0027: {\u0027type:string\u0027: None},"},{"line_number":60,"context_line":"                      \u0027is_visible\u0027: True}"},{"line_number":61,"context_line":"    },"},{"line_number":62,"context_line":"}"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2FInc%3D","line":60,"in_reply_to":"AAAAM3%2F%2FIsE%3D","updated":"2013-02-06 00:43:28.000000000","message":"I agree with you. I update this patch with https://review.openstack.org/#/c/21265/ after the patch merged.","commit_id":"dca18f93927f6d211f3f30a2b6ed9125be2e6a4a"},{"author":{"_account_id":447,"name":"dan wendlandt","email":"dan@nicira.com","username":"danwent"},"unresolved":false,"context_lines":[{"line_number":103,"context_line":"class ExtraRoutePluginBase(object):"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def create_extra_route(self, context, extra_routes):"},{"line_number":106,"context_line":"        raise OperationNotSupported()"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"    @abstractmethod"},{"line_number":109,"context_line":"    def update_extra_route(self, context, id, extra_routes):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2FIr4%3D","line":106,"updated":"2013-02-06 00:06:39.000000000","message":"these non-sensical CREATE/LIST/DELETE calls are probably another reason why it doesn\u0027t really make sense to have this as an extra attribute long-term.","commit_id":"dca18f93927f6d211f3f30a2b6ed9125be2e6a4a"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":103,"context_line":"class ExtraRoutePluginBase(object):"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def create_extra_route(self, context, extra_routes):"},{"line_number":106,"context_line":"        raise OperationNotSupported()"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"    @abstractmethod"},{"line_number":109,"context_line":"    def update_extra_route(self, context, id, extra_routes):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2FInU%3D","line":106,"in_reply_to":"AAAAM3%2F%2FIr4%3D","updated":"2013-02-06 00:43:28.000000000","message":"This problem will be removed if I use https://review.openstack.org/#/c/21265/","commit_id":"dca18f93927f6d211f3f30a2b6ed9125be2e6a4a"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"unresolved":false,"context_lines":[{"line_number":101,"context_line":""},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"class ExtraRoutePluginBase(object):"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def create_extra_route(self, context, extra_routes):"},{"line_number":106,"context_line":"        raise OperationNotSupported()"},{"line_number":107,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2FGm4%3D","line":104,"updated":"2013-02-07 02:16:06.000000000","message":"__metaclass__ \u003d ABCMeta?","commit_id":"4438e2215f415bf9b70f990425531cb665d41dce"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":101,"context_line":""},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"class ExtraRoutePluginBase(object):"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def create_extra_route(self, context, extra_routes):"},{"line_number":106,"context_line":"        raise OperationNotSupported()"},{"line_number":107,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2B%2BGE%3D","line":104,"in_reply_to":"AAAAM3%2F%2FGm4%3D","updated":"2013-02-12 21:28:30.000000000","message":"This class will be removed","commit_id":"4438e2215f415bf9b70f990425531cb665d41dce"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"# Extra Routes Exceptions"},{"line_number":29,"context_line":"class InvalidRoutes(qexception.InvalidInput):"},{"line_number":30,"context_line":"    message \u003d _(\"Routes %(routes)s are invalid format\")"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class OperationNotSupported(qexception.InvalidInput):"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxVk%3D","line":30,"updated":"2013-02-19 16:26:23.000000000","message":"Consider: Invalid format for routes: %(routes)s","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"# Extra Routes Exceptions"},{"line_number":29,"context_line":"class InvalidRoutes(qexception.InvalidInput):"},{"line_number":30,"context_line":"    message \u003d _(\"Routes %(routes)s are invalid format\")"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class OperationNotSupported(qexception.InvalidInput):"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxS0%3D","line":30,"in_reply_to":"AAAAM3%2F%2BxVk%3D","updated":"2013-02-19 16:45:29.000000000","message":"Done","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class OperationNotSupported(qexception.InvalidInput):"},{"line_number":34,"context_line":"    message \u003d _(\"Only Update and Show is allowed\")"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"class RouterInterfaceInUseByRoute(qexception.InUse):"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxVg%3D","line":34,"updated":"2013-02-19 16:26:23.000000000","message":"\u0027update\u0027 and \u0027show\u0027","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class OperationNotSupported(qexception.InvalidInput):"},{"line_number":34,"context_line":"    message \u003d _(\"Only Update and Show is allowed\")"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"class RouterInterfaceInUseByRoute(qexception.InUse):"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxTA%3D","line":34,"in_reply_to":"AAAAM3%2F%2BxVg%3D","updated":"2013-02-19 16:45:29.000000000","message":"This exception is not used, so I removed it","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":"class RoutesExhausted(qexception.BadRequest):"},{"line_number":44,"context_line":"    message \u003d _(\"Unable to complete operation for %(router_id)s. \""},{"line_number":45,"context_line":"                \"The number of routes exceeds the limit %(quota)s.\")"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"# Attribute Map"},{"line_number":48,"context_line":"EXTENDED_ATTRIBUTES_2_0 \u003d {"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxVY%3D","line":45,"updated":"2013-02-19 16:26:23.000000000","message":"limit \u003d\u003e maximum","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":"class RoutesExhausted(qexception.BadRequest):"},{"line_number":44,"context_line":"    message \u003d _(\"Unable to complete operation for %(router_id)s. \""},{"line_number":45,"context_line":"                \"The number of routes exceeds the limit %(quota)s.\")"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"# Attribute Map"},{"line_number":48,"context_line":"EXTENDED_ATTRIBUTES_2_0 \u003d {"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxSw%3D","line":45,"in_reply_to":"AAAAM3%2F%2BxVY%3D","updated":"2013-02-19 16:45:29.000000000","message":"Done","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"unresolved":false,"context_lines":[{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    @classmethod"},{"line_number":60,"context_line":"    def get_name(cls):"},{"line_number":61,"context_line":"        return \"Quantum Extra Route\""},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    @classmethod"},{"line_number":64,"context_line":"    def get_alias(cls):"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxVU%3D","line":61,"updated":"2013-02-19 16:26:23.000000000","message":"Additional Routes?","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    @classmethod"},{"line_number":60,"context_line":"    def get_name(cls):"},{"line_number":61,"context_line":"        return \"Quantum Extra Route\""},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    @classmethod"},{"line_number":64,"context_line":"    def get_alias(cls):"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxSg%3D","line":61,"in_reply_to":"AAAAM3%2F%2BxVU%3D","updated":"2013-02-19 16:45:29.000000000","message":"it is similar meanings :)","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    @classmethod"},{"line_number":64,"context_line":"    def get_description(cls):"},{"line_number":65,"context_line":"        return \"Extra routes configration for L3 router\""},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    @classmethod"},{"line_number":68,"context_line":"    def get_namespace(cls):"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BxOI%3D","line":65,"updated":"2013-02-19 17:24:58.000000000","message":"typo: configuration","commit_id":"9449e3cd04fa6ee6232e580a0c612ac219e90ec6"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    @classmethod"},{"line_number":64,"context_line":"    def get_description(cls):"},{"line_number":65,"context_line":"        return \"Extra routes configration for L3 router\""},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    @classmethod"},{"line_number":68,"context_line":"    def get_namespace(cls):"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BxEM%3D","line":65,"in_reply_to":"AAAAM3%2F%2BxOI%3D","updated":"2013-02-19 17:44:10.000000000","message":"Done","commit_id":"9449e3cd04fa6ee6232e580a0c612ac219e90ec6"},{"author":{"_account_id":490,"name":"Sumit Naiksatam","email":"sumitnaiksatam@gmail.com","username":"snaiksat"},"unresolved":false,"context_lines":[{"line_number":16,"context_line":"#    under the License."},{"line_number":17,"context_line":""},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from abc import abstractmethod"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from quantum.api import extensions"},{"line_number":22,"context_line":"from quantum.api.v2 import attributes as attr"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2Bw%2BU%3D","line":19,"updated":"2013-02-19 18:13:43.000000000","message":"unused","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":16,"context_line":"#    under the License."},{"line_number":17,"context_line":""},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from abc import abstractmethod"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from quantum.api import extensions"},{"line_number":22,"context_line":"from quantum.api.v2 import attributes as attr"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2Bw6A%3D","line":19,"in_reply_to":"AAAAM3%2F%2Bw%2BU%3D","updated":"2013-02-19 18:33:42.000000000","message":"Done","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"},{"author":{"_account_id":490,"name":"Sumit Naiksatam","email":"sumitnaiksatam@gmail.com","username":"snaiksat"},"unresolved":false,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from abc import abstractmethod"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from quantum.api import extensions"},{"line_number":22,"context_line":"from quantum.api.v2 import attributes as attr"},{"line_number":23,"context_line":"from quantum.api.v2 import base"},{"line_number":24,"context_line":"from quantum.common import exceptions as qexception"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2Bw%2BA%3D","line":21,"updated":"2013-02-19 18:13:43.000000000","message":"unused","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from abc import abstractmethod"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from quantum.api import extensions"},{"line_number":22,"context_line":"from quantum.api.v2 import attributes as attr"},{"line_number":23,"context_line":"from quantum.api.v2 import base"},{"line_number":24,"context_line":"from quantum.common import exceptions as qexception"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2Bw58%3D","line":21,"in_reply_to":"AAAAM3%2F%2Bw%2BA%3D","updated":"2013-02-19 18:33:42.000000000","message":"Done","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"},{"author":{"_account_id":490,"name":"Sumit Naiksatam","email":"sumitnaiksatam@gmail.com","username":"snaiksat"},"unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from quantum.api import extensions"},{"line_number":22,"context_line":"from quantum.api.v2 import attributes as attr"},{"line_number":23,"context_line":"from quantum.api.v2 import base"},{"line_number":24,"context_line":"from quantum.common import exceptions as qexception"},{"line_number":25,"context_line":"from quantum import manager"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2Bw%2BE%3D","line":23,"updated":"2013-02-19 18:13:43.000000000","message":"unused","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from quantum.api import extensions"},{"line_number":22,"context_line":"from quantum.api.v2 import attributes as attr"},{"line_number":23,"context_line":"from quantum.api.v2 import base"},{"line_number":24,"context_line":"from quantum.common import exceptions as qexception"},{"line_number":25,"context_line":"from quantum import manager"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2Bw54%3D","line":23,"in_reply_to":"AAAAM3%2F%2Bw%2BE%3D","updated":"2013-02-19 18:33:42.000000000","message":"Done","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"},{"author":{"_account_id":490,"name":"Sumit Naiksatam","email":"sumitnaiksatam@gmail.com","username":"snaiksat"},"unresolved":false,"context_lines":[{"line_number":22,"context_line":"from quantum.api.v2 import attributes as attr"},{"line_number":23,"context_line":"from quantum.api.v2 import base"},{"line_number":24,"context_line":"from quantum.common import exceptions as qexception"},{"line_number":25,"context_line":"from quantum import manager"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"# Extra Routes Exceptions"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2Bw%2BM%3D","line":25,"updated":"2013-02-19 18:13:43.000000000","message":"unused","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":22,"context_line":"from quantum.api.v2 import attributes as attr"},{"line_number":23,"context_line":"from quantum.api.v2 import base"},{"line_number":24,"context_line":"from quantum.common import exceptions as qexception"},{"line_number":25,"context_line":"from quantum import manager"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"# Extra Routes Exceptions"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAM3%2F%2Bw50%3D","line":25,"in_reply_to":"AAAAM3%2F%2Bw%2BM%3D","updated":"2013-02-19 18:33:42.000000000","message":"Done","commit_id":"2fe0266a6ecde7c26538b8eb7186eaf7883ba238"}],"quantum/tests/unit/test_extension_extraroute.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Copyright 2012, Nachi Ueno, NTT MCL, Inc."},{"line_number":4,"context_line":"# All Rights Reserved."},{"line_number":5,"context_line":"#"},{"line_number":6,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMbY%3D","line":3,"updated":"2013-02-04 07:06:35.000000000","message":"2013","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Copyright 2012, Nachi Ueno, NTT MCL, Inc."},{"line_number":4,"context_line":"# All Rights Reserved."},{"line_number":5,"context_line":"#"},{"line_number":6,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLOU%3D","line":3,"in_reply_to":"AAAAM3%2F%2FMbY%3D","updated":"2013-02-04 20:59:49.000000000","message":"Done","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"unresolved":false,"context_lines":[{"line_number":76,"context_line":"    def test_route_update_with_one_route(self):"},{"line_number":77,"context_line":"        with self.router() as r:"},{"line_number":78,"context_line":"            with self.subnet(cidr\u003d\u002710.0.1.0/24\u0027) as s:"},{"line_number":79,"context_line":"                with self.port(subnet\u003ds, no_delete\u003dTrue) as p:"},{"line_number":80,"context_line":"                    body \u003d self._show(\u0027extra-routes\u0027, r[\u0027router\u0027][\u0027id\u0027])"},{"line_number":81,"context_line":"                    body \u003d self._router_interface_action(\u0027add\u0027,"},{"line_number":82,"context_line":"                                                         r[\u0027router\u0027][\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FMbU%3D","line":79,"updated":"2013-02-04 07:06:35.000000000","message":"Why is no_delete required?","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":76,"context_line":"    def test_route_update_with_one_route(self):"},{"line_number":77,"context_line":"        with self.router() as r:"},{"line_number":78,"context_line":"            with self.subnet(cidr\u003d\u002710.0.1.0/24\u0027) as s:"},{"line_number":79,"context_line":"                with self.port(subnet\u003ds, no_delete\u003dTrue) as p:"},{"line_number":80,"context_line":"                    body \u003d self._show(\u0027extra-routes\u0027, r[\u0027router\u0027][\u0027id\u0027])"},{"line_number":81,"context_line":"                    body \u003d self._router_interface_action(\u0027add\u0027,"},{"line_number":82,"context_line":"                                                         r[\u0027router\u0027][\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2FLOQ%3D","line":79,"in_reply_to":"AAAAM3%2F%2FMbU%3D","updated":"2013-02-04 20:59:49.000000000","message":"because the port is deleted on line 99","commit_id":"f5b10a380f53e7276d36b2dcb9b92ea68030e671"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"unresolved":false,"context_lines":[{"line_number":96,"context_line":"                                      routes)"},{"line_number":97,"context_line":"                    self._update(\u0027routers\u0027, r[\u0027router\u0027][\u0027id\u0027],"},{"line_number":98,"context_line":"                                 {\u0027router\u0027: {\u0027routes\u0027: []}})"},{"line_number":99,"context_line":"                    # clean-up"},{"line_number":100,"context_line":"                    self._router_interface_action(\u0027remove\u0027,"},{"line_number":101,"context_line":"                                                  r[\u0027router\u0027][\u0027id\u0027],"},{"line_number":102,"context_line":"                                                  None,"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2ByJQ%3D","line":99,"updated":"2013-02-19 11:12:00.000000000","message":"Clean-up should be done in tearDown method.\nOtherwise error(or fail) in this test affects other tests.\n\nsome for the following tests.","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"unresolved":false,"context_lines":[{"line_number":96,"context_line":"                                      routes)"},{"line_number":97,"context_line":"                    self._update(\u0027routers\u0027, r[\u0027router\u0027][\u0027id\u0027],"},{"line_number":98,"context_line":"                                 {\u0027router\u0027: {\u0027routes\u0027: []}})"},{"line_number":99,"context_line":"                    # clean-up"},{"line_number":100,"context_line":"                    self._router_interface_action(\u0027remove\u0027,"},{"line_number":101,"context_line":"                                                  r[\u0027router\u0027][\u0027id\u0027],"},{"line_number":102,"context_line":"                                                  None,"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BxhI%3D","line":99,"in_reply_to":"AAAAM3%2F%2ByJQ%3D","updated":"2013-02-19 15:34:36.000000000","message":"In order to delete router with \u0027with statement\u0027, we should delete the port here. If we faild to do that, the tests will fail, so there are no problem here. This is also same style with another l3 tests","commit_id":"649c4f2036385f9cb8174b6faddcdd87520abfe1"}]}
