)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"f1169565283310846c4cea2a5e4395bbcd658261","unresolved":false,"context_lines":[{"line_number":5,"context_line":"CommitDate: 2019-04-05 15:27:07 +0200"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"WiP - L3 Conntrack Helper Extension"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: I55d659c47f3e9a65af78509fbd63416373a501f3"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"5fc1f717_19eb3878","line":8,"updated":"2019-04-08 12:42:37.000000000","message":"You need the bug reference.","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"cf52271a6b849d0f30cf8c1d7116f35cd4f27bbf","unresolved":false,"context_lines":[{"line_number":5,"context_line":"CommitDate: 2019-04-05 15:27:07 +0200"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"WiP - L3 Conntrack Helper Extension"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: I55d659c47f3e9a65af78509fbd63416373a501f3"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"5fc1f717_677092a5","line":8,"in_reply_to":"5fc1f717_19eb3878","updated":"2019-04-08 16:51:17.000000000","message":"Done","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"}],"api-ref/source/v2/l3-conntrack-helper.inc":[{"author":{"_account_id":5367,"name":"boden","email":"bodenvmw@gmail.com","username":"boden"},"change_message_id":"2474a810b243f656df8899b7e55bdf30fe075d6e","unresolved":false,"context_lines":[{"line_number":64,"context_line":""},{"line_number":65,"context_line":".. rest_parameters:: parameters.yaml"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"   - router_id: router_id"},{"line_number":68,"context_line":"   - conntrack_helper_id: conntrack_helper_id-path"},{"line_number":69,"context_line":"   - helper: conntrack_helper_helper-body"},{"line_number":70,"context_line":"   - protocol: conntrack_helper_protocol-body"},{"line_number":71,"context_line":"   - port: conntrack_helper_port-body"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"Request Example"}],"source_content_type":"text/x-c++src","patch_set":4,"id":"5fc1f717_428529ac","line":71,"range":{"start_line":67,"start_character":5,"end_line":71,"end_character":37},"updated":"2019-04-09 15:13:05.000000000","message":"Are these all required on the request body?\nThe way the read now, they are all required.\nIf some are optional pls specify as such.","commit_id":"45fa01d744bcec1f38e60e88ecad64aa9a5ced8d"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"2306a5a64c455c68c8e43107ae4f38265f0dc3f4","unresolved":false,"context_lines":[{"line_number":64,"context_line":""},{"line_number":65,"context_line":".. rest_parameters:: parameters.yaml"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"   - router_id: router_id"},{"line_number":68,"context_line":"   - conntrack_helper_id: conntrack_helper_id-path"},{"line_number":69,"context_line":"   - helper: conntrack_helper_helper-body"},{"line_number":70,"context_line":"   - protocol: conntrack_helper_protocol-body"},{"line_number":71,"context_line":"   - port: conntrack_helper_port-body"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"Request Example"}],"source_content_type":"text/x-c++src","patch_set":4,"id":"5fc1f717_6f4032a3","line":71,"range":{"start_line":67,"start_character":5,"end_line":71,"end_character":37},"in_reply_to":"5fc1f717_428529ac","updated":"2019-04-10 21:03:36.000000000","message":"The update request does not need all these in the request.\nI have added entries in parameters.yaml and updated this so the api-ref doc should list them as optional.\n\nDone.","commit_id":"45fa01d744bcec1f38e60e88ecad64aa9a5ced8d"},{"author":{"_account_id":5367,"name":"boden","email":"bodenvmw@gmail.com","username":"boden"},"change_message_id":"2474a810b243f656df8899b7e55bdf30fe075d6e","unresolved":false,"context_lines":[{"line_number":139,"context_line":""},{"line_number":140,"context_line":".. rest_parameters:: parameters.yaml"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"   - router_id: router_id"},{"line_number":143,"context_line":"   - id: id-query"},{"line_number":144,"context_line":"   - helper: conntrack_helper_helper-query"},{"line_number":145,"context_line":"   - protocol: conntrack_helper_protocol-query"},{"line_number":146,"context_line":"   - port: conntrack_helper_port-query"},{"line_number":147,"context_line":"   - sort_key: conntrack_helper-sort_key"},{"line_number":148,"context_line":"   - sort_dir: sort_dir"},{"line_number":149,"context_line":"   - fields: fields"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"Response Parameters"},{"line_number":152,"context_line":"-------------------"}],"source_content_type":"text/x-c++src","patch_set":4,"id":"5fc1f717_62b3859b","line":149,"range":{"start_line":142,"start_character":0,"end_line":149,"end_character":19},"updated":"2019-04-09 15:13:05.000000000","message":"Are these all required on the request body?\nThe way the read now, they are all required.\nIf some are optional pls specify as such.","commit_id":"45fa01d744bcec1f38e60e88ecad64aa9a5ced8d"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"2306a5a64c455c68c8e43107ae4f38265f0dc3f4","unresolved":false,"context_lines":[{"line_number":139,"context_line":""},{"line_number":140,"context_line":".. rest_parameters:: parameters.yaml"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"   - router_id: router_id"},{"line_number":143,"context_line":"   - id: id-query"},{"line_number":144,"context_line":"   - helper: conntrack_helper_helper-query"},{"line_number":145,"context_line":"   - protocol: conntrack_helper_protocol-query"},{"line_number":146,"context_line":"   - port: conntrack_helper_port-query"},{"line_number":147,"context_line":"   - sort_key: conntrack_helper-sort_key"},{"line_number":148,"context_line":"   - sort_dir: sort_dir"},{"line_number":149,"context_line":"   - fields: fields"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"Response Parameters"},{"line_number":152,"context_line":"-------------------"}],"source_content_type":"text/x-c++src","patch_set":4,"id":"5fc1f717_6f96f24b","line":149,"range":{"start_line":142,"start_character":0,"end_line":149,"end_character":19},"in_reply_to":"5fc1f717_62b3859b","updated":"2019-04-10 21:03:36.000000000","message":"http://logs.openstack.org/71/650271/4/check/build-openstack-api-ref/17d6c9e/html/v2/index.html?expanded\u003dlist-router-conntrack-helpers-detail#routers-conntrack-helper-ct-target-rules\n\nThe GET lists everything but the router_id as optional in the rendered docs?","commit_id":"45fa01d744bcec1f38e60e88ecad64aa9a5ced8d"},{"author":{"_account_id":5367,"name":"boden","email":"bodenvmw@gmail.com","username":"boden"},"change_message_id":"2474a810b243f656df8899b7e55bdf30fe075d6e","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":".. rest_parameters:: parameters.yaml"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"   - conntrack_helper: conntrack_helper"},{"line_number":185,"context_line":"   - router_id: router_id"},{"line_number":186,"context_line":"   - helper: conntrack_helper_helper-body"},{"line_number":187,"context_line":"   - protocol: conntrack_helper_protocol-body"},{"line_number":188,"context_line":"   - port: conntrack_helper_port-body"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"Request Example"}],"source_content_type":"text/x-c++src","patch_set":4,"id":"5fc1f717_c267d924","line":188,"range":{"start_line":184,"start_character":3,"end_line":188,"end_character":37},"updated":"2019-04-09 15:13:05.000000000","message":"Are these all required on the request body?\nThe way the read now, they are all required.\nIf some are optional pls specify as such.","commit_id":"45fa01d744bcec1f38e60e88ecad64aa9a5ced8d"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"2306a5a64c455c68c8e43107ae4f38265f0dc3f4","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":".. rest_parameters:: parameters.yaml"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"   - conntrack_helper: conntrack_helper"},{"line_number":185,"context_line":"   - router_id: router_id"},{"line_number":186,"context_line":"   - helper: conntrack_helper_helper-body"},{"line_number":187,"context_line":"   - protocol: conntrack_helper_protocol-body"},{"line_number":188,"context_line":"   - port: conntrack_helper_port-body"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"Request Example"}],"source_content_type":"text/x-c++src","patch_set":4,"id":"5fc1f717_cf8046fa","line":188,"range":{"start_line":184,"start_character":3,"end_line":188,"end_character":37},"in_reply_to":"5fc1f717_c267d924","updated":"2019-04-10 21:03:36.000000000","message":"For create they are all required.","commit_id":"45fa01d744bcec1f38e60e88ecad64aa9a5ced8d"},{"author":{"_account_id":5367,"name":"boden","email":"bodenvmw@gmail.com","username":"boden"},"change_message_id":"52118d8313b1828d61ce7c2fd850264857c533d5","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":".. rest_parameters:: parameters.yaml"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"   - conntrack_helper: conntrack_helper"},{"line_number":185,"context_line":"   - router_id: router_id"},{"line_number":186,"context_line":"   - helper: conntrack_helper_helper-body"},{"line_number":187,"context_line":"   - protocol: conntrack_helper_protocol-body"},{"line_number":188,"context_line":"   - port: conntrack_helper_port-body"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"Request Example"}],"source_content_type":"text/x-c++src","patch_set":6,"id":"3fce034c_d94a0b7f","line":188,"range":{"start_line":184,"start_character":0,"end_line":188,"end_character":37},"updated":"2019-04-12 12:19:31.000000000","message":"These are all required in the body for a POST??\nThat\u0027s the way it reads right now, so just confirming.","commit_id":"c6b907a2cfa9626260348f07284206ab87e5712d"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"80379d8cd95e4e024ab8706610bff4f0fad4a890","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":".. rest_parameters:: parameters.yaml"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"   - conntrack_helper: conntrack_helper"},{"line_number":185,"context_line":"   - router_id: router_id"},{"line_number":186,"context_line":"   - helper: conntrack_helper_helper-body"},{"line_number":187,"context_line":"   - protocol: conntrack_helper_protocol-body"},{"line_number":188,"context_line":"   - port: conntrack_helper_port-body"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"Request Example"}],"source_content_type":"text/x-c++src","patch_set":6,"id":"3fce034c_6b615d05","line":188,"range":{"start_line":184,"start_character":0,"end_line":188,"end_character":37},"in_reply_to":"3fce034c_77e2a903","updated":"2019-04-17 23:01:32.000000000","message":"They are required true. see : api-ref/source/v2/parameters.yaml L2100, L2118, L2130","commit_id":"c6b907a2cfa9626260348f07284206ab87e5712d"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"b5397753a71e21835e91a009f4afac085108cced","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":".. rest_parameters:: parameters.yaml"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"   - conntrack_helper: conntrack_helper"},{"line_number":185,"context_line":"   - router_id: router_id"},{"line_number":186,"context_line":"   - helper: conntrack_helper_helper-body"},{"line_number":187,"context_line":"   - protocol: conntrack_helper_protocol-body"},{"line_number":188,"context_line":"   - port: conntrack_helper_port-body"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"Request Example"}],"source_content_type":"text/x-c++src","patch_set":6,"id":"3fce034c_77e2a903","line":188,"range":{"start_line":184,"start_character":0,"end_line":188,"end_character":37},"in_reply_to":"3fce034c_d94a0b7f","updated":"2019-04-17 14:34:36.000000000","message":"Does it make sense to add \u0027required\u0027 to these on the API definition?","commit_id":"c6b907a2cfa9626260348f07284206ab87e5712d"}],"neutron_lib/api/definitions/base.py":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"9c81d5cbe2569db6b39228ae4b224b727fe9e9f1","unresolved":false,"context_lines":[{"line_number":91,"context_line":"    \u0027dns-integration\u0027,"},{"line_number":92,"context_line":"    \u0027dvr\u0027,"},{"line_number":93,"context_line":"    \u0027empty-string-filtering\u0027,"},{"line_number":94,"context_line":"    \u0027expose_l3_conntrack_helper\u0027,"},{"line_number":95,"context_line":"    \u0027expose-port-forwarding-in-fip\u0027,"},{"line_number":96,"context_line":"    \u0027ext-gw-mode\u0027,"},{"line_number":97,"context_line":"    \u0027external-net\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"5fc1f717_c5040381","line":94,"updated":"2019-04-05 13:17:15.000000000","message":"Why _ and not - ?  These things always confuse me...","commit_id":"e81811f5232539cce73b938c114ac0addc111228"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"6f53914c93ef0eb72becc3a84285732b81d1a872","unresolved":false,"context_lines":[{"line_number":91,"context_line":"    \u0027dns-integration\u0027,"},{"line_number":92,"context_line":"    \u0027dvr\u0027,"},{"line_number":93,"context_line":"    \u0027empty-string-filtering\u0027,"},{"line_number":94,"context_line":"    \u0027expose_l3_conntrack_helper\u0027,"},{"line_number":95,"context_line":"    \u0027expose-port-forwarding-in-fip\u0027,"},{"line_number":96,"context_line":"    \u0027ext-gw-mode\u0027,"},{"line_number":97,"context_line":"    \u0027external-net\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"5fc1f717_25706708","line":94,"in_reply_to":"5fc1f717_c5040381","updated":"2019-04-05 13:28:56.000000000","message":"Copy/Pasta mistake by me. We should use - here.","commit_id":"e81811f5232539cce73b938c114ac0addc111228"}],"neutron_lib/api/definitions/expose_l3_conntrack_helper.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"f1169565283310846c4cea2a5e4395bbcd658261","unresolved":false,"context_lines":[{"line_number":31,"context_line":"            \u0027allow_post\u0027: False,"},{"line_number":32,"context_line":"            \u0027allow_put\u0027: False,"},{"line_number":33,"context_line":"            \u0027is_visible\u0027: True,"},{"line_number":34,"context_line":"            \u0027default\u0027: None"},{"line_number":35,"context_line":"        }"},{"line_number":36,"context_line":"    }"},{"line_number":37,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":2,"id":"5fc1f717_79735c4f","line":34,"range":{"start_line":34,"start_character":23,"end_line":34,"end_character":27},"updated":"2019-04-08 12:42:37.000000000","message":"nit: if this is going to be a list of rules, the default value should be an empty list","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"cf52271a6b849d0f30cf8c1d7116f35cd4f27bbf","unresolved":false,"context_lines":[{"line_number":31,"context_line":"            \u0027allow_post\u0027: False,"},{"line_number":32,"context_line":"            \u0027allow_put\u0027: False,"},{"line_number":33,"context_line":"            \u0027is_visible\u0027: True,"},{"line_number":34,"context_line":"            \u0027default\u0027: None"},{"line_number":35,"context_line":"        }"},{"line_number":36,"context_line":"    }"},{"line_number":37,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":2,"id":"5fc1f717_0773ce81","line":34,"range":{"start_line":34,"start_character":23,"end_line":34,"end_character":27},"in_reply_to":"5fc1f717_79735c4f","updated":"2019-04-08 16:51:17.000000000","message":"None, seems to be what is used elsewhere:\n\nhttps://github.com/openstack/neutron-lib/blob/master/neutron_lib/api/definitions/expose_port_forwarding_in_fip.py#L32\n\ncurl -s -H \"X-Auth-Token: $(openstack token issue -f value -c id)\" http://192.168.122.103:9696/v2.0/routers/878470ae-b083-4c5e-ac30-2a76884633b1/conntrack_helpers| json_reformat\n{\n    \"conntrack_helpers\": [\n\n    ]\n}\n\nThis also seem to yield the correct results:\n[stack@neutron-devstack ~]$ curl -s -H \"X-Auth-Token: $(openstack token issue -f value -c id)\" http://192.168.122.103:9696/v2.0/routers/878470ae-b083-4c5e-ac30-2a76884633b1 | json_reformat\n{\n    \"router\": {\n        \"status\": \"ACTIVE\",\n        \"external_gateway_info\": {\n            \"network_id\": \"147e0028-85d6-4b17-a785-183086d65bbf\",\n            \"enable_snat\": true,\n            \"external_fixed_ips\": [\n                {\n                    \"subnet_id\": \"81a9035b-151c-452c-908a-7bbb21ad8a45\",\n                    \"ip_address\": \"172.20.0.246\"\n                },\n                {\n                    \"subnet_id\": \"001ef703-d0bb-4ebb-91a0-7a895134821a\",\n                    \"ip_address\": \"2001:db8::132\"\n                }\n            ]\n        },\n        \"availability_zone_hints\": [\n\n        ],\n        \"availability_zones\": [\n            \"nova\"\n        ],\n        \"description\": \"\",\n        \"tags\": [\n\n        ],\n        \"tenant_id\": \"c8180ad2c3aa461abf96d98849c9eec6\",\n        \"created_at\": \"2019-04-05T11:17:05Z\",\n        \"admin_state_up\": true,\n        \"distributed\": false,\n        \"updated_at\": \"2019-04-08T14:36:10Z\",\n        \"conntrack_helpers\": [\n\n        ],\n        \"project_id\": \"c8180ad2c3aa461abf96d98849c9eec6\",\n        \"flavor_id\": null,\n        \"revision_number\": 34,\n        \"routes\": [\n\n        ],\n        \"ha\": false,\n        \"id\": \"878470ae-b083-4c5e-ac30-2a76884633b1\",\n        \"name\": \"router1\"\n    }\n}","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"}],"neutron_lib/api/definitions/l3_conntrack_helper.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"f1169565283310846c4cea2a5e4395bbcd658261","unresolved":false,"context_lines":[{"line_number":47,"context_line":"DESCRIPTION \u003d \"Allow adding CT target rules for conntrack helper\""},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"# A timestamp of when the extension was introduced."},{"line_number":50,"context_line":"UPDATED_TIMESTAMP \u003d \"2019-03-19T10:00:00-00:00\""},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"# The name of the resource."},{"line_number":53,"context_line":"RESOURCE_NAME \u003d \u0027conntrack_helper\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"5fc1f717_f9ad0c84","line":50,"updated":"2019-04-08 12:42:37.000000000","message":"nit and trivial: [1] both are created at the same time.\n\n[1] https://review.openstack.org/#/c/650271/2/neutron_lib/api/definitions/expose_l3_conntrack_helper.py@25","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"cf52271a6b849d0f30cf8c1d7116f35cd4f27bbf","unresolved":false,"context_lines":[{"line_number":47,"context_line":"DESCRIPTION \u003d \"Allow adding CT target rules for conntrack helper\""},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"# A timestamp of when the extension was introduced."},{"line_number":50,"context_line":"UPDATED_TIMESTAMP \u003d \"2019-03-19T10:00:00-00:00\""},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"# The name of the resource."},{"line_number":53,"context_line":"RESOURCE_NAME \u003d \u0027conntrack_helper\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"5fc1f717_a7d75a23","line":50,"in_reply_to":"5fc1f717_f9ad0c84","updated":"2019-04-08 16:51:17.000000000","message":"Done","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"f1169565283310846c4cea2a5e4395bbcd658261","unresolved":false,"context_lines":[{"line_number":87,"context_line":"                         \u0027validate\u0027: {"},{"line_number":88,"context_line":"                             \u0027type:string\u0027: db_const.PROJECT_ID_FIELD_SIZE},"},{"line_number":89,"context_line":"                         \u0027required_by_policy\u0027: True,"},{"line_number":90,"context_line":"                         \u0027is_visible\u0027: False},"},{"line_number":91,"context_line":"            PROTOCOL: {\u0027allow_post\u0027: True, \u0027allow_put\u0027: True,"},{"line_number":92,"context_line":"                       \u0027validate\u0027: {\u0027type:values\u0027: PROTOCOLS},"},{"line_number":93,"context_line":"                       \u0027is_visible\u0027: True,"}],"source_content_type":"text/x-python","patch_set":2,"id":"5fc1f717_d9f61090","line":90,"range":{"start_line":90,"start_character":39,"end_line":90,"end_character":44},"updated":"2019-04-08 12:42:37.000000000","message":"Why False?","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"cf52271a6b849d0f30cf8c1d7116f35cd4f27bbf","unresolved":false,"context_lines":[{"line_number":87,"context_line":"                         \u0027validate\u0027: {"},{"line_number":88,"context_line":"                             \u0027type:string\u0027: db_const.PROJECT_ID_FIELD_SIZE},"},{"line_number":89,"context_line":"                         \u0027required_by_policy\u0027: True,"},{"line_number":90,"context_line":"                         \u0027is_visible\u0027: False},"},{"line_number":91,"context_line":"            PROTOCOL: {\u0027allow_post\u0027: True, \u0027allow_put\u0027: True,"},{"line_number":92,"context_line":"                       \u0027validate\u0027: {\u0027type:values\u0027: PROTOCOLS},"},{"line_number":93,"context_line":"                       \u0027is_visible\u0027: True,"}],"source_content_type":"text/x-python","patch_set":2,"id":"5fc1f717_e7a482a5","line":90,"range":{"start_line":90,"start_character":39,"end_line":90,"end_character":44},"in_reply_to":"5fc1f717_d9f61090","updated":"2019-04-08 16:51:17.000000000","message":"This is under API_PREFIX \u003d \u0027/\u0027 + l3.ROUTERS\n\nSince l3.ROUTERS have project_id, it does\u0027nt make sense to show it again under the \"conntection_trackers\" field of the router?","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"414ba1ce5c3b2d9ae115b58c33641809255b3a32","unresolved":false,"context_lines":[{"line_number":87,"context_line":"                         \u0027validate\u0027: {"},{"line_number":88,"context_line":"                             \u0027type:string\u0027: db_const.PROJECT_ID_FIELD_SIZE},"},{"line_number":89,"context_line":"                         \u0027required_by_policy\u0027: True,"},{"line_number":90,"context_line":"                         \u0027is_visible\u0027: False},"},{"line_number":91,"context_line":"            PROTOCOL: {\u0027allow_post\u0027: True, \u0027allow_put\u0027: True,"},{"line_number":92,"context_line":"                       \u0027validate\u0027: {\u0027type:values\u0027: PROTOCOLS},"},{"line_number":93,"context_line":"                       \u0027is_visible\u0027: True,"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fce034c_ccc5845d","line":90,"range":{"start_line":90,"start_character":39,"end_line":90,"end_character":44},"in_reply_to":"5fc1f717_e7a482a5","updated":"2019-04-11 09:45:53.000000000","message":"You are right!","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"abffa0eeb1625ab65a16688a65e01be387fe0c13","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                   \u0027is_sort_key\u0027: True,"},{"line_number":102,"context_line":"                   \u0027is_filter\u0027: True},"},{"line_number":103,"context_line":"            HELPER: {\u0027allow_post\u0027: True, \u0027allow_put\u0027: True,"},{"line_number":104,"context_line":"                     \u0027convert_to\u0027: converters.convert_to_string,"},{"line_number":105,"context_line":"                     \u0027validate\u0027: {\u0027type:string\u0027: validators.validate_string},"},{"line_number":106,"context_line":"                     \u0027is_visible\u0027: True,"},{"line_number":107,"context_line":"                     \u0027is_sort_key\u0027: True,"}],"source_content_type":"text/x-python","patch_set":2,"id":"5fc1f717_707e0a6b","line":104,"range":{"start_line":104,"start_character":35,"end_line":104,"end_character":63},"updated":"2019-04-08 15:57:24.000000000","message":"This will be too generic for users to set the right value, right? Can we add some rule resource, like QoS bandwidth rules, security group rules, etc. Then we can bind these rules to the router or floating IP?","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"fb7b59784e429d03127e64aaa671dfb0cbba2a66","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                   \u0027is_sort_key\u0027: True,"},{"line_number":102,"context_line":"                   \u0027is_filter\u0027: True},"},{"line_number":103,"context_line":"            HELPER: {\u0027allow_post\u0027: True, \u0027allow_put\u0027: True,"},{"line_number":104,"context_line":"                     \u0027convert_to\u0027: converters.convert_to_string,"},{"line_number":105,"context_line":"                     \u0027validate\u0027: {\u0027type:string\u0027: validators.validate_string},"},{"line_number":106,"context_line":"                     \u0027is_visible\u0027: True,"},{"line_number":107,"context_line":"                     \u0027is_sort_key\u0027: True,"}],"source_content_type":"text/x-python","patch_set":2,"id":"5fc1f717_63d95481","line":104,"range":{"start_line":104,"start_character":35,"end_line":104,"end_character":63},"in_reply_to":"5fc1f717_12fea0ae","updated":"2019-04-09 07:37:43.000000000","message":"I don\u0027t think we should hardcode the helpers in the API.\nDifferent distributions may ship different set\u0027s of conntrack helpers. Do we want to keep updating this if a new helper is added in an OS distribution? (For example a new module is in Fedora, but it is not in Ubuntu). Or the operator decided to remove a specific conntrack helper module from the deployed operating system according to some security policy.\n\nIt is also possible that an operator need to load a conntrack helper that is not in the kernel tree, i.e a private cloud using a private/internal protocol.\n\nAdditionally a distribution/operator may be loading the module with the ports\u003d option. For example:\n  modprobe nf_conntrack_$PROTO ports\u003d0\n\n^^ will be renaming of the conntrack helper which will be named $PROTO-0.\n\nThe more I think about it, I think we should let the operator choose what is made available to the tenant/user by making the \"constrains\" statically added in https://review.openstack.org/#/c/650270/3/neutron/services/conntrack_helper/plugin.py@50 controlled by an option.","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"cf52271a6b849d0f30cf8c1d7116f35cd4f27bbf","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                   \u0027is_sort_key\u0027: True,"},{"line_number":102,"context_line":"                   \u0027is_filter\u0027: True},"},{"line_number":103,"context_line":"            HELPER: {\u0027allow_post\u0027: True, \u0027allow_put\u0027: True,"},{"line_number":104,"context_line":"                     \u0027convert_to\u0027: converters.convert_to_string,"},{"line_number":105,"context_line":"                     \u0027validate\u0027: {\u0027type:string\u0027: validators.validate_string},"},{"line_number":106,"context_line":"                     \u0027is_visible\u0027: True,"},{"line_number":107,"context_line":"                     \u0027is_sort_key\u0027: True,"}],"source_content_type":"text/x-python","patch_set":2,"id":"5fc1f717_b63b0a9a","line":104,"range":{"start_line":104,"start_character":35,"end_line":104,"end_character":63},"in_reply_to":"5fc1f717_707e0a6b","updated":"2019-04-08 16:51:17.000000000","message":"The \u0027helper\u0027 is just the nf_conntrack_ module alias. i.e \u0027ftp\u0027, \u0027tftp\u0027, \u0027sip\u0027 etc. I also added some constraints in https://review.openstack.org/#/c/650270/3/neutron/services/conntrack_helper/plugin.py@50 to ensure we raise a BadRequest in case the user specifies non-good helper/protocol combination.\n\nI don\u0027t think it is genric at all?\n\nIf the user want to do more granular filtering, like allowing only certain destination net\u0027s etc I think that can be done with security groups?","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"88beaf2350410deabaa92eaf4ba216c805ebda42","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                   \u0027is_sort_key\u0027: True,"},{"line_number":102,"context_line":"                   \u0027is_filter\u0027: True},"},{"line_number":103,"context_line":"            HELPER: {\u0027allow_post\u0027: True, \u0027allow_put\u0027: True,"},{"line_number":104,"context_line":"                     \u0027convert_to\u0027: converters.convert_to_string,"},{"line_number":105,"context_line":"                     \u0027validate\u0027: {\u0027type:string\u0027: validators.validate_string},"},{"line_number":106,"context_line":"                     \u0027is_visible\u0027: True,"},{"line_number":107,"context_line":"                     \u0027is_sort_key\u0027: True,"}],"source_content_type":"text/x-python","patch_set":2,"id":"5fc1f717_12fea0ae","line":104,"range":{"start_line":104,"start_character":35,"end_line":104,"end_character":63},"in_reply_to":"5fc1f717_b63b0a9a","updated":"2019-04-09 03:31:18.000000000","message":"So can we use string choices here? Something like this:\nhttps://github.com/openstack/neutron-lib/blob/master/neutron_lib/api/definitions/qos_bw_minimum_ingress.py#L37","commit_id":"e37037614dd34357a1681b4558f48afce28a79c1"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"b5397753a71e21835e91a009f4afac085108cced","unresolved":false,"context_lines":[{"line_number":74,"context_line":"    COLLECTION_NAME: {"},{"line_number":75,"context_line":"        \u0027parent\u0027: {\u0027collection_name\u0027: PARENT_COLLECTION_NAME,"},{"line_number":76,"context_line":"                   \u0027member_name\u0027: PARENT_RESOURCE_NAME},"},{"line_number":77,"context_line":"        \u0027parameters\u0027: {"},{"line_number":78,"context_line":"            ID: {\u0027allow_post\u0027: False,"},{"line_number":79,"context_line":"                 \u0027allow_put\u0027: False,"},{"line_number":80,"context_line":"                 \u0027validate\u0027: {\u0027type:uuid\u0027: None},"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fce034c_b7b9f1e9","line":77,"updated":"2019-04-17 14:34:36.000000000","message":"It seems like all of these parameters are required. Should we add \u0027required\u0027 to these?","commit_id":"c6b907a2cfa9626260348f07284206ab87e5712d"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"40630bc6985e6d8b4182a7219d77d7bc95d667b5","unresolved":false,"context_lines":[{"line_number":74,"context_line":"    COLLECTION_NAME: {"},{"line_number":75,"context_line":"        \u0027parent\u0027: {\u0027collection_name\u0027: PARENT_COLLECTION_NAME,"},{"line_number":76,"context_line":"                   \u0027member_name\u0027: PARENT_RESOURCE_NAME},"},{"line_number":77,"context_line":"        \u0027parameters\u0027: {"},{"line_number":78,"context_line":"            ID: {\u0027allow_post\u0027: False,"},{"line_number":79,"context_line":"                 \u0027allow_put\u0027: False,"},{"line_number":80,"context_line":"                 \u0027validate\u0027: {\u0027type:uuid\u0027: None},"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fce034c_2b5a6029","line":77,"in_reply_to":"3fce034c_1181dc4a","updated":"2019-04-18 20:47:59.000000000","message":"I didn\u0027t realize the attribute would default to mandatory. This looks good.","commit_id":"c6b907a2cfa9626260348f07284206ab87e5712d"},{"author":{"_account_id":5367,"name":"boden","email":"bodenvmw@gmail.com","username":"boden"},"change_message_id":"1ea3d6d830470e3afb0f23654db4c83dc7d23701","unresolved":false,"context_lines":[{"line_number":74,"context_line":"    COLLECTION_NAME: {"},{"line_number":75,"context_line":"        \u0027parent\u0027: {\u0027collection_name\u0027: PARENT_COLLECTION_NAME,"},{"line_number":76,"context_line":"                   \u0027member_name\u0027: PARENT_RESOURCE_NAME},"},{"line_number":77,"context_line":"        \u0027parameters\u0027: {"},{"line_number":78,"context_line":"            ID: {\u0027allow_post\u0027: False,"},{"line_number":79,"context_line":"                 \u0027allow_put\u0027: False,"},{"line_number":80,"context_line":"                 \u0027validate\u0027: {\u0027type:uuid\u0027: None},"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fce034c_1181dc4a","line":77,"in_reply_to":"3fce034c_36bdf801","updated":"2019-04-18 13:38:31.000000000","message":"If I understand correctly Ryan is asking about the API attributes [1]. As per [1], if \u0027default\u0027 is not specified, the attribute is mandatory (required). So it seems these are all required.\n\n\n[1] https://docs.openstack.org/neutron-lib/latest/contributor/api_attributes.html","commit_id":"c6b907a2cfa9626260348f07284206ab87e5712d"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"80379d8cd95e4e024ab8706610bff4f0fad4a890","unresolved":false,"context_lines":[{"line_number":74,"context_line":"    COLLECTION_NAME: {"},{"line_number":75,"context_line":"        \u0027parent\u0027: {\u0027collection_name\u0027: PARENT_COLLECTION_NAME,"},{"line_number":76,"context_line":"                   \u0027member_name\u0027: PARENT_RESOURCE_NAME},"},{"line_number":77,"context_line":"        \u0027parameters\u0027: {"},{"line_number":78,"context_line":"            ID: {\u0027allow_post\u0027: False,"},{"line_number":79,"context_line":"                 \u0027allow_put\u0027: False,"},{"line_number":80,"context_line":"                 \u0027validate\u0027: {\u0027type:uuid\u0027: None},"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fce034c_36bdf801","line":77,"in_reply_to":"3fce034c_b7b9f1e9","updated":"2019-04-17 23:01:32.000000000","message":"You mean in validate? link in extra_dhcp_opts and some others?\n\nAlso they are only all required on create, not on update.\nI don\u0027t see any required on a subnets \u0027cidr\u0027, but I don\u0027t think that is an optional on create.","commit_id":"c6b907a2cfa9626260348f07284206ab87e5712d"}],"neutron_lib/tests/unit/api/definitions/test_expose_l3_conntrack_helper.py":[{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"88beaf2350410deabaa92eaf4ba216c805ebda42","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from neutron_lib.tests.unit.api.definitions import base"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"class ExposePortForwardingInFip(base.DefinitionBaseTestCase):"},{"line_number":22,"context_line":"    extension_module \u003d expose_l3_conntrack_helper"},{"line_number":23,"context_line":"    extension_resources \u003d (expose_l3_conntrack_helper.COLLECTION_NAME,)"},{"line_number":24,"context_line":"    extension_attributes \u003d (l3_conntrack_helper.COLLECTION_NAME,)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5fc1f717_b20f8cde","line":21,"range":{"start_line":21,"start_character":12,"end_line":21,"end_character":31},"updated":"2019-04-09 03:31:18.000000000","message":"L3ConntrackHelper?","commit_id":"2d3ad9384f02e250b8b65fefcb90ba5a93a8c9fa"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"fb7b59784e429d03127e64aaa671dfb0cbba2a66","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from neutron_lib.tests.unit.api.definitions import base"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"class ExposePortForwardingInFip(base.DefinitionBaseTestCase):"},{"line_number":22,"context_line":"    extension_module \u003d expose_l3_conntrack_helper"},{"line_number":23,"context_line":"    extension_resources \u003d (expose_l3_conntrack_helper.COLLECTION_NAME,)"},{"line_number":24,"context_line":"    extension_attributes \u003d (l3_conntrack_helper.COLLECTION_NAME,)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5fc1f717_989aaf10","line":21,"range":{"start_line":21,"start_character":12,"end_line":21,"end_character":31},"in_reply_to":"5fc1f717_b20f8cde","updated":"2019-04-09 07:37:43.000000000","message":"ooops. thank you!","commit_id":"2d3ad9384f02e250b8b65fefcb90ba5a93a8c9fa"},{"author":{"_account_id":5367,"name":"boden","email":"bodenvmw@gmail.com","username":"boden"},"change_message_id":"2474a810b243f656df8899b7e55bdf30fe075d6e","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from neutron_lib.tests.unit.api.definitions import base"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"class ExposeL3ConntrackHelper(base.DefinitionBaseTestCase):"},{"line_number":22,"context_line":"    extension_module \u003d expose_l3_conntrack_helper"},{"line_number":23,"context_line":"    extension_resources \u003d (expose_l3_conntrack_helper.COLLECTION_NAME,)"},{"line_number":24,"context_line":"    extension_attributes \u003d (l3_conntrack_helper.COLLECTION_NAME,)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5fc1f717_a213adb7","line":21,"range":{"start_line":21,"start_character":6,"end_line":21,"end_character":29},"updated":"2019-04-09 15:13:05.000000000","message":"For consistency do you mind following the naming scheme of the other api def tests?? e.g. add \"DefinitionTestCase\" to the name.","commit_id":"45fa01d744bcec1f38e60e88ecad64aa9a5ced8d"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"2306a5a64c455c68c8e43107ae4f38265f0dc3f4","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from neutron_lib.tests.unit.api.definitions import base"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"class ExposeL3ConntrackHelper(base.DefinitionBaseTestCase):"},{"line_number":22,"context_line":"    extension_module \u003d expose_l3_conntrack_helper"},{"line_number":23,"context_line":"    extension_resources \u003d (expose_l3_conntrack_helper.COLLECTION_NAME,)"},{"line_number":24,"context_line":"    extension_attributes \u003d (l3_conntrack_helper.COLLECTION_NAME,)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fce034c_f2906051","line":21,"range":{"start_line":21,"start_character":6,"end_line":21,"end_character":29},"in_reply_to":"5fc1f717_a213adb7","updated":"2019-04-10 21:03:36.000000000","message":"Done","commit_id":"45fa01d744bcec1f38e60e88ecad64aa9a5ced8d"}],"neutron_lib/tests/unit/api/definitions/test_l3_conntrack_helper.py":[{"author":{"_account_id":5367,"name":"boden","email":"bodenvmw@gmail.com","username":"boden"},"change_message_id":"2474a810b243f656df8899b7e55bdf30fe075d6e","unresolved":false,"context_lines":[{"line_number":17,"context_line":"from neutron_lib.tests.unit.api.definitions import base"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"class ConntrackHelper(base.DefinitionBaseTestCase):"},{"line_number":21,"context_line":"    extension_module \u003d l3_conntrack_helper"},{"line_number":22,"context_line":"    extension_resources \u003d (l3_conntrack_helper.PARENT_COLLECTION_NAME,)"},{"line_number":23,"context_line":"    extension_attributes \u003d (l3_conntrack_helper.ID,"}],"source_content_type":"text/x-python","patch_set":4,"id":"5fc1f717_62094582","line":20,"range":{"start_line":20,"start_character":6,"end_line":20,"end_character":21},"updated":"2019-04-09 15:13:05.000000000","message":"For consistency do you mind following the naming scheme of the other api def tests?? e.g. add \"DefinitionTestCase\" to the name.","commit_id":"45fa01d744bcec1f38e60e88ecad64aa9a5ced8d"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"2306a5a64c455c68c8e43107ae4f38265f0dc3f4","unresolved":false,"context_lines":[{"line_number":17,"context_line":"from neutron_lib.tests.unit.api.definitions import base"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"class ConntrackHelper(base.DefinitionBaseTestCase):"},{"line_number":21,"context_line":"    extension_module \u003d l3_conntrack_helper"},{"line_number":22,"context_line":"    extension_resources \u003d (l3_conntrack_helper.PARENT_COLLECTION_NAME,)"},{"line_number":23,"context_line":"    extension_attributes \u003d (l3_conntrack_helper.ID,"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fce034c_b29ad86b","line":20,"range":{"start_line":20,"start_character":6,"end_line":20,"end_character":21},"in_reply_to":"5fc1f717_62094582","updated":"2019-04-10 21:03:36.000000000","message":"Done","commit_id":"45fa01d744bcec1f38e60e88ecad64aa9a5ced8d"}],"releasenotes/notes/l3_conntrack_helper-f186bcdcc31bcaf2.yaml":[{"author":{"_account_id":5367,"name":"boden","email":"bodenvmw@gmail.com","username":"boden"},"change_message_id":"2474a810b243f656df8899b7e55bdf30fe075d6e","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    The ``conntrack_helpers`` API definition for ``Router`` is introduced,"},{"line_number":5,"context_line":"    which allows conntrack helper target rules to be set for a ``Router``."},{"line_number":6,"context_line":"  - |"},{"line_number":7,"context_line":"    Introduced ``expose-l3-conntrack-helper`` API extension for exposing"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"5fc1f717_4269a922","line":4,"range":{"start_line":4,"start_character":10,"end_line":4,"end_character":27},"updated":"2019-04-09 15:13:05.000000000","message":"Shouldn\u0027t this be the alias; l3-conntrack-helper","commit_id":"45fa01d744bcec1f38e60e88ecad64aa9a5ced8d"},{"author":{"_account_id":24245,"name":"Harald Jensås","email":"hjensas@redhat.com","username":"harald.jensas"},"change_message_id":"2306a5a64c455c68c8e43107ae4f38265f0dc3f4","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    The ``conntrack_helpers`` API definition for ``Router`` is introduced,"},{"line_number":5,"context_line":"    which allows conntrack helper target rules to be set for a ``Router``."},{"line_number":6,"context_line":"  - |"},{"line_number":7,"context_line":"    Introduced ``expose-l3-conntrack-helper`` API extension for exposing"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"3fce034c_528e1428","line":4,"range":{"start_line":4,"start_character":10,"end_line":4,"end_character":27},"in_reply_to":"5fc1f717_4269a922","updated":"2019-04-10 21:03:36.000000000","message":"Done","commit_id":"45fa01d744bcec1f38e60e88ecad64aa9a5ced8d"}]}
