)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"b36101f0773d66d46fa648e598b00a8081add40a","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Add physical network to port data model"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change implements the changes to the port data model required to"},{"line_number":10,"context_line":"support physical network awareness.  This includes updating the ports"},{"line_number":11,"context_line":"table in the database, extending the Port object, and exposing the"},{"line_number":12,"context_line":"fields in the ironic API.  API microversion is bumped to 1.32."},{"line_number":13,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"1f013ff3_a4a043a7","line":10,"range":{"start_line":10,"start_character":35,"end_line":10,"end_character":36},"updated":"2017-05-13 01:51:57.000000000","message":"extra space","commit_id":"0141463cc5cf87b92fbbcbe0309c43ff2ef55be0"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"19e7d29401ea2c20d4676ffe1b5fdb87151f7372","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Add physical network to port data model"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change implements the changes to the port data model required to"},{"line_number":10,"context_line":"support physical network awareness.  This includes updating the ports"},{"line_number":11,"context_line":"table in the database, extending the Port object, and exposing the"},{"line_number":12,"context_line":"fields in the ironic API.  API microversion is bumped to 1.32."},{"line_number":13,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"1f013ff3_607d711b","line":10,"range":{"start_line":10,"start_character":35,"end_line":10,"end_character":36},"in_reply_to":"1f013ff3_a4a043a7","updated":"2017-05-16 10:58:35.000000000","message":"This is quite nitty. Plus it\u0027s a fairly common style to double-space separate sentences.\n\nhttps://en.wikipedia.org/wiki/Sentence_spacing","commit_id":"0141463cc5cf87b92fbbcbe0309c43ff2ef55be0"}],"ironic/api/controllers/v1/port.py":[{"author":{"_account_id":14525,"name":"Vasyl Saienko","email":"vsaienko@mirantis.com","username":"vsaienko"},"change_message_id":"9bd34d359dd322f072aa2123f858836fab348ab7","unresolved":false,"context_lines":[{"line_number":148,"context_line":"    local_link_connection \u003d types.locallinkconnectiontype"},{"line_number":149,"context_line":"    \"\"\"The port binding profile for the port\"\"\""},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"    physical_network \u003d wtypes.text"},{"line_number":152,"context_line":"    \"\"\"The name of the physical network to which this port is connected.\"\"\""},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"    links \u003d wsme.wsattr([link.Link], readonly\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_f527c811","line":151,"updated":"2017-05-07 16:35:09.000000000","message":"This should be a list. For example if tenant networks are mapped to physnet1 and ironic provision network is mapped to physnet2 which is valid setup when different NICs are used for tenant networks on openstack control nodes. By having a single value in the port will not allow to use such setups.","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"b2e61e264285dcda2e9328d7b3b260589a8f87cb","unresolved":false,"context_lines":[{"line_number":148,"context_line":"    local_link_connection \u003d types.locallinkconnectiontype"},{"line_number":149,"context_line":"    \"\"\"The port binding profile for the port\"\"\""},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"    physical_network \u003d wtypes.text"},{"line_number":152,"context_line":"    \"\"\"The name of the physical network to which this port is connected.\"\"\""},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"    links \u003d wsme.wsattr([link.Link], readonly\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_12b6b8da","line":151,"in_reply_to":"3f044301_019d4c58","updated":"2017-05-08 15:47:52.000000000","message":"I think the case for supporting baremetal nodes on multiple physnets either involves hooking up mulitple NICs on the server in each physnet you care about which the new logic will correctly map too, or we work with neutron to add support for routed networks so we\u0027re no longer tied to specific physnets.","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"ae5c70580b5a20f2f188490d6ec584a3e6aa8ac6","unresolved":false,"context_lines":[{"line_number":148,"context_line":"    local_link_connection \u003d types.locallinkconnectiontype"},{"line_number":149,"context_line":"    \"\"\"The port binding profile for the port\"\"\""},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"    physical_network \u003d wtypes.text"},{"line_number":152,"context_line":"    \"\"\"The name of the physical network to which this port is connected.\"\"\""},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"    links \u003d wsme.wsattr([link.Link], readonly\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_f00fbade","line":151,"in_reply_to":"3f044301_12b6b8da","updated":"2017-05-09 08:19:16.000000000","message":"It\u0027s also worth pointing out that the use of this feature isn\u0027t mandatory - ports can be given a null physnet, in which case the scenario that Vasyl described would still work.","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"617bbfed153e19646b89b0dd1638bd4aae6a0960","unresolved":false,"context_lines":[{"line_number":148,"context_line":"    local_link_connection \u003d types.locallinkconnectiontype"},{"line_number":149,"context_line":"    \"\"\"The port binding profile for the port\"\"\""},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"    physical_network \u003d wtypes.text"},{"line_number":152,"context_line":"    \"\"\"The name of the physical network to which this port is connected.\"\"\""},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"    links \u003d wsme.wsattr([link.Link], readonly\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_019d4c58","line":151,"in_reply_to":"3f044301_18a6e111","updated":"2017-05-08 13:07:38.000000000","message":"My understanding of a physnet follows Sam\u0027s - a physical port can be connected to only one physical network.\n\nI think I understand your use case Vasyl, and why that might be desirable but IMHO it is taking advantage of the fact that ironic is not currently physical network-aware.\n\nA better (albeit not currently possible AFAIK) way to achieve this would be to have a more flexible way to map between interfaces, physnets and VLANs on the neutron agent side. Currently for OVS we can map interfaces to physical networks and vlan ranges to physical networks. What we would ideally want would be a mapping from interface to (physnet, VLAN ranges) 2-tuple.\n\nIt\u0027s a shame this didn\u0027t come up during the spec review.","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":14525,"name":"Vasyl Saienko","email":"vsaienko@mirantis.com","username":"vsaienko"},"change_message_id":"58c8e32de28f104dabcbae422adfabf49c819b42","unresolved":false,"context_lines":[{"line_number":148,"context_line":"    local_link_connection \u003d types.locallinkconnectiontype"},{"line_number":149,"context_line":"    \"\"\"The port binding profile for the port\"\"\""},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"    physical_network \u003d wtypes.text"},{"line_number":152,"context_line":"    \"\"\"The name of the physical network to which this port is connected.\"\"\""},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"    links \u003d wsme.wsattr([link.Link], readonly\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_18a6e111","line":151,"in_reply_to":"3f044301_40f35c0b","updated":"2017-05-08 09:32:25.000000000","message":"If I understand correctly physical_network of the ironic will be compared with Neutron network physical_network value by ML2 drivers and if they do not match, such port binding will be rejected.\n\nFrom Neutron standpoint it is normal situation when tenants networks are mapped to physnet1 (eth0) while ironic provision network is mapped to physnet2(eth1). This allows to use different hardware NICs on neutron node for tenant and ironic provision network.\n\nBy making a single value here will require that ironic provision/cleaning networks are always mapped to the same physnet as tenant networks.","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"55c002a53bc24dcf34d8b1a0df768fd447381fb0","unresolved":false,"context_lines":[{"line_number":148,"context_line":"    local_link_connection \u003d types.locallinkconnectiontype"},{"line_number":149,"context_line":"    \"\"\"The port binding profile for the port\"\"\""},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"    physical_network \u003d wtypes.text"},{"line_number":152,"context_line":"    \"\"\"The name of the physical network to which this port is connected.\"\"\""},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"    links \u003d wsme.wsattr([link.Link], readonly\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_40f35c0b","line":151,"in_reply_to":"3f044301_f527c811","updated":"2017-05-07 18:28:33.000000000","message":"A physical NIC being connected to more than one physnet is an impossibility, being able to connect a NIC to more than one physnet breaks the definition of a physnet.","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"ae5c70580b5a20f2f188490d6ec584a3e6aa8ac6","unresolved":false,"context_lines":[{"line_number":514,"context_line":"            raise exception.NotAcceptable()"},{"line_number":515,"context_line":"        if (not api_utils.allow_port_physical_network() and"},{"line_number":516,"context_line":"            \u0027physical_network\u0027 in pdict):"},{"line_number":517,"context_line":"            raise exception.NotAcceptable()"},{"line_number":518,"context_line":""},{"line_number":519,"context_line":"        extra \u003d pdict.get(\u0027extra\u0027)"},{"line_number":520,"context_line":"        vif \u003d extra.get(\u0027vif_port_id\u0027) if extra else None"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_b0e7f212","line":517,"updated":"2017-05-09 08:19:16.000000000","message":"This is actually the same logic as in check_allowed_port_fields().","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"d6fbd53a6e9e43aa939345577c5fd2f1ad0f3810","unresolved":false,"context_lines":[{"line_number":514,"context_line":"            raise exception.NotAcceptable()"},{"line_number":515,"context_line":"        if (not api_utils.allow_port_physical_network() and"},{"line_number":516,"context_line":"            \u0027physical_network\u0027 in pdict):"},{"line_number":517,"context_line":"            raise exception.NotAcceptable()"},{"line_number":518,"context_line":""},{"line_number":519,"context_line":"        extra \u003d pdict.get(\u0027extra\u0027)"},{"line_number":520,"context_line":"        vif \u003d extra.get(\u0027vif_port_id\u0027) if extra else None"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_65d643c6","line":517,"in_reply_to":"3f044301_b0e7f212","updated":"2017-05-09 18:28:50.000000000","message":"Done","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"53563b76272c9fa150adab02e081e4b96c6b575b","unresolved":false,"context_lines":[{"line_number":554,"context_line":"    @METRICS.timer(\u0027PortsController.patch\u0027)"},{"line_number":555,"context_line":"    @wsme.validate(types.uuid, [PortPatchType])"},{"line_number":556,"context_line":"    @expose.expose(Port, types.uuid, body\u003d[PortPatchType])"},{"line_number":557,"context_line":"    def patch(self, port_uuid, patch):"},{"line_number":558,"context_line":"        \"\"\"Update an existing port."},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        :param port_uuid: UUID of a port."}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_15c0df4f","line":557,"range":{"start_line":557,"start_character":8,"end_line":557,"end_character":13},"updated":"2017-05-08 19:14:26.000000000","message":"Should it be allowed to have op:remove on physical_network?","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"45e478b5af1cbe59ae786e34bff6ca936fb949df","unresolved":false,"context_lines":[{"line_number":554,"context_line":"    @METRICS.timer(\u0027PortsController.patch\u0027)"},{"line_number":555,"context_line":"    @wsme.validate(types.uuid, [PortPatchType])"},{"line_number":556,"context_line":"    @expose.expose(Port, types.uuid, body\u003d[PortPatchType])"},{"line_number":557,"context_line":"    def patch(self, port_uuid, patch):"},{"line_number":558,"context_line":"        \"\"\"Update an existing port."},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        :param port_uuid: UUID of a port."}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_cd1087ab","line":557,"range":{"start_line":557,"start_character":8,"end_line":557,"end_character":13},"in_reply_to":"3f044301_05f1bf6b","updated":"2017-05-10 20:34:26.000000000","message":"Thanks","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"ae5c70580b5a20f2f188490d6ec584a3e6aa8ac6","unresolved":false,"context_lines":[{"line_number":554,"context_line":"    @METRICS.timer(\u0027PortsController.patch\u0027)"},{"line_number":555,"context_line":"    @wsme.validate(types.uuid, [PortPatchType])"},{"line_number":556,"context_line":"    @expose.expose(Port, types.uuid, body\u003d[PortPatchType])"},{"line_number":557,"context_line":"    def patch(self, port_uuid, patch):"},{"line_number":558,"context_line":"        \"\"\"Update an existing port."},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        :param port_uuid: UUID of a port."}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_7003aab9","line":557,"range":{"start_line":557,"start_character":8,"end_line":557,"end_character":13},"in_reply_to":"3f044301_15c0df4f","updated":"2017-05-09 08:19:16.000000000","message":"The physical network field can be null, and using op:remove will set it to null. Does that seem reasonable?","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"a730858d1d2ac413ba79a4c687f521f295a284f4","unresolved":false,"context_lines":[{"line_number":554,"context_line":"    @METRICS.timer(\u0027PortsController.patch\u0027)"},{"line_number":555,"context_line":"    @wsme.validate(types.uuid, [PortPatchType])"},{"line_number":556,"context_line":"    @expose.expose(Port, types.uuid, body\u003d[PortPatchType])"},{"line_number":557,"context_line":"    def patch(self, port_uuid, patch):"},{"line_number":558,"context_line":"        \"\"\"Update an existing port."},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        :param port_uuid: UUID of a port."}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_85414f3c","line":557,"range":{"start_line":557,"start_character":8,"end_line":557,"end_character":13},"in_reply_to":"3f044301_6af5f282","updated":"2017-05-09 17:50:13.000000000","message":"That\u0027s a good point. I think we should do whatever is done for other similar fields (link_local_connection, pxe_enabled, etc.). There is some logic in the conductor to prevent changes to these fields when the node is not in enroll, inspecting, manageable. I\u0027ll extend this to include the physical network.","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"b84452e1e592aa399551fc3e6e4d906ebe6bcf1d","unresolved":false,"context_lines":[{"line_number":554,"context_line":"    @METRICS.timer(\u0027PortsController.patch\u0027)"},{"line_number":555,"context_line":"    @wsme.validate(types.uuid, [PortPatchType])"},{"line_number":556,"context_line":"    @expose.expose(Port, types.uuid, body\u003d[PortPatchType])"},{"line_number":557,"context_line":"    def patch(self, port_uuid, patch):"},{"line_number":558,"context_line":"        \"\"\"Update an existing port."},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        :param port_uuid: UUID of a port."}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_ea3a2296","line":557,"range":{"start_line":557,"start_character":8,"end_line":557,"end_character":13},"in_reply_to":"3f044301_7003aab9","updated":"2017-05-09 17:04:04.000000000","message":"But then there will be port mapped to no physnet at all, correct me if I have understood it wrong","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"d6fbd53a6e9e43aa939345577c5fd2f1ad0f3810","unresolved":false,"context_lines":[{"line_number":554,"context_line":"    @METRICS.timer(\u0027PortsController.patch\u0027)"},{"line_number":555,"context_line":"    @wsme.validate(types.uuid, [PortPatchType])"},{"line_number":556,"context_line":"    @expose.expose(Port, types.uuid, body\u003d[PortPatchType])"},{"line_number":557,"context_line":"    def patch(self, port_uuid, patch):"},{"line_number":558,"context_line":"        \"\"\"Update an existing port."},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        :param port_uuid: UUID of a port."}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_05f1bf6b","line":557,"range":{"start_line":557,"start_character":8,"end_line":557,"end_character":13},"in_reply_to":"3f044301_85414f3c","updated":"2017-05-09 18:28:50.000000000","message":"Done","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"8819643c581e7558beef5e1f118c096853faf80e","unresolved":false,"context_lines":[{"line_number":554,"context_line":"    @METRICS.timer(\u0027PortsController.patch\u0027)"},{"line_number":555,"context_line":"    @wsme.validate(types.uuid, [PortPatchType])"},{"line_number":556,"context_line":"    @expose.expose(Port, types.uuid, body\u003d[PortPatchType])"},{"line_number":557,"context_line":"    def patch(self, port_uuid, patch):"},{"line_number":558,"context_line":"        \"\"\"Update an existing port."},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        :param port_uuid: UUID of a port."}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_6af5f282","line":557,"range":{"start_line":557,"start_character":8,"end_line":557,"end_character":13},"in_reply_to":"3f044301_aae09afb","updated":"2017-05-09 17:26:11.000000000","message":"Ok, but consider for e.g. an active ironic node having port connected to physnet and remove operation will then leave that node not connected to any physnet. Shouldn\u0027t this scenario be avoided, wdyt?","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"52a25ad58b552ae9750f756f3efd5d6f21d42ca6","unresolved":false,"context_lines":[{"line_number":554,"context_line":"    @METRICS.timer(\u0027PortsController.patch\u0027)"},{"line_number":555,"context_line":"    @wsme.validate(types.uuid, [PortPatchType])"},{"line_number":556,"context_line":"    @expose.expose(Port, types.uuid, body\u003d[PortPatchType])"},{"line_number":557,"context_line":"    def patch(self, port_uuid, patch):"},{"line_number":558,"context_line":"        \"\"\"Update an existing port."},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        :param port_uuid: UUID of a port."}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_aae09afb","line":557,"range":{"start_line":557,"start_character":8,"end_line":557,"end_character":13},"in_reply_to":"3f044301_ea3a2296","updated":"2017-05-09 17:09:28.000000000","message":"That\u0027s correct. This is to ensure backwards compatibility with previous versions that are not physnet-aware.","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"53563b76272c9fa150adab02e081e4b96c6b575b","unresolved":false,"context_lines":[{"line_number":569,"context_line":"            raise exception.OperationNotPermitted()"},{"line_number":570,"context_line":""},{"line_number":571,"context_line":"        fields_to_check \u003d set()"},{"line_number":572,"context_line":"        for field in (self.advanced_net_fields +"},{"line_number":573,"context_line":"                      [\u0027portgroup_uuid\u0027, \u0027physical_network\u0027]):"},{"line_number":574,"context_line":"            field_path \u003d \u0027/%s\u0027 % field"},{"line_number":575,"context_line":"            if (api_utils.get_patch_values(patch, field_path) or"},{"line_number":576,"context_line":"                    api_utils.is_path_removed(patch, field_path)):"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_b53c8bc8","line":573,"range":{"start_line":572,"start_character":22,"end_line":573,"end_character":61},"updated":"2017-05-08 19:14:26.000000000","message":"do you think we should replace the \u0027advanced_net_fields\u0027 dict with new dict having all fields in advanced_net_fields + portgroup_uuid and physnet?","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"ae5c70580b5a20f2f188490d6ec584a3e6aa8ac6","unresolved":false,"context_lines":[{"line_number":569,"context_line":"            raise exception.OperationNotPermitted()"},{"line_number":570,"context_line":""},{"line_number":571,"context_line":"        fields_to_check \u003d set()"},{"line_number":572,"context_line":"        for field in (self.advanced_net_fields +"},{"line_number":573,"context_line":"                      [\u0027portgroup_uuid\u0027, \u0027physical_network\u0027]):"},{"line_number":574,"context_line":"            field_path \u003d \u0027/%s\u0027 % field"},{"line_number":575,"context_line":"            if (api_utils.get_patch_values(patch, field_path) or"},{"line_number":576,"context_line":"                    api_utils.is_path_removed(patch, field_path)):"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_f028da34","line":573,"range":{"start_line":572,"start_character":22,"end_line":573,"end_character":61},"in_reply_to":"3f044301_b53c8bc8","updated":"2017-05-09 08:19:16.000000000","message":"advanced_net_fields is used for microversion checks in combination with api_utils.allow_port_advanced_net_fields() so I think it\u0027s best to keep it as it is.","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"b84452e1e592aa399551fc3e6e4d906ebe6bcf1d","unresolved":false,"context_lines":[{"line_number":569,"context_line":"            raise exception.OperationNotPermitted()"},{"line_number":570,"context_line":""},{"line_number":571,"context_line":"        fields_to_check \u003d set()"},{"line_number":572,"context_line":"        for field in (self.advanced_net_fields +"},{"line_number":573,"context_line":"                      [\u0027portgroup_uuid\u0027, \u0027physical_network\u0027]):"},{"line_number":574,"context_line":"            field_path \u003d \u0027/%s\u0027 % field"},{"line_number":575,"context_line":"            if (api_utils.get_patch_values(patch, field_path) or"},{"line_number":576,"context_line":"                    api_utils.is_path_removed(patch, field_path)):"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_0a61cea9","line":573,"range":{"start_line":572,"start_character":22,"end_line":573,"end_character":61},"in_reply_to":"3f044301_f028da34","updated":"2017-05-09 17:04:04.000000000","message":"I see, yes then makes sense to keep as is. :)","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"ae5c70580b5a20f2f188490d6ec584a3e6aa8ac6","unresolved":false,"context_lines":[{"line_number":583,"context_line":"            raise exception.NotAcceptable()"},{"line_number":584,"context_line":"        if (\u0027physical_network\u0027 in fields_to_check and"},{"line_number":585,"context_line":"                not api_utils.allow_port_physical_network()):"},{"line_number":586,"context_line":"            raise exception.NotAcceptable()"},{"line_number":587,"context_line":""},{"line_number":588,"context_line":"        rpc_port \u003d objects.Port.get_by_uuid(context, port_uuid)"},{"line_number":589,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_70f16acd","line":586,"updated":"2017-05-09 08:19:16.000000000","message":"This is actually the same logic as in check_allowed_port_fields().","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"d6fbd53a6e9e43aa939345577c5fd2f1ad0f3810","unresolved":false,"context_lines":[{"line_number":583,"context_line":"            raise exception.NotAcceptable()"},{"line_number":584,"context_line":"        if (\u0027physical_network\u0027 in fields_to_check and"},{"line_number":585,"context_line":"                not api_utils.allow_port_physical_network()):"},{"line_number":586,"context_line":"            raise exception.NotAcceptable()"},{"line_number":587,"context_line":""},{"line_number":588,"context_line":"        rpc_port \u003d objects.Port.get_by_uuid(context, port_uuid)"},{"line_number":589,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f044301_a5ed6b8c","line":586,"in_reply_to":"3f044301_70f16acd","updated":"2017-05-09 18:28:50.000000000","message":"Done","commit_id":"2e76fbef89a342913c615368e438c5bd59f1143a"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"8f5806a97874cf84e583c703083957b382a64c78","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    # Sanity check that all existing ports in the group have the same"},{"line_number":73,"context_line":"    # physical network."},{"line_number":74,"context_line":"    pg_physnets \u003d {port.physical_network for port in pg_ports}"},{"line_number":75,"context_line":"    if len(pg_physnets) \u003e 1:"},{"line_number":76,"context_line":"        msg \u003d _(\"Port group %(portgroup)s has existing member ports with \""},{"line_number":77,"context_line":"                \"different physical networks: %(physnets)s. All ports \""},{"line_number":78,"context_line":"                \"in a port group must have the same physical network.\")"},{"line_number":79,"context_line":"        raise exception.Conflict("},{"line_number":80,"context_line":"            msg % {\u0027portgroup\u0027: portgroup.uuid,"},{"line_number":81,"context_line":"                   \u0027physnets\u0027: \", \".join(pg_physnets)})"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    if not pg_physnets:"},{"line_number":84,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":4,"id":"1f013ff3_67a8c2da","line":81,"range":{"start_line":74,"start_character":0,"end_line":81,"end_character":55},"updated":"2017-05-16 14:37:12.000000000","message":"Seems like an impossible situation to exist, but maybe worth checking anyway...","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"c9d2a542b4bc47308831648c17f0080cfb11a405","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    # Sanity check that all existing ports in the group have the same"},{"line_number":73,"context_line":"    # physical network."},{"line_number":74,"context_line":"    pg_physnets \u003d {port.physical_network for port in pg_ports}"},{"line_number":75,"context_line":"    if len(pg_physnets) \u003e 1:"},{"line_number":76,"context_line":"        msg \u003d _(\"Port group %(portgroup)s has existing member ports with \""},{"line_number":77,"context_line":"                \"different physical networks: %(physnets)s. All ports \""},{"line_number":78,"context_line":"                \"in a port group must have the same physical network.\")"},{"line_number":79,"context_line":"        raise exception.Conflict("},{"line_number":80,"context_line":"            msg % {\u0027portgroup\u0027: portgroup.uuid,"},{"line_number":81,"context_line":"                   \u0027physnets\u0027: \", \".join(pg_physnets)})"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    if not pg_physnets:"},{"line_number":84,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_055d5579","line":81,"range":{"start_line":74,"start_character":0,"end_line":81,"end_character":55},"in_reply_to":"1f013ff3_67a8c2da","updated":"2017-05-20 07:43:45.000000000","message":"There is a race that allows it to happen if two separate API calls concurrently create or update ports in a group. The simplest case to consider is two calls adding ports to an empty portgroup. It\u0027s quite an edge case though.\n\nOne way around that might be to move this check to the conductor where the node is locked, but that would require a new create_port method and more complexity. Alternatively, we could add a check to network.validate() as you suggested. That would be driver-specific however.","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"8eb59603bf08408ebc1a15aaaaa01e7d0b326982","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    # Sanity check that all existing ports in the group have the same"},{"line_number":73,"context_line":"    # physical network."},{"line_number":74,"context_line":"    pg_physnets \u003d {port.physical_network for port in pg_ports}"},{"line_number":75,"context_line":"    if len(pg_physnets) \u003e 1:"},{"line_number":76,"context_line":"        msg \u003d _(\"Port group %(portgroup)s has existing member ports with \""},{"line_number":77,"context_line":"                \"different physical networks: %(physnets)s. All ports \""},{"line_number":78,"context_line":"                \"in a port group must have the same physical network.\")"},{"line_number":79,"context_line":"        raise exception.Conflict("},{"line_number":80,"context_line":"            msg % {\u0027portgroup\u0027: portgroup.uuid,"},{"line_number":81,"context_line":"                   \u0027physnets\u0027: \", \".join(pg_physnets)})"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    if not pg_physnets:"},{"line_number":84,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_8aecbb8f","line":81,"range":{"start_line":74,"start_character":0,"end_line":81,"end_character":55},"in_reply_to":"ff0f0b1f_055d5579","updated":"2017-05-22 11:20:16.000000000","message":"Man this is a tough one, I think the only way to avoid this is to use a lock or only enforce this asynchronously using validate :/\n\n\nThese are the solutions I see from here are either:\n\n1) Lock on the portgroup using a new locked:true/false DB field, and then check the physical networks and add the ports while locked. We could do this without going down to the conductor I think.\n\n2) Check everything to do with physical networks and portgroup membership in the neutron network interfaces validate functions and not in the API because its the neutron definition of a physical network that we\u0027re enforcing and different drivers might have different interpretations of what physical_network means. Also I think we\u0027re going to have to validate this scenario in the network interfaces anyway because if this race is possible it needs to be checked before we attach a vif to this misconfigured portgroup\n\n\nWDYT?","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"164123f5483fba7b81fa2ce7f064ddf1cc0fdb5e","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    # Sanity check that all existing ports in the group have the same"},{"line_number":73,"context_line":"    # physical network."},{"line_number":74,"context_line":"    pg_physnets \u003d {port.physical_network for port in pg_ports}"},{"line_number":75,"context_line":"    if len(pg_physnets) \u003e 1:"},{"line_number":76,"context_line":"        msg \u003d _(\"Port group %(portgroup)s has existing member ports with \""},{"line_number":77,"context_line":"                \"different physical networks: %(physnets)s. All ports \""},{"line_number":78,"context_line":"                \"in a port group must have the same physical network.\")"},{"line_number":79,"context_line":"        raise exception.Conflict("},{"line_number":80,"context_line":"            msg % {\u0027portgroup\u0027: portgroup.uuid,"},{"line_number":81,"context_line":"                   \u0027physnets\u0027: \", \".join(pg_physnets)})"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    if not pg_physnets:"},{"line_number":84,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_f50744c9","line":81,"range":{"start_line":74,"start_character":0,"end_line":81,"end_character":55},"in_reply_to":"ff0f0b1f_8aecbb8f","updated":"2017-05-24 14:12:20.000000000","message":"Given that this can be resolved easily enough by a user and should only happen following a user error/mistake *and* a race between concurrent API calls, I\u0027d be inclined to go with 2). \n\nThe main drawback I see is that the validation then becomes driver specific, but it should be possible to put the check in the common network driver to mitigate that to some extent.\n\nThoughts?","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"c26bedf471311e1e03fd8e68df0c6ed20455571e","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    # Sanity check that all existing ports in the group have the same"},{"line_number":73,"context_line":"    # physical network."},{"line_number":74,"context_line":"    pg_physnets \u003d {port.physical_network for port in pg_ports}"},{"line_number":75,"context_line":"    if len(pg_physnets) \u003e 1:"},{"line_number":76,"context_line":"        msg \u003d _(\"Port group %(portgroup)s has existing member ports with \""},{"line_number":77,"context_line":"                \"different physical networks: %(physnets)s. All ports \""},{"line_number":78,"context_line":"                \"in a port group must have the same physical network.\")"},{"line_number":79,"context_line":"        raise exception.Conflict("},{"line_number":80,"context_line":"            msg % {\u0027portgroup\u0027: portgroup.uuid,"},{"line_number":81,"context_line":"                   \u0027physnets\u0027: \", \".join(pg_physnets)})"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    if not pg_physnets:"},{"line_number":84,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_e7331761","line":81,"range":{"start_line":74,"start_character":0,"end_line":81,"end_character":55},"in_reply_to":"ff0f0b1f_956ec8fd","updated":"2017-05-24 14:50:34.000000000","message":"No problem! These things are never as simple as they first seem. Better to get it right now.","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"265b981735c1291d25a729c65cb915e574bdb18b","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    # Sanity check that all existing ports in the group have the same"},{"line_number":73,"context_line":"    # physical network."},{"line_number":74,"context_line":"    pg_physnets \u003d {port.physical_network for port in pg_ports}"},{"line_number":75,"context_line":"    if len(pg_physnets) \u003e 1:"},{"line_number":76,"context_line":"        msg \u003d _(\"Port group %(portgroup)s has existing member ports with \""},{"line_number":77,"context_line":"                \"different physical networks: %(physnets)s. All ports \""},{"line_number":78,"context_line":"                \"in a port group must have the same physical network.\")"},{"line_number":79,"context_line":"        raise exception.Conflict("},{"line_number":80,"context_line":"            msg % {\u0027portgroup\u0027: portgroup.uuid,"},{"line_number":81,"context_line":"                   \u0027physnets\u0027: \", \".join(pg_physnets)})"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    if not pg_physnets:"},{"line_number":84,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_ea7cfe72","line":81,"range":{"start_line":74,"start_character":0,"end_line":81,"end_character":55},"in_reply_to":"ff0f0b1f_e7331761","updated":"2017-05-24 15:05:48.000000000","message":"Thinking about it, the validation could be added as a separate change from this one given that we\u0027re not actually using these fields yet.\n\nOTOH...\n\nJust to backtrack a little, are there any unforeseen consequences of allowing porgroups to become inconsistent? Perhaps in terms of additional logic required by other services that may be dependent upon these fields to handle inconsistent port groups? Or if we do add an API to batch get/set the physical network for all ports in a group, what would we return if a portgroup is inconsistent?\n\nI guess the point is, if we brush away the complexity here does it land somewhere else less appropriate?\n\nGiven that portgroups are assigned to nodes, and port updates already acquire a write lock on the node, perhaps adding a create_port RPC to the conductor wouldn\u0027t be so bad after all.\n\nThoughts?","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"633392d522a29974d8ff6f0a4d46ba625dcf2269","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    # Sanity check that all existing ports in the group have the same"},{"line_number":73,"context_line":"    # physical network."},{"line_number":74,"context_line":"    pg_physnets \u003d {port.physical_network for port in pg_ports}"},{"line_number":75,"context_line":"    if len(pg_physnets) \u003e 1:"},{"line_number":76,"context_line":"        msg \u003d _(\"Port group %(portgroup)s has existing member ports with \""},{"line_number":77,"context_line":"                \"different physical networks: %(physnets)s. All ports \""},{"line_number":78,"context_line":"                \"in a port group must have the same physical network.\")"},{"line_number":79,"context_line":"        raise exception.Conflict("},{"line_number":80,"context_line":"            msg % {\u0027portgroup\u0027: portgroup.uuid,"},{"line_number":81,"context_line":"                   \u0027physnets\u0027: \", \".join(pg_physnets)})"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    if not pg_physnets:"},{"line_number":84,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_956ec8fd","line":81,"range":{"start_line":74,"start_character":0,"end_line":81,"end_character":55},"in_reply_to":"ff0f0b1f_f50744c9","updated":"2017-05-24 14:27:15.000000000","message":"I think that is probably the best course of action, we already have a bunch of common code between network interfaces so I think we should be able to hook it in somewhere there. Thanks for baring with this Mark :D","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"a431b8e0e3c09a4f4463d92a5aa1cf8a7bbe7c4f","unresolved":false,"context_lines":[{"line_number":80,"context_line":"            msg % {\u0027portgroup\u0027: portgroup.uuid,"},{"line_number":81,"context_line":"                   \u0027physnets\u0027: \", \".join(pg_physnets)})"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    if not pg_physnets:"},{"line_number":84,"context_line":"        return"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    # Check that the port has the same physical network as any existing"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_b264b4e5","line":83,"range":{"start_line":83,"start_character":4,"end_line":83,"end_character":23},"updated":"2017-05-20 00:34:11.000000000","message":"Can this happen (may be i am missing some scenario)? Or is this for backward compatibility?","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"c9d2a542b4bc47308831648c17f0080cfb11a405","unresolved":false,"context_lines":[{"line_number":80,"context_line":"            msg % {\u0027portgroup\u0027: portgroup.uuid,"},{"line_number":81,"context_line":"                   \u0027physnets\u0027: \", \".join(pg_physnets)})"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    if not pg_physnets:"},{"line_number":84,"context_line":"        return"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    # Check that the port has the same physical network as any existing"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_050f9589","line":83,"range":{"start_line":83,"start_character":4,"end_line":83,"end_character":23},"in_reply_to":"ff0f0b1f_b264b4e5","updated":"2017-05-20 07:43:45.000000000","message":"If we\u0027re adding a port to an empty portgroup there will be no physnet associated with the portgroup.","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"a431b8e0e3c09a4f4463d92a5aa1cf8a7bbe7c4f","unresolved":false,"context_lines":[{"line_number":455,"context_line":"    @expose.expose(PortCollection, types.uuid_or_name, types.uuid,"},{"line_number":456,"context_line":"                   types.macaddress, types.uuid, int, wtypes.text,"},{"line_number":457,"context_line":"                   wtypes.text, types.uuid_or_name)"},{"line_number":458,"context_line":"    def detail(self, node\u003dNone, node_uuid\u003dNone, address\u003dNone, marker\u003dNone,"},{"line_number":459,"context_line":"               limit\u003dNone, sort_key\u003d\u0027id\u0027, sort_dir\u003d\u0027asc\u0027, portgroup\u003dNone):"},{"line_number":460,"context_line":"        \"\"\"Retrieve a list of ports with detail."},{"line_number":461,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_52f4385b","line":458,"range":{"start_line":458,"start_character":8,"end_line":458,"end_character":14},"updated":"2017-05-20 00:34:11.000000000","message":"any plan for adding the physnet detail on this API call?","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"c9d2a542b4bc47308831648c17f0080cfb11a405","unresolved":false,"context_lines":[{"line_number":455,"context_line":"    @expose.expose(PortCollection, types.uuid_or_name, types.uuid,"},{"line_number":456,"context_line":"                   types.macaddress, types.uuid, int, wtypes.text,"},{"line_number":457,"context_line":"                   wtypes.text, types.uuid_or_name)"},{"line_number":458,"context_line":"    def detail(self, node\u003dNone, node_uuid\u003dNone, address\u003dNone, marker\u003dNone,"},{"line_number":459,"context_line":"               limit\u003dNone, sort_key\u003d\u0027id\u0027, sort_dir\u003d\u0027asc\u0027, portgroup\u003dNone):"},{"line_number":460,"context_line":"        \"\"\"Retrieve a list of ports with detail."},{"line_number":461,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_c5563d5d","line":458,"range":{"start_line":458,"start_character":8,"end_line":458,"end_character":14},"in_reply_to":"ff0f0b1f_52f4385b","updated":"2017-05-20 07:43:45.000000000","message":"Physnet is returned by this call automatically thanks to the Port object. The arguments accepted by this method are to used lookup by MAC, node, portgroup etc. I don\u0027t think we need a lookup by physnet at this stage, do you?","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"8f5806a97874cf84e583c703083957b382a64c78","unresolved":false,"context_lines":[{"line_number":642,"context_line":""},{"line_number":643,"context_line":"        physnet_fields \u003d {\u0027portgroup_id\u0027, \u0027physical_network\u0027}"},{"line_number":644,"context_line":"        if (rpc_port.portgroup_id is not None and"},{"line_number":645,"context_line":"                rpc_port.obj_what_changed() \u0026 physnet_fields):"},{"line_number":646,"context_line":"            rpc_pg \u003d objects.Portgroup.get_by_id(context,"},{"line_number":647,"context_line":"                                                 rpc_port.portgroup_id)"},{"line_number":648,"context_line":"            _validate_portgroup_physnet(rpc_pg, rpc_port.physical_network)"}],"source_content_type":"text/x-python","patch_set":4,"id":"1f013ff3_a72b6a80","line":645,"range":{"start_line":645,"start_character":16,"end_line":645,"end_character":60},"updated":"2017-05-16 14:37:12.000000000","message":"This is cool, TIL this syntax! NIT: might need a comment to explain what your using it for, so people don\u0027t need to look it up.","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"a431b8e0e3c09a4f4463d92a5aa1cf8a7bbe7c4f","unresolved":false,"context_lines":[{"line_number":642,"context_line":""},{"line_number":643,"context_line":"        physnet_fields \u003d {\u0027portgroup_id\u0027, \u0027physical_network\u0027}"},{"line_number":644,"context_line":"        if (rpc_port.portgroup_id is not None and"},{"line_number":645,"context_line":"                rpc_port.obj_what_changed() \u0026 physnet_fields):"},{"line_number":646,"context_line":"            rpc_pg \u003d objects.Portgroup.get_by_id(context,"},{"line_number":647,"context_line":"                                                 rpc_port.portgroup_id)"},{"line_number":648,"context_line":"            _validate_portgroup_physnet(rpc_pg, rpc_port.physical_network)"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_92a89077","line":645,"range":{"start_line":645,"start_character":16,"end_line":645,"end_character":60},"in_reply_to":"1f013ff3_a72b6a80","updated":"2017-05-20 00:34:11.000000000","message":"+1, like this way of check","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"c9d2a542b4bc47308831648c17f0080cfb11a405","unresolved":false,"context_lines":[{"line_number":642,"context_line":""},{"line_number":643,"context_line":"        physnet_fields \u003d {\u0027portgroup_id\u0027, \u0027physical_network\u0027}"},{"line_number":644,"context_line":"        if (rpc_port.portgroup_id is not None and"},{"line_number":645,"context_line":"                rpc_port.obj_what_changed() \u0026 physnet_fields):"},{"line_number":646,"context_line":"            rpc_pg \u003d objects.Portgroup.get_by_id(context,"},{"line_number":647,"context_line":"                                                 rpc_port.portgroup_id)"},{"line_number":648,"context_line":"            _validate_portgroup_physnet(rpc_pg, rpc_port.physical_network)"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_654bf1af","line":645,"range":{"start_line":645,"start_character":16,"end_line":645,"end_character":60},"in_reply_to":"ff0f0b1f_92a89077","updated":"2017-05-20 07:43:45.000000000","message":":) I\u0027ll call a comment.","commit_id":"aad249bf5a8731df5567d4164cd631b6df10f0e3"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"0e735a21d813920e34dcfa4a98d1c701942bf508","unresolved":false,"context_lines":[{"line_number":373,"context_line":"            raise exception.NotAcceptable()"},{"line_number":374,"context_line":"        # NOTE(mgoddard): The physical network attribute is not yet exposed by"},{"line_number":375,"context_line":"        # the API."},{"line_number":376,"context_line":"        if \u0027physical_network\u0027 in fields:"},{"line_number":377,"context_line":"            raise exception.NotAcceptable()"},{"line_number":378,"context_line":""},{"line_number":379,"context_line":"    @METRICS.timer(\u0027PortsController.get_all\u0027)"},{"line_number":380,"context_line":"    @expose.expose(PortCollection, types.uuid_or_name, types.uuid,"}],"source_content_type":"text/x-python","patch_set":7,"id":"df140735_5979e42c","line":377,"range":{"start_line":376,"start_character":8,"end_line":377,"end_character":43},"updated":"2017-06-01 17:29:57.000000000","message":"I don\u0027t think it\u0027s needed, it is not present in API port object, so you\u0027ll not be able neither to create a port with this field, nor update a port setting this value.","commit_id":"827968707d7966b68a17d60e79f2208624abca19"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"6c50dd6f61ee1f7bf67ab16b8f875c2250a8ccc6","unresolved":false,"context_lines":[{"line_number":373,"context_line":"            raise exception.NotAcceptable()"},{"line_number":374,"context_line":"        # NOTE(mgoddard): The physical network attribute is not yet exposed by"},{"line_number":375,"context_line":"        # the API."},{"line_number":376,"context_line":"        if \u0027physical_network\u0027 in fields:"},{"line_number":377,"context_line":"            raise exception.NotAcceptable()"},{"line_number":378,"context_line":""},{"line_number":379,"context_line":"    @METRICS.timer(\u0027PortsController.get_all\u0027)"},{"line_number":380,"context_line":"    @expose.expose(PortCollection, types.uuid_or_name, types.uuid,"}],"source_content_type":"text/x-python","patch_set":7,"id":"df140735_51c4065f","line":377,"range":{"start_line":376,"start_character":8,"end_line":377,"end_character":43},"in_reply_to":"df140735_5979e42c","updated":"2017-06-02 09:15:42.000000000","message":"Good spot. This actually gets caught by check_for_invalid_fields() in Port.convert_with_links().","commit_id":"827968707d7966b68a17d60e79f2208624abca19"}],"ironic/conductor/manager.py":[{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"b36101f0773d66d46fa648e598b00a8081add40a","unresolved":false,"context_lines":[{"line_number":1884,"context_line":"                                                           \u0027port\u0027: port_uuid})"},{"line_number":1885,"context_line":""},{"line_number":1886,"context_line":"            # If port update is modifying the portgroup membership of the port"},{"line_number":1887,"context_line":"            # or modifying the local_link_connection or pxe_enabled flags then"},{"line_number":1888,"context_line":"            # node should be in MANAGEABLE/INSPECTING/ENROLL provisioning state"},{"line_number":1889,"context_line":"            # or in maintenance mode."},{"line_number":1890,"context_line":"            # Otherwise InvalidState exception is raised."},{"line_number":1891,"context_line":"            connectivity_attr \u003d {\u0027portgroup_id\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f013ff3_24f8b3c2","line":1888,"range":{"start_line":1887,"start_character":67,"end_line":1888,"end_character":79},"updated":"2017-05-13 01:51:57.000000000","message":"missed to add physnet here","commit_id":"0141463cc5cf87b92fbbcbe0309c43ff2ef55be0"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"19e7d29401ea2c20d4676ffe1b5fdb87151f7372","unresolved":false,"context_lines":[{"line_number":1884,"context_line":"                                                           \u0027port\u0027: port_uuid})"},{"line_number":1885,"context_line":""},{"line_number":1886,"context_line":"            # If port update is modifying the portgroup membership of the port"},{"line_number":1887,"context_line":"            # or modifying the local_link_connection or pxe_enabled flags then"},{"line_number":1888,"context_line":"            # node should be in MANAGEABLE/INSPECTING/ENROLL provisioning state"},{"line_number":1889,"context_line":"            # or in maintenance mode."},{"line_number":1890,"context_line":"            # Otherwise InvalidState exception is raised."},{"line_number":1891,"context_line":"            connectivity_attr \u003d {\u0027portgroup_id\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f013ff3_00746d34","line":1888,"range":{"start_line":1887,"start_character":67,"end_line":1888,"end_character":79},"in_reply_to":"1f013ff3_24f8b3c2","updated":"2017-05-16 10:58:35.000000000","message":"I\u0027ll add this.","commit_id":"0141463cc5cf87b92fbbcbe0309c43ff2ef55be0"}],"ironic/objects/port.py":[{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"0e735a21d813920e34dcfa4a98d1c701942bf508","unresolved":false,"context_lines":[{"line_number":311,"context_line":""},{"line_number":312,"context_line":""},{"line_number":313,"context_line":"@base.IronicObjectRegistry.register"},{"line_number":314,"context_line":"class PortCRUDPayload(notification.NotificationPayloadBase):"},{"line_number":315,"context_line":"    # Version 1.0: Initial version"},{"line_number":316,"context_line":"    # Version 1.1: Add \"portgroup_uuid\" field"},{"line_number":317,"context_line":"    # Version 1.2: Add \"physical_network\" field"}],"source_content_type":"text/x-python","patch_set":7,"id":"df140735_79cca869","line":314,"updated":"2017-06-01 17:29:57.000000000","message":"I\u0027d delay this until it\u0027s exposed in api. sending another several bytes on the wire does not make sense as it is always going to be none for now :)","commit_id":"827968707d7966b68a17d60e79f2208624abca19"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"6c50dd6f61ee1f7bf67ab16b8f875c2250a8ccc6","unresolved":false,"context_lines":[{"line_number":311,"context_line":""},{"line_number":312,"context_line":""},{"line_number":313,"context_line":"@base.IronicObjectRegistry.register"},{"line_number":314,"context_line":"class PortCRUDPayload(notification.NotificationPayloadBase):"},{"line_number":315,"context_line":"    # Version 1.0: Initial version"},{"line_number":316,"context_line":"    # Version 1.1: Add \"portgroup_uuid\" field"},{"line_number":317,"context_line":"    # Version 1.2: Add \"physical_network\" field"}],"source_content_type":"text/x-python","patch_set":7,"id":"df140735_f181dafc","line":314,"in_reply_to":"df140735_79cca869","updated":"2017-06-02 09:15:42.000000000","message":"Fair point, I\u0027ll add it to the API change.","commit_id":"827968707d7966b68a17d60e79f2208624abca19"}],"ironic/tests/unit/api/utils.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5980ec3b8d9181716d7da178f23d8d50e3fc0fe6","unresolved":false,"context_lines":[{"line_number":117,"context_line":"    port.pop(\u0027node_id\u0027)"},{"line_number":118,"context_line":"    # portgroup_id is not part of the API object"},{"line_number":119,"context_line":"    port.pop(\u0027portgroup_id\u0027)"},{"line_number":120,"context_line":"    # NOTE(mgoddard): Physical network is not yet supported by the REST API."},{"line_number":121,"context_line":"    port.pop(\u0027physical_network\u0027)"},{"line_number":122,"context_line":"    internal \u003d port_controller.PortPatchType.internal_attrs()"},{"line_number":123,"context_line":"    return remove_internal(port, internal)"}],"source_content_type":"text/x-python","patch_set":8,"id":"df140735_1df4fcef","line":120,"updated":"2017-06-06 14:56:06.000000000","message":"more like a TODO, but this is fine, as long as we remember to undo this (I\u0027m guessing in one of your later patches).","commit_id":"20bf354a76d138ace2dca045c26cf7188957948e"}],"ironic/tests/unit/api/v1/test_ports.py":[{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"b36101f0773d66d46fa648e598b00a8081add40a","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        data \u003d self.get_json(\u0027/ports/%s\u0027 % port.uuid,"},{"line_number":133,"context_line":"                             headers\u003d{api_base.Version.string: \"1.18\"})"},{"line_number":134,"context_line":"        self.assertEqual({\"foo\": \"bar\"}, data[\u0027internal_info\u0027])"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    def test_hide_fields_in_newer_versions_advanced_net(self):"},{"line_number":137,"context_line":"        llc \u003d {\u0027switch_info\u0027: \u0027switch\u0027, \u0027switch_id\u0027: \u0027aa:bb:cc:dd:ee:ff\u0027,"},{"line_number":138,"context_line":"               \u0027port_id\u0027: \u0027Gig0/1\u0027}"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f013ff3_64835b06","line":135,"updated":"2017-05-13 01:51:57.000000000","message":"Is there going to be a check on invalid physnet name or something, not sure if we need it but just wondering it loud?","commit_id":"0141463cc5cf87b92fbbcbe0309c43ff2ef55be0"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"19e7d29401ea2c20d4676ffe1b5fdb87151f7372","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        data \u003d self.get_json(\u0027/ports/%s\u0027 % port.uuid,"},{"line_number":133,"context_line":"                             headers\u003d{api_base.Version.string: \"1.18\"})"},{"line_number":134,"context_line":"        self.assertEqual({\"foo\": \"bar\"}, data[\u0027internal_info\u0027])"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    def test_hide_fields_in_newer_versions_advanced_net(self):"},{"line_number":137,"context_line":"        llc \u003d {\u0027switch_info\u0027: \u0027switch\u0027, \u0027switch_id\u0027: \u0027aa:bb:cc:dd:ee:ff\u0027,"},{"line_number":138,"context_line":"               \u0027port_id\u0027: \u0027Gig0/1\u0027}"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f013ff3_7e6984bc","line":135,"in_reply_to":"1f013ff3_64835b06","updated":"2017-05-16 10:58:35.000000000","message":"Good idea.","commit_id":"0141463cc5cf87b92fbbcbe0309c43ff2ef55be0"},{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"b36101f0773d66d46fa648e598b00a8081add40a","unresolved":false,"context_lines":[{"line_number":994,"context_line":"        self.assertEqual(\u0027application/json\u0027, response.content_type)"},{"line_number":995,"context_line":"        self.assertEqual(http_client.NOT_ACCEPTABLE, response.status_int)"},{"line_number":996,"context_line":"        self.assertFalse(mock_upd.called)"},{"line_number":997,"context_line":""},{"line_number":998,"context_line":"    def test_update_physical_network(self, mock_upd):"},{"line_number":999,"context_line":"        physical_network \u003d \u0027physnet1\u0027"},{"line_number":1000,"context_line":"        mock_upd.return_value \u003d self.port"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f013ff3_a48e0325","line":997,"updated":"2017-05-13 01:51:57.000000000","message":"missing test case for removing physnet, may be in the same one can add removing with old_api","commit_id":"0141463cc5cf87b92fbbcbe0309c43ff2ef55be0"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"19e7d29401ea2c20d4676ffe1b5fdb87151f7372","unresolved":false,"context_lines":[{"line_number":994,"context_line":"        self.assertEqual(\u0027application/json\u0027, response.content_type)"},{"line_number":995,"context_line":"        self.assertEqual(http_client.NOT_ACCEPTABLE, response.status_int)"},{"line_number":996,"context_line":"        self.assertFalse(mock_upd.called)"},{"line_number":997,"context_line":""},{"line_number":998,"context_line":"    def test_update_physical_network(self, mock_upd):"},{"line_number":999,"context_line":"        physical_network \u003d \u0027physnet1\u0027"},{"line_number":1000,"context_line":"        mock_upd.return_value \u003d self.port"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f013ff3_b3550c53","line":997,"in_reply_to":"1f013ff3_a48e0325","updated":"2017-05-16 10:58:35.000000000","message":"Done","commit_id":"0141463cc5cf87b92fbbcbe0309c43ff2ef55be0"},{"author":{"_account_id":23630,"name":"Tovin Seven","email":"tovin07@gmail.com","username":"tovin07"},"change_message_id":"cc56e3a207d731aac8ba57bce7490c83ff453389","unresolved":false,"context_lines":[{"line_number":211,"context_line":""},{"line_number":212,"context_line":"        data \u003d self.get_json(\u0027/ports/%s\u0027 % port.uuid,"},{"line_number":213,"context_line":"                             headers\u003d{api_base.Version.string: \"1.19\"})"},{"line_number":214,"context_line":"        self.assertEqual(True, data[\u0027pxe_enabled\u0027])"},{"line_number":215,"context_line":"        self.assertEqual(llc, data[\u0027local_link_connection\u0027])"},{"line_number":216,"context_line":""},{"line_number":217,"context_line":"    def test_hide_fields_in_newer_versions_portgroup_uuid(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"ff0f0b1f_5c87ff10","line":214,"range":{"start_line":214,"start_character":8,"end_line":214,"end_character":29},"updated":"2017-05-26 03:35:13.000000000","message":"assertTrue is a better convention in OpenStack hacking","commit_id":"1c9347662516d7dcdb377f675b5ab3b668e4fe9a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"d1be7373ba78f36f88b9c42e2dfb85d2a5c37718","unresolved":false,"context_lines":[{"line_number":211,"context_line":""},{"line_number":212,"context_line":"        data \u003d self.get_json(\u0027/ports/%s\u0027 % port.uuid,"},{"line_number":213,"context_line":"                             headers\u003d{api_base.Version.string: \"1.19\"})"},{"line_number":214,"context_line":"        self.assertEqual(True, data[\u0027pxe_enabled\u0027])"},{"line_number":215,"context_line":"        self.assertEqual(llc, data[\u0027local_link_connection\u0027])"},{"line_number":216,"context_line":""},{"line_number":217,"context_line":"    def test_hide_fields_in_newer_versions_portgroup_uuid(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"df140735_1a47f07a","line":214,"range":{"start_line":214,"start_character":8,"end_line":214,"end_character":29},"in_reply_to":"ff0f0b1f_5c87ff10","updated":"2017-06-01 07:22:38.000000000","message":"Good point, I will change this.","commit_id":"1c9347662516d7dcdb377f675b5ab3b668e4fe9a"},{"author":{"_account_id":23630,"name":"Tovin Seven","email":"tovin07@gmail.com","username":"tovin07"},"change_message_id":"cc56e3a207d731aac8ba57bce7490c83ff453389","unresolved":false,"context_lines":[{"line_number":1262,"context_line":"        self.assertEqual(\u0027application/json\u0027, response.content_type)"},{"line_number":1263,"context_line":"        self.assertEqual(http_client.CONFLICT, response.status_int)"},{"line_number":1264,"context_line":"        self.assertFalse(mock_upd.called)"},{"line_number":1265,"context_line":"        error_msg \u003d response.json[\u0027error_message\u0027]"},{"line_number":1266,"context_line":"        self.assertTrue(error_msg)"},{"line_number":1267,"context_line":"        self.assertIn(pg.uuid, error_msg)"},{"line_number":1268,"context_line":"        self.assertIn(\u0027physnet1\u0027, error_msg)"},{"line_number":1269,"context_line":"        self.assertIn(\u0027physnet2\u0027, error_msg)"}],"source_content_type":"text/x-python","patch_set":5,"id":"ff0f0b1f_9ce0f7ce","line":1266,"range":{"start_line":1265,"start_character":8,"end_line":1266,"end_character":34},"updated":"2017-05-26 03:35:13.000000000","message":"is error_message expected to be a boolean value?\nso confused, i think it should be a string.\nor you just mis-use assertTrue?","commit_id":"1c9347662516d7dcdb377f675b5ab3b668e4fe9a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"d1be7373ba78f36f88b9c42e2dfb85d2a5c37718","unresolved":false,"context_lines":[{"line_number":1262,"context_line":"        self.assertEqual(\u0027application/json\u0027, response.content_type)"},{"line_number":1263,"context_line":"        self.assertEqual(http_client.CONFLICT, response.status_int)"},{"line_number":1264,"context_line":"        self.assertFalse(mock_upd.called)"},{"line_number":1265,"context_line":"        error_msg \u003d response.json[\u0027error_message\u0027]"},{"line_number":1266,"context_line":"        self.assertTrue(error_msg)"},{"line_number":1267,"context_line":"        self.assertIn(pg.uuid, error_msg)"},{"line_number":1268,"context_line":"        self.assertIn(\u0027physnet1\u0027, error_msg)"},{"line_number":1269,"context_line":"        self.assertIn(\u0027physnet2\u0027, error_msg)"}],"source_content_type":"text/x-python","patch_set":5,"id":"df140735_ba2004b2","line":1266,"range":{"start_line":1265,"start_character":8,"end_line":1266,"end_character":34},"in_reply_to":"ff0f0b1f_9ce0f7ce","updated":"2017-06-01 07:22:38.000000000","message":"It\u0027s a string, we\u0027re just asserting that it\u0027s not empty. I\u0027m just following a pattern used in other test cases in this suite.","commit_id":"1c9347662516d7dcdb377f675b5ab3b668e4fe9a"}],"ironic/tests/unit/conductor/test_manager.py":[{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"b36101f0773d66d46fa648e598b00a8081add40a","unresolved":false,"context_lines":[{"line_number":3303,"context_line":"        port.refresh()"},{"line_number":3304,"context_line":"        self.assertEqual(old_pxe, port.pxe_enabled)"},{"line_number":3305,"context_line":""},{"line_number":3306,"context_line":"    def test_update_port_physnet_node_deleting_state(self):"},{"line_number":3307,"context_line":"        node \u003d obj_utils.create_test_node(self.context, driver\u003d\u0027fake\u0027,"},{"line_number":3308,"context_line":"                                          provision_state\u003dstates.DELETING)"},{"line_number":3309,"context_line":"        port \u003d obj_utils.create_test_port(self.context,"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f013ff3_44397f3f","line":3306,"range":{"start_line":3306,"start_character":8,"end_line":3306,"end_character":52},"updated":"2017-05-13 01:51:57.000000000","message":"Feel like it would be good to check if port_changed() gets called on successful updating, wdyt?","commit_id":"0141463cc5cf87b92fbbcbe0309c43ff2ef55be0"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"19e7d29401ea2c20d4676ffe1b5fdb87151f7372","unresolved":false,"context_lines":[{"line_number":3303,"context_line":"        port.refresh()"},{"line_number":3304,"context_line":"        self.assertEqual(old_pxe, port.pxe_enabled)"},{"line_number":3305,"context_line":""},{"line_number":3306,"context_line":"    def test_update_port_physnet_node_deleting_state(self):"},{"line_number":3307,"context_line":"        node \u003d obj_utils.create_test_node(self.context, driver\u003d\u0027fake\u0027,"},{"line_number":3308,"context_line":"                                          provision_state\u003dstates.DELETING)"},{"line_number":3309,"context_line":"        port \u003d obj_utils.create_test_port(self.context,"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f013ff3_f0f7f3f4","line":3306,"range":{"start_line":3306,"start_character":8,"end_line":3306,"end_character":52},"in_reply_to":"1f013ff3_44397f3f","updated":"2017-05-16 10:58:35.000000000","message":"Done","commit_id":"0141463cc5cf87b92fbbcbe0309c43ff2ef55be0"}],"releasenotes/notes/port-physical-network-a7009dc514353796.yaml":[{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"8c0c3dd02709801f294c7a702dc0a40d65c27ed0","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":"    Adds physical network field to the port object."},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"    This field specifies the name of the physical network to which the port is"},{"line_number":7,"context_line":"    connected.  Defaults to unset."}],"source_content_type":"text/x-yaml","patch_set":1,"id":"5ff73747_5af6f4fb","line":4,"updated":"2017-05-02 16:37:03.000000000","message":"I almost wonder if we should recycle this release note and just keep editing it as we go...... Since the current message is completely developer centric and will just be noise to most operators.","commit_id":"cd4826c8f3a93209bef84fc2bda28fc83e094af3"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"0e735a21d813920e34dcfa4a98d1c701942bf508","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":"    Adds a ``physical_network`` field to the port object."},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"    This field specifies the name of the physical network to which the port is"},{"line_number":7,"context_line":"    connected.  Defaults to unset."}],"source_content_type":"text/x-yaml","patch_set":7,"id":"df140735_b9e7e0e4","line":7,"range":{"start_line":1,"start_character":0,"end_line":7,"end_character":34},"updated":"2017-06-01 17:29:57.000000000","message":"ditto, this is not visible to user until it\u0027s exposed in the api. I\u0027d just drop this reno.","commit_id":"827968707d7966b68a17d60e79f2208624abca19"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"6c50dd6f61ee1f7bf67ab16b8f875c2250a8ccc6","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":"    Adds a ``physical_network`` field to the port object."},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"    This field specifies the name of the physical network to which the port is"},{"line_number":7,"context_line":"    connected.  Defaults to unset."}],"source_content_type":"text/x-yaml","patch_set":7,"id":"df140735_11320e60","line":7,"range":{"start_line":1,"start_character":0,"end_line":7,"end_character":34},"in_reply_to":"df140735_b9e7e0e4","updated":"2017-06-02 09:15:42.000000000","message":"I\u0027ll add this to the API change.","commit_id":"827968707d7966b68a17d60e79f2208624abca19"}]}
