)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"eb31958d25ab0d133ee96d06ef0e6ac1b1f96b70","unresolved":false,"context_lines":[{"line_number":16,"context_line":"ApiImpact"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Implements: blueprint specify-router-ext-ip"},{"line_number":19,"context_line":"Partial-Bug: #1188427"},{"line_number":20,"context_line":"Change-Id: Iba7c606eea48181fc10e9d0d5dc667e6f48f37de"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"5a890539_6edbb97d","line":19,"updated":"2014-11-28 12:17:21.000000000","message":"Why only Partial-Bug?","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"9d7cd1480b5e824df7c30331a2be6530822e277b","unresolved":false,"context_lines":[{"line_number":16,"context_line":"ApiImpact"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Implements: blueprint specify-router-ext-ip"},{"line_number":19,"context_line":"Partial-Bug: #1188427"},{"line_number":20,"context_line":"Change-Id: Iba7c606eea48181fc10e9d0d5dc667e6f48f37de"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"5a890539_9bb6c023","line":19,"in_reply_to":"5a890539_6edbb97d","updated":"2014-12-04 08:55:39.000000000","message":"whoops, fixed","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"}],"etc/policy.json":[{"author":{"_account_id":6854,"name":"YAMAMOTO Takashi","email":"yamamoto@midokura.com","username":"yamamoto"},"change_message_id":"50aef3823bc919ee3202c07665fa4c85ff5cac21","unresolved":false,"context_lines":[{"line_number":76,"context_line":"    \"remove_router_interface\": \"rule:admin_or_owner\","},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    \"create_router:external_gateway_info:external_fixed_ips\": \"rule:admin_only\","},{"line_number":79,"context_line":"    \"update_router:external_gateway_info:external_fixed_ips\": \"rule:admin_only\","},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    \"create_firewall\": \"\","},{"line_number":82,"context_line":"    \"get_firewall\": \"rule:admin_or_owner\","}],"source_content_type":"application/json","patch_set":19,"id":"fa98f980_3b903295","line":79,"updated":"2014-09-01 08:46:12.000000000","message":"this seems to make tempest.api.network.test_routers.RoutersTest.test_create_show_list_update_delete_router failed","commit_id":"f5a88a1b9da52e19c966c909c5cf3d27109e7c65"}],"neutron/db/l3_db.py":[{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"bb152f78ee25d5c9702dde61ae28ae46059e4f4f","unresolved":false,"context_lines":[{"line_number":160,"context_line":"        else:"},{"line_number":161,"context_line":"            fixed_ips \u003d attributes.ATTR_NOT_SPECIFIED"},{"line_number":162,"context_line":"        # Port has no \u0027tenant-id\u0027, as it is hidden from user"},{"line_number":163,"context_line":"        gw_port \u003d self._core_plugin.create_port(context.elevated(), {"},{"line_number":164,"context_line":"            \u0027port\u0027: {\u0027tenant_id\u0027: \u0027\u0027,  # intentionally not set"},{"line_number":165,"context_line":"                     \u0027network_id\u0027: network_id,"},{"line_number":166,"context_line":"                     \u0027mac_address\u0027: attributes.ATTR_NOT_SPECIFIED,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAWH%2F%2BO6A%3D","line":163,"updated":"2014-03-28 08:11:05.000000000","message":"Need to handle possible ip address validation/overlap errors here","commit_id":"5d964ffcfe351744d4fc8a65e04f03db8815da80"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"a3e6b90d4f22ca2c26302fb9b4fb34af5950622b","unresolved":false,"context_lines":[{"line_number":160,"context_line":"        else:"},{"line_number":161,"context_line":"            fixed_ips \u003d attributes.ATTR_NOT_SPECIFIED"},{"line_number":162,"context_line":"        # Port has no \u0027tenant-id\u0027, as it is hidden from user"},{"line_number":163,"context_line":"        gw_port \u003d self._core_plugin.create_port(context.elevated(), {"},{"line_number":164,"context_line":"            \u0027port\u0027: {\u0027tenant_id\u0027: \u0027\u0027,  # intentionally not set"},{"line_number":165,"context_line":"                     \u0027network_id\u0027: network_id,"},{"line_number":166,"context_line":"                     \u0027mac_address\u0027: attributes.ATTR_NOT_SPECIFIED,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAWH%2F%2BKf4%3D","line":163,"in_reply_to":"AAAAWH%2F%2BO6A%3D","updated":"2014-03-28 17:35:10.000000000","message":"That\u0027s handled in the port_create request on the plugin side, right? \n\nI already have a unit test that is testing an IP in the incorrect subnet that is exercising that.","commit_id":"5d964ffcfe351744d4fc8a65e04f03db8815da80"},{"author":{"_account_id":2592,"name":"Mark McClain","email":"mark@mcclain.xyz","username":"markmcclain"},"change_message_id":"87ee60f9f0b74981c7be062856dcd3e01be7144f","unresolved":false,"context_lines":[{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    def _create_router_gw_port(self, context, router, network_id, ext_ips):"},{"line_number":239,"context_line":"        if ext_ips:"},{"line_number":240,"context_line":"            if len(ext_ips) \u003e 1:"},{"line_number":241,"context_line":"                msg \u003d _(\"Routers currently support only 1 external IP\")"},{"line_number":242,"context_line":"                raise n_exc.BadRequest(resource\u003d\u0027router\u0027, msg\u003dmsg)"},{"line_number":243,"context_line":"            fixed_ips \u003d [{\u0027ip_address\u0027: ext_ip} for ext_ip in ext_ips]"}],"source_content_type":"text/x-python","patch_set":13,"id":"1ae5cdf2_caccffbd","line":240,"updated":"2014-06-05 17:48:50.000000000","message":"why accept a list via the api then?","commit_id":"d3887d2de9c03136f1182d1784b5e146af621d04"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"b26c1cb9ce4e9e64774a3b99930a8a6d24a881ed","unresolved":false,"context_lines":[{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    def _create_router_gw_port(self, context, router, network_id, ext_ips):"},{"line_number":239,"context_line":"        if ext_ips:"},{"line_number":240,"context_line":"            if len(ext_ips) \u003e 1:"},{"line_number":241,"context_line":"                msg \u003d _(\"Routers currently support only 1 external IP\")"},{"line_number":242,"context_line":"                raise n_exc.BadRequest(resource\u003d\u0027router\u0027, msg\u003dmsg)"},{"line_number":243,"context_line":"            fixed_ips \u003d [{\u0027ip_address\u0027: ext_ip} for ext_ip in ext_ips]"}],"source_content_type":"text/x-python","patch_set":13,"id":"1ae5cdf2_9c3ddd91","line":240,"in_reply_to":"1ae5cdf2_caccffbd","updated":"2014-06-05 20:24:22.000000000","message":"Expecting multiple once DVR is implemented.","commit_id":"d3887d2de9c03136f1182d1784b5e146af621d04"},{"author":{"_account_id":2592,"name":"Mark McClain","email":"mark@mcclain.xyz","username":"markmcclain"},"change_message_id":"87ee60f9f0b74981c7be062856dcd3e01be7144f","unresolved":false,"context_lines":[{"line_number":283,"context_line":"                        \"network\") % network_id"},{"line_number":284,"context_line":"                raise n_exc.BadRequest(resource\u003d\u0027router\u0027, msg\u003dmsg)"},{"line_number":285,"context_line":"            if ext_ips:"},{"line_number":286,"context_line":"                subnets \u003d self._core_plugin._get_subnets_by_network(context,"},{"line_number":287,"context_line":"                                                                    network_id)"},{"line_number":288,"context_line":"                for s in subnets:"},{"line_number":289,"context_line":"                    for ext_ip in ext_ips:"}],"source_content_type":"text/x-python","patch_set":13,"id":"1ae5cdf2_eac61b99","line":286,"updated":"2014-06-05 17:48:50.000000000","message":"network_db is a db object, so you can use\nfor s in network_db.subnets:","commit_id":"d3887d2de9c03136f1182d1784b5e146af621d04"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"b26c1cb9ce4e9e64774a3b99930a8a6d24a881ed","unresolved":false,"context_lines":[{"line_number":283,"context_line":"                        \"network\") % network_id"},{"line_number":284,"context_line":"                raise n_exc.BadRequest(resource\u003d\u0027router\u0027, msg\u003dmsg)"},{"line_number":285,"context_line":"            if ext_ips:"},{"line_number":286,"context_line":"                subnets \u003d self._core_plugin._get_subnets_by_network(context,"},{"line_number":287,"context_line":"                                                                    network_id)"},{"line_number":288,"context_line":"                for s in subnets:"},{"line_number":289,"context_line":"                    for ext_ip in ext_ips:"}],"source_content_type":"text/x-python","patch_set":13,"id":"1ae5cdf2_fc4d013f","line":286,"in_reply_to":"1ae5cdf2_eac61b99","updated":"2014-06-05 20:24:22.000000000","message":"Cool. Will update once the blueprint is approved.","commit_id":"d3887d2de9c03136f1182d1784b5e146af621d04"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"c2c08a1a0cfdcc0dda496b4b1c77e49058c753db","unresolved":false,"context_lines":[{"line_number":282,"context_line":"                raise n_exc.BadRequest(resource\u003d\u0027router\u0027, msg\u003dmsg)"},{"line_number":283,"context_line":"        if ext_ips:"},{"line_number":284,"context_line":"            subnets \u003d self._core_plugin._get_subnets_by_network(context,"},{"line_number":285,"context_line":"                                                                network_id)"},{"line_number":286,"context_line":"            for s in subnets:"},{"line_number":287,"context_line":"                if not s[\u0027gateway_ip\u0027]:"},{"line_number":288,"context_line":"                    continue"}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_5136f751","line":285,"updated":"2014-06-20 04:33:39.000000000","message":"what happened if network_id is None?","commit_id":"9da7ec27497627152fa26d3e091844a051086c75"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"5e4329890af86a5ddcb08354ee38b8e7f2892636","unresolved":false,"context_lines":[{"line_number":282,"context_line":"                raise n_exc.BadRequest(resource\u003d\u0027router\u0027, msg\u003dmsg)"},{"line_number":283,"context_line":"        if ext_ips:"},{"line_number":284,"context_line":"            subnets \u003d self._core_plugin._get_subnets_by_network(context,"},{"line_number":285,"context_line":"                                                                network_id)"},{"line_number":286,"context_line":"            for s in subnets:"},{"line_number":287,"context_line":"                if not s[\u0027gateway_ip\u0027]:"},{"line_number":288,"context_line":"                    continue"}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_9e832755","line":285,"in_reply_to":"1ae5cdf2_5136f751","updated":"2014-06-20 10:48:40.000000000","message":"Good catch. I need to skip this if network_id is none.","commit_id":"9da7ec27497627152fa26d3e091844a051086c75"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"c2c08a1a0cfdcc0dda496b4b1c77e49058c753db","unresolved":false,"context_lines":[{"line_number":349,"context_line":"    def _check_for_external_ip_change(self, context, gw_port, ext_ips):"},{"line_number":350,"context_line":"        # determine if new external IPs differ from the existing fixed_ips"},{"line_number":351,"context_line":"        if not ext_ips:"},{"line_number":352,"context_line":"            return False"},{"line_number":353,"context_line":"        if not gw_port:"},{"line_number":354,"context_line":"            return True"},{"line_number":355,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_11cc6f34","line":352,"updated":"2014-06-20 04:33:39.000000000","message":"add a NOTE to say if not ext_ips, which means we don\u0027t input the ext ip.","commit_id":"9da7ec27497627152fa26d3e091844a051086c75"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"5e4329890af86a5ddcb08354ee38b8e7f2892636","unresolved":false,"context_lines":[{"line_number":349,"context_line":"    def _check_for_external_ip_change(self, context, gw_port, ext_ips):"},{"line_number":350,"context_line":"        # determine if new external IPs differ from the existing fixed_ips"},{"line_number":351,"context_line":"        if not ext_ips:"},{"line_number":352,"context_line":"            return False"},{"line_number":353,"context_line":"        if not gw_port:"},{"line_number":354,"context_line":"            return True"},{"line_number":355,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_7e5adb1e","line":352,"in_reply_to":"1ae5cdf2_11cc6f34","updated":"2014-06-20 10:48:40.000000000","message":"Done","commit_id":"9da7ec27497627152fa26d3e091844a051086c75"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"c2c08a1a0cfdcc0dda496b4b1c77e49058c753db","unresolved":false,"context_lines":[{"line_number":363,"context_line":"        if ip_address in [f[\u0027ip_address\u0027]"},{"line_number":364,"context_line":"                          for f in ext_ips"},{"line_number":365,"context_line":"                          if f.get(\u0027ip_address\u0027)]:"},{"line_number":366,"context_line":"            fixed_change \u003d False"},{"line_number":367,"context_line":"        return fixed_change"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"    def _ensure_router_not_in_use(self, context, router_id):"}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_11654f44","line":366,"updated":"2014-06-20 04:33:39.000000000","message":"so the ext_ips must contain subnet_id and ip_address at the same time. Does the validation in attr can guarantee this?","commit_id":"9da7ec27497627152fa26d3e091844a051086c75"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"5e4329890af86a5ddcb08354ee38b8e7f2892636","unresolved":false,"context_lines":[{"line_number":363,"context_line":"        if ip_address in [f[\u0027ip_address\u0027]"},{"line_number":364,"context_line":"                          for f in ext_ips"},{"line_number":365,"context_line":"                          if f.get(\u0027ip_address\u0027)]:"},{"line_number":366,"context_line":"            fixed_change \u003d False"},{"line_number":367,"context_line":"        return fixed_change"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"    def _ensure_router_not_in_use(self, context, router_id):"}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_3b6ea596","line":366,"in_reply_to":"1ae5cdf2_11654f44","updated":"2014-06-20 10:48:40.000000000","message":"No, it doesn\u0027t have to. That\u0027s why it uses f.get() to check for it\u0027s existence","commit_id":"9da7ec27497627152fa26d3e091844a051086c75"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"change_message_id":"ed66e7450cd2b525035a045ab85731d851d66c3f","unresolved":false,"context_lines":[{"line_number":344,"context_line":"        self._delete_current_gw_port(context, router_id, router, network_id,"},{"line_number":345,"context_line":"                                     ext_ip_change)"},{"line_number":346,"context_line":"        self._create_gw_port(context, router_id, router, network_id, ext_ips,"},{"line_number":347,"context_line":"                             ext_ip_change)"},{"line_number":348,"context_line":""},{"line_number":349,"context_line":"    def _check_for_external_ip_change(self, context, gw_port, ext_ips):"},{"line_number":350,"context_line":"        # determine if new external IPs differ from the existing fixed_ips"}],"source_content_type":"text/x-python","patch_set":17,"id":"1abeadc6_dd02c46e","line":347,"updated":"2014-08-25 16:40:56.000000000","message":"How agent can know this change?","commit_id":"39f39a7f19c1a5596fe6af024c077e2a1867b9a9"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"ba2b96040a84d3be474010be881ea2c60c55691f","unresolved":false,"context_lines":[{"line_number":280,"context_line":"                    for ext_ip in ext_ips:"},{"line_number":281,"context_line":"                        if ext_ip.get(\u0027ip_address\u0027) \u003d\u003d s[\u0027gateway_ip\u0027]:"},{"line_number":282,"context_line":"                            msg \u003d _(\"External IP %s overlaps with \""},{"line_number":283,"context_line":"                                    \"gateway IP\") % ext_ip.get(\u0027ip_address\u0027)"},{"line_number":284,"context_line":"                            raise n_exc.BadRequest(resource\u003d\u0027router\u0027, msg\u003dmsg)"},{"line_number":285,"context_line":"        return network_id"},{"line_number":286,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"fa98f980_9c92e355","line":283,"updated":"2014-09-01 15:57:43.000000000","message":"I know CIDRs can overlap, but I honestly don\u0027t know how two IP addresses can overlap without being identical","commit_id":"f5a88a1b9da52e19c966c909c5cf3d27109e7c65"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e4bc4be80094f5a34c35e80db1900f06c0c1f53e","unresolved":false,"context_lines":[{"line_number":280,"context_line":"                    for ext_ip in ext_ips:"},{"line_number":281,"context_line":"                        if ext_ip.get(\u0027ip_address\u0027) \u003d\u003d s[\u0027gateway_ip\u0027]:"},{"line_number":282,"context_line":"                            msg \u003d _(\"External IP %s overlaps with \""},{"line_number":283,"context_line":"                                    \"gateway IP\") % ext_ip.get(\u0027ip_address\u0027)"},{"line_number":284,"context_line":"                            raise n_exc.BadRequest(resource\u003d\u0027router\u0027, msg\u003dmsg)"},{"line_number":285,"context_line":"        return network_id"},{"line_number":286,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"fa98f980_840df939","line":283,"in_reply_to":"fa98f980_9c92e355","updated":"2014-09-02 09:28:44.000000000","message":"identical is just a subset of overlapping :-)","commit_id":"f5a88a1b9da52e19c966c909c5cf3d27109e7c65"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"ba2b96040a84d3be474010be881ea2c60c55691f","unresolved":false,"context_lines":[{"line_number":309,"context_line":"    def _create_gw_port(self, context, router_id, router, new_network,"},{"line_number":310,"context_line":"                        ext_ips, ext_ip_change):"},{"line_number":311,"context_line":"        if not new_network:"},{"line_number":312,"context_line":"            return"},{"line_number":313,"context_line":"        new_valid_gw_port_attachment \u003d ("},{"line_number":314,"context_line":"            new_network and (not router.gw_port or ext_ip_change or"},{"line_number":315,"context_line":"                             router.gw_port[\u0027network_id\u0027] !\u003d new_network))"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa98f980_1ce353da","line":312,"updated":"2014-09-01 15:57:43.000000000","message":"what does returning here buy us?\nIt does not make the code more readable imho","commit_id":"f5a88a1b9da52e19c966c909c5cf3d27109e7c65"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e4bc4be80094f5a34c35e80db1900f06c0c1f53e","unresolved":false,"context_lines":[{"line_number":309,"context_line":"    def _create_gw_port(self, context, router_id, router, new_network,"},{"line_number":310,"context_line":"                        ext_ips, ext_ip_change):"},{"line_number":311,"context_line":"        if not new_network:"},{"line_number":312,"context_line":"            return"},{"line_number":313,"context_line":"        new_valid_gw_port_attachment \u003d ("},{"line_number":314,"context_line":"            new_network and (not router.gw_port or ext_ip_change or"},{"line_number":315,"context_line":"                             router.gw_port[\u0027network_id\u0027] !\u003d new_network))"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa98f980_467316b1","line":312,"in_reply_to":"fa98f980_1ce353da","updated":"2014-09-02 09:28:44.000000000","message":"absolutely nothing!","commit_id":"f5a88a1b9da52e19c966c909c5cf3d27109e7c65"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"ba2b96040a84d3be474010be881ea2c60c55691f","unresolved":false,"context_lines":[{"line_number":346,"context_line":"            return True"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":"        fixed_change \u003d True"},{"line_number":349,"context_line":"        subnet_id \u003d gw_port[\u0027fixed_ips\u0027][0][\u0027subnet_id\u0027]"},{"line_number":350,"context_line":"        if subnet_id in [f[\u0027subnet_id\u0027]"},{"line_number":351,"context_line":"                         for f in ext_ips"},{"line_number":352,"context_line":"                         if f.get(\u0027subnet_id\u0027)]:"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa98f980_1c66f351","line":349,"updated":"2014-09-01 15:57:43.000000000","message":"maybe add a  comment stating that given current limitations you will do the check only for the first IP\n\nbtw, it should not bee too hard to check on all IPs, even if such check won\u0027t ever be used.","commit_id":"f5a88a1b9da52e19c966c909c5cf3d27109e7c65"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e4bc4be80094f5a34c35e80db1900f06c0c1f53e","unresolved":false,"context_lines":[{"line_number":346,"context_line":"            return True"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":"        fixed_change \u003d True"},{"line_number":349,"context_line":"        subnet_id \u003d gw_port[\u0027fixed_ips\u0027][0][\u0027subnet_id\u0027]"},{"line_number":350,"context_line":"        if subnet_id in [f[\u0027subnet_id\u0027]"},{"line_number":351,"context_line":"                         for f in ext_ips"},{"line_number":352,"context_line":"                         if f.get(\u0027subnet_id\u0027)]:"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa98f980_0402e90a","line":349,"in_reply_to":"fa98f980_1c66f351","updated":"2014-09-02 09:28:44.000000000","message":"Done","commit_id":"f5a88a1b9da52e19c966c909c5cf3d27109e7c65"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"ba2b96040a84d3be474010be881ea2c60c55691f","unresolved":false,"context_lines":[{"line_number":350,"context_line":"        if subnet_id in [f[\u0027subnet_id\u0027]"},{"line_number":351,"context_line":"                         for f in ext_ips"},{"line_number":352,"context_line":"                         if f.get(\u0027subnet_id\u0027)]:"},{"line_number":353,"context_line":"            fixed_change \u003d False"},{"line_number":354,"context_line":"        ip_address \u003d gw_port[\u0027fixed_ips\u0027][0][\u0027ip_address\u0027]"},{"line_number":355,"context_line":"        if ip_address in [f[\u0027ip_address\u0027]"},{"line_number":356,"context_line":"                          for f in ext_ips"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa98f980_dca70b4e","line":353,"updated":"2014-09-01 15:57:43.000000000","message":"what if one picks a different IP on the same subnet?","commit_id":"f5a88a1b9da52e19c966c909c5cf3d27109e7c65"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e4bc4be80094f5a34c35e80db1900f06c0c1f53e","unresolved":false,"context_lines":[{"line_number":350,"context_line":"        if subnet_id in [f[\u0027subnet_id\u0027]"},{"line_number":351,"context_line":"                         for f in ext_ips"},{"line_number":352,"context_line":"                         if f.get(\u0027subnet_id\u0027)]:"},{"line_number":353,"context_line":"            fixed_change \u003d False"},{"line_number":354,"context_line":"        ip_address \u003d gw_port[\u0027fixed_ips\u0027][0][\u0027ip_address\u0027]"},{"line_number":355,"context_line":"        if ip_address in [f[\u0027ip_address\u0027]"},{"line_number":356,"context_line":"                          for f in ext_ips"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa98f980_e69c0ac3","line":353,"in_reply_to":"fa98f980_dca70b4e","updated":"2014-09-02 09:28:44.000000000","message":"that should be detected by the IP change code following","commit_id":"f5a88a1b9da52e19c966c909c5cf3d27109e7c65"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"ba2b96040a84d3be474010be881ea2c60c55691f","unresolved":false,"context_lines":[{"line_number":351,"context_line":"                         for f in ext_ips"},{"line_number":352,"context_line":"                         if f.get(\u0027subnet_id\u0027)]:"},{"line_number":353,"context_line":"            fixed_change \u003d False"},{"line_number":354,"context_line":"        ip_address \u003d gw_port[\u0027fixed_ips\u0027][0][\u0027ip_address\u0027]"},{"line_number":355,"context_line":"        if ip_address in [f[\u0027ip_address\u0027]"},{"line_number":356,"context_line":"                          for f in ext_ips"},{"line_number":357,"context_line":"                          if f.get(\u0027ip_address\u0027)]:"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa98f980_7c89bfc9","line":354,"updated":"2014-09-01 15:57:43.000000000","message":"consider doing this at line 354:\n\ngw_port_ips \u003d gw_port[\u0027fixed_ips\u0027][0]\n(subnet_id, ip_address) \u003d (gw_port_ips[\u0027subnet_id\u0027], gw_ports_ds[\u0027ip_address\u0027])\n\nNo technical reason - just optional advice.","commit_id":"f5a88a1b9da52e19c966c909c5cf3d27109e7c65"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e4bc4be80094f5a34c35e80db1900f06c0c1f53e","unresolved":false,"context_lines":[{"line_number":351,"context_line":"                         for f in ext_ips"},{"line_number":352,"context_line":"                         if f.get(\u0027subnet_id\u0027)]:"},{"line_number":353,"context_line":"            fixed_change \u003d False"},{"line_number":354,"context_line":"        ip_address \u003d gw_port[\u0027fixed_ips\u0027][0][\u0027ip_address\u0027]"},{"line_number":355,"context_line":"        if ip_address in [f[\u0027ip_address\u0027]"},{"line_number":356,"context_line":"                          for f in ext_ips"},{"line_number":357,"context_line":"                          if f.get(\u0027ip_address\u0027)]:"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa98f980_6642da3f","line":354,"in_reply_to":"fa98f980_7c89bfc9","updated":"2014-09-02 09:28:44.000000000","message":"I made an alternative using sets that looks a bit better.","commit_id":"f5a88a1b9da52e19c966c909c5cf3d27109e7c65"},{"author":{"_account_id":10980,"name":"Doug Wiegley","email":"dougwig@parkside.io","username":"dougw"},"change_message_id":"a5aeb9e3959737a41cabd8c4e9529a1ba7a6f8d5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":20,"id":"5a890539_5562e9ad","side":"PARENT","updated":"2014-11-12 18:53:38.000000000","message":"Seems like ext_ips should default to None or [], or be partof kwargs","commit_id":"6c38103e095dbf107bdb199979be8e5e909d7e74"},{"author":{"_account_id":10980,"name":"Doug Wiegley","email":"dougwig@parkside.io","username":"dougw"},"change_message_id":"a5aeb9e3959737a41cabd8c4e9529a1ba7a6f8d5","unresolved":false,"context_lines":[{"line_number":257,"context_line":"                                                         gw_port[\u0027id\u0027])"},{"line_number":258,"context_line":"            context.session.add(router)"},{"line_number":259,"context_line":""},{"line_number":260,"context_line":"    def _validate_gw_info(self, context, gw_port, info):"},{"line_number":261,"context_line":"        network_id \u003d info[\u0027network_id\u0027] if info else None"},{"line_number":262,"context_line":"        if network_id:"},{"line_number":263,"context_line":"            network_db \u003d self._core_plugin._get_network(context, network_id)"}],"source_content_type":"text/x-python","patch_set":20,"id":"5a890539_7559a5fd","side":"PARENT","line":260,"updated":"2014-11-12 18:53:38.000000000","message":"Same comment here.","commit_id":"6c38103e095dbf107bdb199979be8e5e909d7e74"},{"author":{"_account_id":10980,"name":"Doug Wiegley","email":"dougwig@parkside.io","username":"dougw"},"change_message_id":"a5aeb9e3959737a41cabd8c4e9529a1ba7a6f8d5","unresolved":false,"context_lines":[{"line_number":267,"context_line":"        return network_id"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    def _delete_current_gw_port(self, context, router_id, router, new_network):"},{"line_number":270,"context_line":"        \"\"\"Delete gw port, if it is attached to an old network.\"\"\""},{"line_number":271,"context_line":"        is_gw_port_attached_to_existing_network \u003d ("},{"line_number":272,"context_line":"            router.gw_port and router.gw_port[\u0027network_id\u0027] !\u003d new_network)"},{"line_number":273,"context_line":"        admin_ctx \u003d context.elevated()"}],"source_content_type":"text/x-python","patch_set":20,"id":"5a890539_955c51ef","side":"PARENT","line":270,"updated":"2014-11-12 18:53:38.000000000","message":"The futher up/down the stack this goes, the more I lean towards kwargs.","commit_id":"6c38103e095dbf107bdb199979be8e5e909d7e74"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"b6f1a597bf670b5ea9c1c46f3296ee2ddb817e8d","unresolved":false,"context_lines":[{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    def _create_router_gw_port(self, context, router, network_id, ext_ips):"},{"line_number":270,"context_line":"        if ext_ips and len(ext_ips) \u003e 1:"},{"line_number":271,"context_line":"                msg \u003d _(\"Routers currently support only 1 external IP\")"},{"line_number":272,"context_line":"                raise n_exc.BadRequest(resource\u003d\u0027router\u0027, msg\u003dmsg)"},{"line_number":273,"context_line":"        # Port has no \u0027tenant-id\u0027, as it is hidden from user"},{"line_number":274,"context_line":"        gw_port \u003d self._core_plugin.create_port(context.elevated(), {"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a890539_debdd6b2","line":271,"updated":"2014-12-03 05:22:52.000000000","message":"i wonder if we should drop the word currently.","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"6317d0f1b7ac4875299415605a8a4a2a00d30894","unresolved":false,"context_lines":[{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    def _create_router_gw_port(self, context, router, network_id, ext_ips):"},{"line_number":270,"context_line":"        if ext_ips and len(ext_ips) \u003e 1:"},{"line_number":271,"context_line":"                msg \u003d _(\"Routers currently support only 1 external IP\")"},{"line_number":272,"context_line":"                raise n_exc.BadRequest(resource\u003d\u0027router\u0027, msg\u003dmsg)"},{"line_number":273,"context_line":"        # Port has no \u0027tenant-id\u0027, as it is hidden from user"},{"line_number":274,"context_line":"        gw_port \u003d self._core_plugin.create_port(context.elevated(), {"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a890539_8d107801","line":271,"in_reply_to":"5a890539_debdd6b2","updated":"2014-12-03 12:15:21.000000000","message":"indentation here is dodgy\nplease use 4 spaces and not 8","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"9d7cd1480b5e824df7c30331a2be6530822e277b","unresolved":false,"context_lines":[{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    def _create_router_gw_port(self, context, router, network_id, ext_ips):"},{"line_number":270,"context_line":"        if ext_ips and len(ext_ips) \u003e 1:"},{"line_number":271,"context_line":"                msg \u003d _(\"Routers currently support only 1 external IP\")"},{"line_number":272,"context_line":"                raise n_exc.BadRequest(resource\u003d\u0027router\u0027, msg\u003dmsg)"},{"line_number":273,"context_line":"        # Port has no \u0027tenant-id\u0027, as it is hidden from user"},{"line_number":274,"context_line":"        gw_port \u003d self._core_plugin.create_port(context.elevated(), {"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a890539_db6208ac","line":271,"in_reply_to":"5a890539_debdd6b2","updated":"2014-12-04 08:55:39.000000000","message":"yeah, not really adding anything useful other than hinting at a vaporware feature :)\n\nindentation fixed","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"b76073244674202bccd17dd5cbac319828368551","unresolved":false,"context_lines":[{"line_number":326,"context_line":"            router.gw_port and router.gw_port[\u0027network_id\u0027] !\u003d new_network)"},{"line_number":327,"context_line":"        admin_ctx \u003d context.elevated()"},{"line_number":328,"context_line":""},{"line_number":329,"context_line":"        if (router.gw_port and"},{"line_number":330,"context_line":"            (is_gw_port_attached_to_existing_network or ext_ip_change)):"},{"line_number":331,"context_line":"            if self.get_floatingips_count("},{"line_number":332,"context_line":"                admin_ctx, {\u0027router_id\u0027: [router_id]}):"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a890539_b5102401","line":329,"updated":"2014-12-03 09:46:15.000000000","message":"is_gw_port_attached_to_existing_network includes checking for router.gw_port","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"9d7cd1480b5e824df7c30331a2be6530822e277b","unresolved":false,"context_lines":[{"line_number":326,"context_line":"            router.gw_port and router.gw_port[\u0027network_id\u0027] !\u003d new_network)"},{"line_number":327,"context_line":"        admin_ctx \u003d context.elevated()"},{"line_number":328,"context_line":""},{"line_number":329,"context_line":"        if (router.gw_port and"},{"line_number":330,"context_line":"            (is_gw_port_attached_to_existing_network or ext_ip_change)):"},{"line_number":331,"context_line":"            if self.get_floatingips_count("},{"line_number":332,"context_line":"                admin_ctx, {\u0027router_id\u0027: [router_id]}):"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a890539_5bca986e","line":329,"in_reply_to":"5a890539_b5102401","updated":"2014-12-04 08:55:39.000000000","message":"it does, but i still need to check it for the ext_ip_change case. let me update that var so i don\u0027t spread logic between the two.","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"6317d0f1b7ac4875299415605a8a4a2a00d30894","unresolved":false,"context_lines":[{"line_number":343,"context_line":"                    vpnservice.check_router_in_use(context, router_id)"},{"line_number":344,"context_line":"            self._core_plugin.delete_port("},{"line_number":345,"context_line":"                admin_ctx, gw_port[\u0027id\u0027], l3_port_check\u003dFalse)"},{"line_number":346,"context_line":"            return True"},{"line_number":347,"context_line":"        return False"},{"line_number":348,"context_line":""},{"line_number":349,"context_line":"    def _create_gw_port(self, context, router_id, router, new_network,"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a890539_ad1ff407","line":346,"updated":"2014-12-03 12:15:21.000000000","message":"why do we need these?","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"9d7cd1480b5e824df7c30331a2be6530822e277b","unresolved":false,"context_lines":[{"line_number":343,"context_line":"                    vpnservice.check_router_in_use(context, router_id)"},{"line_number":344,"context_line":"            self._core_plugin.delete_port("},{"line_number":345,"context_line":"                admin_ctx, gw_port[\u0027id\u0027], l3_port_check\u003dFalse)"},{"line_number":346,"context_line":"            return True"},{"line_number":347,"context_line":"        return False"},{"line_number":348,"context_line":""},{"line_number":349,"context_line":"    def _create_gw_port(self, context, router_id, router, new_network,"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a890539_9be960e5","line":346,"in_reply_to":"5a890539_ad1ff407","updated":"2014-12-04 08:55:39.000000000","message":"whoops, i think these existed in an old version of the l3 code and got caught in when i rebased.","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"b76073244674202bccd17dd5cbac319828368551","unresolved":false,"context_lines":[{"line_number":386,"context_line":"        subnet_ids \u003d set(ip[\u0027subnet_id\u0027] for ip in gw_port[\u0027fixed_ips\u0027])"},{"line_number":387,"context_line":"        new_subnet_ids \u003d set(f[\u0027subnet_id\u0027] for f in ext_ips"},{"line_number":388,"context_line":"                             if f.get(\u0027subnet_id\u0027))"},{"line_number":389,"context_line":"        subnet_change \u003d not new_subnet_ids \u003d\u003d subnet_ids"},{"line_number":390,"context_line":"        ip_addresses \u003d set(ip[\u0027ip_address\u0027] for ip in gw_port[\u0027fixed_ips\u0027])"},{"line_number":391,"context_line":"        new_ip_addresses \u003d set(f[\u0027ip_address\u0027] for f in ext_ips"},{"line_number":392,"context_line":"                               if f.get(\u0027ip_address\u0027))"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a890539_158c987f","line":389,"updated":"2014-12-03 09:46:15.000000000","message":"may return here if subnet_change","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"9d7cd1480b5e824df7c30331a2be6530822e277b","unresolved":false,"context_lines":[{"line_number":386,"context_line":"        subnet_ids \u003d set(ip[\u0027subnet_id\u0027] for ip in gw_port[\u0027fixed_ips\u0027])"},{"line_number":387,"context_line":"        new_subnet_ids \u003d set(f[\u0027subnet_id\u0027] for f in ext_ips"},{"line_number":388,"context_line":"                             if f.get(\u0027subnet_id\u0027))"},{"line_number":389,"context_line":"        subnet_change \u003d not new_subnet_ids \u003d\u003d subnet_ids"},{"line_number":390,"context_line":"        ip_addresses \u003d set(ip[\u0027ip_address\u0027] for ip in gw_port[\u0027fixed_ips\u0027])"},{"line_number":391,"context_line":"        new_ip_addresses \u003d set(f[\u0027ip_address\u0027] for f in ext_ips"},{"line_number":392,"context_line":"                               if f.get(\u0027ip_address\u0027))"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a890539_3b7dcc1c","line":389,"in_reply_to":"5a890539_158c987f","updated":"2014-12-04 08:55:39.000000000","message":"Done","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"}],"neutron/extensions/l3.py":[{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"ba2b96040a84d3be474010be881ea2c60c55691f","unresolved":false,"context_lines":[{"line_number":105,"context_line":"                               \u0027type:dict_or_nodata\u0027: {"},{"line_number":106,"context_line":"                                   \u0027network_id\u0027: {\u0027type:uuid\u0027: None,"},{"line_number":107,"context_line":"                                                  \u0027required\u0027: True},"},{"line_number":108,"context_line":"                                   \u0027external_fixed_ips\u0027: {"},{"line_number":109,"context_line":"                                       \u0027convert_list_to\u0027:"},{"line_number":110,"context_line":"                                       attr.convert_kvp_list_to_dict,"},{"line_number":111,"context_line":"                                       \u0027type:fixed_ips\u0027: None,"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa98f980_7c729f7d","line":108,"updated":"2014-09-01 15:57:43.000000000","message":"This is the ugliest extension ever made.\nThe author of this extension should be hanged over a pool full of hungry crocodiles.\n\nObviously I am its original author.\nAdding more stuff to this extension will only make the code even more unmainteinable.\n\nPersonally I think external_gateway_info is one of those attributes which should be promoted to sub resource. This will simplify authz policy management, and most importantly the user workflow.\nWe need to find a way where the main resource and the sub resource can be created/updated/returned in the same API request. However, if necessary, the user should be able to operate directly on the subresource.\n\nThis is probably something that can\u0027t be addressed for this release cycle. So if there is any urgency around this blueprint we might proceed this way and then rework it in Kilo.\n\nHowever, if this patch does not make Juno, I would suggest reworking the external_gateway_info attribute (and yes, we should worry also about backward compatibility)","commit_id":"f5a88a1b9da52e19c966c909c5cf3d27109e7c65"}],"neutron/extensions/l3_ext_gw_mode.py":[{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"c2c08a1a0cfdcc0dda496b4b1c77e49058c753db","unresolved":false,"context_lines":[{"line_number":30,"context_line":"                  {\u0027network_id\u0027: {\u0027type:uuid\u0027: None, \u0027required\u0027: True},"},{"line_number":31,"context_line":"                   \u0027enable_snat\u0027: {\u0027type:boolean\u0027: None, \u0027required\u0027: False,"},{"line_number":32,"context_line":"                                   \u0027convert_to\u0027: attrs.convert_to_boolean},"},{"line_number":33,"context_line":"                   \u0027external_fixed_ips\u0027: {"},{"line_number":34,"context_line":"                       \u0027convert_list_to\u0027: attrs.convert_kvp_list_to_dict,"},{"line_number":35,"context_line":"                       \u0027validate\u0027: {\u0027type:fixed_ips\u0027: None},"},{"line_number":36,"context_line":"                       \u0027default\u0027: [],"}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_f12c6304","line":33,"updated":"2014-06-20 04:33:39.000000000","message":"are u sure we should add it into this extension? we have add it in the router extension.","commit_id":"9da7ec27497627152fa26d3e091844a051086c75"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"5e4329890af86a5ddcb08354ee38b8e7f2892636","unresolved":false,"context_lines":[{"line_number":30,"context_line":"                  {\u0027network_id\u0027: {\u0027type:uuid\u0027: None, \u0027required\u0027: True},"},{"line_number":31,"context_line":"                   \u0027enable_snat\u0027: {\u0027type:boolean\u0027: None, \u0027required\u0027: False,"},{"line_number":32,"context_line":"                                   \u0027convert_to\u0027: attrs.convert_to_boolean},"},{"line_number":33,"context_line":"                   \u0027external_fixed_ips\u0027: {"},{"line_number":34,"context_line":"                       \u0027convert_list_to\u0027: attrs.convert_kvp_list_to_dict,"},{"line_number":35,"context_line":"                       \u0027validate\u0027: {\u0027type:fixed_ips\u0027: None},"},{"line_number":36,"context_line":"                       \u0027default\u0027: [],"}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_ef12b75f","line":33,"in_reply_to":"1ae5cdf2_f12c6304","updated":"2014-06-20 10:48:40.000000000","message":"I think if I don\u0027t have it here, it won\u0027t work when using this extension. This also redefines all of the other router properties not directly related to snat.","commit_id":"9da7ec27497627152fa26d3e091844a051086c75"}],"neutron/tests/unit/test_l3_plugin.py":[{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"646e1f256abe4f614358e1524f7d2a867f4977eb","unresolved":false,"context_lines":[{"line_number":509,"context_line":"    def test_router_create_with_gwinfo_ext_ip(self):"},{"line_number":510,"context_line":"        with self.subnet() as s:"},{"line_number":511,"context_line":"            self._set_net_external(s[\u0027subnet\u0027][\u0027network_id\u0027])"},{"line_number":512,"context_line":"            data \u003d {\u0027router\u0027: {\u0027tenant_id\u0027: _uuid()}}"},{"line_number":513,"context_line":"            data[\u0027router\u0027][\u0027name\u0027] \u003d \u0027router1\u0027"},{"line_number":514,"context_line":"            data[\u0027router\u0027][\u0027external_gateway_info\u0027] \u003d {"},{"line_number":515,"context_line":"                \u0027network_id\u0027: s[\u0027subnet\u0027][\u0027network_id\u0027],"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAWH%2F9m8o%3D","line":512,"updated":"2014-04-03 11:44:39.000000000","message":"Line from 512 till 519 and line from 529 till 536 are almost identical to lines from 497 to 503. I\u0027d suggest creating an function like that:\n\n_create_router(self, subnet_id, external_ip\u003dNone, ctx\u003dNone)\n\nthat takes care of the router creation, refactor the code to use that instead of repeating the same lines.\n\nI guess external_ip and ctx are the only param that need to be passed.","commit_id":"16e073de9f92b1c298ee080cabfc98d4855c884f"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"866ae94f7dc8953174de2ecb7257af164cac96d7","unresolved":false,"context_lines":[{"line_number":509,"context_line":"    def test_router_create_with_gwinfo_ext_ip(self):"},{"line_number":510,"context_line":"        with self.subnet() as s:"},{"line_number":511,"context_line":"            self._set_net_external(s[\u0027subnet\u0027][\u0027network_id\u0027])"},{"line_number":512,"context_line":"            data \u003d {\u0027router\u0027: {\u0027tenant_id\u0027: _uuid()}}"},{"line_number":513,"context_line":"            data[\u0027router\u0027][\u0027name\u0027] \u003d \u0027router1\u0027"},{"line_number":514,"context_line":"            data[\u0027router\u0027][\u0027external_gateway_info\u0027] \u003d {"},{"line_number":515,"context_line":"                \u0027network_id\u0027: s[\u0027subnet\u0027][\u0027network_id\u0027],"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAWH%2F9hp0%3D","line":512,"in_reply_to":"AAAAWH%2F9m8o%3D","updated":"2014-04-03 22:38:33.000000000","message":"Done","commit_id":"16e073de9f92b1c298ee080cabfc98d4855c884f"},{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"eb31958d25ab0d133ee96d06ef0e6ac1b1f96b70","unresolved":false,"context_lines":[{"line_number":818,"context_line":"                    ext_ips\u003d[{\u0027subnet_id\u0027: s2[\u0027subnet\u0027][\u0027id\u0027]}])"},{"line_number":819,"context_line":"        fip1 \u003d res1[\u0027router\u0027][\u0027external_gateway_info\u0027][\u0027external_fixed_ips\u0027][0]"},{"line_number":820,"context_line":"        fip2 \u003d res2[\u0027router\u0027][\u0027external_gateway_info\u0027][\u0027external_fixed_ips\u0027][0]"},{"line_number":821,"context_line":"        self.assertEqual(fip1[\u0027subnet_id\u0027], s1[\u0027subnet\u0027][\u0027id\u0027])"},{"line_number":822,"context_line":"        self.assertEqual(fip2[\u0027subnet_id\u0027], s2[\u0027subnet\u0027][\u0027id\u0027])"},{"line_number":823,"context_line":"        self.assertNotEqual(fip1[\u0027subnet_id\u0027], fip2[\u0027subnet_id\u0027])"},{"line_number":824,"context_line":"        self.assertNotEqual(fip1[\u0027ip_address\u0027], fip2[\u0027ip_address\u0027])"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a890539_8e1b851b","line":821,"updated":"2014-11-28 12:17:21.000000000","message":"iiuc, it should be:\n\n  # self.assertEqual(expected, observed)\n  self.assertEqual(s1[\u0027subnet\u0027][\u0027id\u0027], fip1[\u0027subnet_id\u0027])\n  self.assertEqual(s2[\u0027subnet\u0027][\u0027id\u0027], fip2[\u0027subnet_id\u0027])","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"9d7cd1480b5e824df7c30331a2be6530822e277b","unresolved":false,"context_lines":[{"line_number":818,"context_line":"                    ext_ips\u003d[{\u0027subnet_id\u0027: s2[\u0027subnet\u0027][\u0027id\u0027]}])"},{"line_number":819,"context_line":"        fip1 \u003d res1[\u0027router\u0027][\u0027external_gateway_info\u0027][\u0027external_fixed_ips\u0027][0]"},{"line_number":820,"context_line":"        fip2 \u003d res2[\u0027router\u0027][\u0027external_gateway_info\u0027][\u0027external_fixed_ips\u0027][0]"},{"line_number":821,"context_line":"        self.assertEqual(fip1[\u0027subnet_id\u0027], s1[\u0027subnet\u0027][\u0027id\u0027])"},{"line_number":822,"context_line":"        self.assertEqual(fip2[\u0027subnet_id\u0027], s2[\u0027subnet\u0027][\u0027id\u0027])"},{"line_number":823,"context_line":"        self.assertNotEqual(fip1[\u0027subnet_id\u0027], fip2[\u0027subnet_id\u0027])"},{"line_number":824,"context_line":"        self.assertNotEqual(fip1[\u0027ip_address\u0027], fip2[\u0027ip_address\u0027])"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a890539_fbad0485","line":821,"in_reply_to":"5a890539_8e1b851b","updated":"2014-12-04 08:55:39.000000000","message":"But I expect that the result returned is equal to the one I observed earlier. ;-)","commit_id":"e164b7ca534394d756d2b90016a067f55c8c4a67"},{"author":{"_account_id":2035,"name":"Maru Newby","email":"marun@redhat.com","username":"maru"},"change_message_id":"c2a0ce5f096fb42ce129574f93de4bb9fe0a4150","unresolved":false,"context_lines":[{"line_number":619,"context_line":"                router[\u0027router\u0027][\u0027external_gateway_info\u0027][\u0027network_id\u0027])"},{"line_number":620,"context_line":"            self._delete(\u0027routers\u0027, router[\u0027router\u0027][\u0027id\u0027])"},{"line_number":621,"context_line":""},{"line_number":622,"context_line":"    def test_router_create_with_gwinfo_ext_ip(self):"},{"line_number":623,"context_line":"        with self.subnet() as s:"},{"line_number":624,"context_line":"            self._set_net_external(s[\u0027subnet\u0027][\u0027network_id\u0027])"},{"line_number":625,"context_line":"            ext_info \u003d {"}],"source_content_type":"text/x-python","patch_set":22,"id":"3a961159_fe35bfdb","line":622,"updated":"2014-12-16 02:32:04.000000000","message":"(No action required) No wonder you wanted to clean up the tests, this is very difficult for me to parse.","commit_id":"0f647f67c35cab9836b44f9bec240b47cd20ad55"}]}
