)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"7545b747_a4e357df","updated":"2021-10-18 09:51:49.000000000","message":"recheck","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"44162715b711c777d7ead18a5746bd56d4c7b9fa","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"0dbcc32d_fd025486","updated":"2021-10-19 15:55:11.000000000","message":"-1 for https://review.opendev.org/c/openstack/neutron/+/804523/10..13/neutron/objects/local_ip.py#b43","commit_id":"45fe02fe51537d2b33849307e15e045a1250d76d"},{"author":{"_account_id":8313,"name":"Lajos Katona","display_name":"lajoskatona","email":"katonalala@gmail.com","username":"elajkat","status":"Ericsson Software Technology"},"change_message_id":"1547625bb3c6de78c72b309640ee5f4d26419344","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"32f68225_956d11fc","updated":"2021-10-21 09:52:06.000000000","message":"coming back later...","commit_id":"45fe02fe51537d2b33849307e15e045a1250d76d"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"630bbda130f9d2c9ebe50fb9d331741af688db93","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"0a5891ff_678b7bdd","updated":"2021-10-25 15:01:20.000000000","message":"Hi Oleg. This is what I was suggesting: https://review.opendev.org/c/openstack/neutron/+/815095\n\nSame as with QoS binding objects, here \"LocalIPAssociation\" registers will link \"LocalIP\" with \"Ports\". But \"LocalIP\" object should not refer to them in its view model (that means no adding \"port_associations\" member). This is because \"LocalIPAssociation\" is not a child object from \"LocalIP\"\n\n\"LocalIPAssociation\" should not refer neither to \"LocalIP\" in its view model (OVO model). Please check I also removed \"id\" from \"LocalIPAssociation\".\n\nIn order to have in \"LocalIP\" a reference to a list of ports (or port IDs), you can add \"port_associations\" but as a list of strings. During the OVO load, you can populate manually the Port list or just the port IDs (the second one will be much faster).","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"c28473d846473602e684b26ca1bc36292afeebc3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"ce45919d_fa7c26fd","updated":"2021-10-25 16:02:35.000000000","message":"Next patches in relation chain may better show my intent: user associates some port with Local IP (created earlier) - LocalIPAssociation object is created - push notification is issued - agent gets LocalIPAssociation and can get needed LocalIP info from it (local ip address, ip_mode), along with fixed port id and fixed ip address.","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"cdd879e3225a42814accb0e6fe1f5e24a9698cc2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"0def3f0e_b5ba606a","updated":"2021-10-28 14:41:16.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"a3b8eab8f2003333126fb0c82a1cf30c5509250d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"353b2d8b_56624467","updated":"2021-10-29 13:46:53.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"26d993e2b754c8de4a26bcd298781c36765ed25a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"4072e26b_bc32a1fc","updated":"2021-10-28 07:54:19.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":32667,"name":"Mamatisa Nurmatov","email":"nurmatov.mamatisa@huawei.com","username":"isabek"},"change_message_id":"df11df218652bbe95273f3af2070af2cfec490cb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"411b23c7_74456865","updated":"2021-11-01 06:02:00.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"3912e32566efb51d1bc5aa9110771451d4b5bfc8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"7a6d1ce8_224229a3","updated":"2021-10-25 12:26:15.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"3bd87073c05dd6e247a44dd9c5fdac73b84c3937","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"864854d3_323bbc9d","updated":"2021-10-25 07:15:12.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"ea02d9789ccecec2ff0f56c4a2bd5eb736e1c439","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"8efa0c5a_ec3da3f8","updated":"2021-10-26 07:04:48.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":32667,"name":"Mamatisa Nurmatov","email":"nurmatov.mamatisa@huawei.com","username":"isabek"},"change_message_id":"f5b28a900de37d3e1068f1c7f5ebf10c8547b535","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"920f35ba_c9ce70f0","updated":"2021-10-31 04:23:27.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"491d44765dbd911022d4576e0eb85ad9c7c4d304","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"97fc2d3c_bbd1a912","updated":"2021-10-25 09:57:16.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"ac7a781290f85d540e0c9d082d39bb2809fb274f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"a81b33f3_50402bd6","updated":"2021-10-27 12:56:18.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":32667,"name":"Mamatisa Nurmatov","email":"nurmatov.mamatisa@huawei.com","username":"isabek"},"change_message_id":"9a065942eeef9ca306f709e9edf752ce5429f0a3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"bd24f015_e8fbda2c","updated":"2021-10-30 12:45:04.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"b203bcbdbab1ff05e9463a3392f97601da171bba","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"c08399b2_d469d94a","updated":"2021-10-29 09:08:09.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"eb9ce6d6acd1754927b096b736df4b8945e207e8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"c219c222_93cadfb1","updated":"2021-10-25 15:53:01.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"701812b0d9f1d42dc076bd04c46fd4db37c00a83","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"db14517a_da2ca071","updated":"2021-10-29 06:47:32.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":32667,"name":"Mamatisa Nurmatov","email":"nurmatov.mamatisa@huawei.com","username":"isabek"},"change_message_id":"a59014d0eff04064a20ba3f4a1b47160ee4303fc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"dfa658b6_21b1db32","updated":"2021-10-30 07:17:47.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"1c73a943da43f595890561d2926a5176d9b51bdd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"f0958228_5ca3c7f1","updated":"2021-10-26 11:53:02.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"591ec4d6ea3d77506a8bc39ce384cb6e3470b014","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"fe936dbe_c1a2e54b","updated":"2021-10-28 10:58:51.000000000","message":"recheck","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"8c8a59300f9acd70e6bf4ed8e5d4d4b948974936","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"4a9b035f_88272b86","updated":"2021-10-25 07:15:28.000000000","message":"sorry for accidental rebases","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"fddcc2c46e2cf87d9b2bf6de0ef8661d3228bc7e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"7bbc8a74_af7163e0","in_reply_to":"0a5891ff_678b7bdd","updated":"2021-10-25 15:52:21.000000000","message":"Hi Rodolfo, thanks for such a thorough review and research! I left comments inline \n\n\u003e Hi Oleg. This is what I was suggesting: https://review.opendev.org/c/openstack/neutron/+/815095\n\u003e \n\u003e Same as with QoS binding objects, here \"LocalIPAssociation\" registers will link \"LocalIP\" with \"Ports\". But \"LocalIP\" object should not refer to them in its view model (that means no adding \"port_associations\" member). This is because \"LocalIPAssociation\" is not a child object from \"LocalIP\"\n\nBut actually \"LocalIPAssociation\" is a child of \"LocalIP\".\n\n\u003e \n\u003e \"LocalIPAssociation\" should not refer neither to \"LocalIP\" in its view model (OVO model). Please check I also removed \"id\" from \"LocalIPAssociation\".\n\nBut this is exactly what I need: having LocalIPAssociation object I want a quick access to parent LocalIP to get actual local IP address and other parent attributes. Thus new LocalIPAssociation objects will be communicated to OVS agent via push notification mechanism. Then agent will have all needed info in one object update.\n\n\u003e \n\u003e In order to have in \"LocalIP\" a reference to a list of ports (or port IDs), you can add \"port_associations\" but as a list of strings. During the OVO load, you can populate manually the Port list or just the port IDs (the second one will be much faster).\n\nIn fact I don\u0027t need a list of associated ports. LocalIPAssociation updates are central in server - agent communication.","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"877ebeee48c3c930d26a88e89957cb3d36d681db","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"5692011c_45be3563","in_reply_to":"1af597d6_d74ba608","updated":"2021-10-27 15:41:54.000000000","message":"Ok, I will not continue this discussion. According to [1], foreign_keys was to be used in a child object to create a reference to the parent object and, in the parent object, populate the child objects content. In [2] or this patch, this is not happening.\n\nI\u0027m ok if this patch is merged.\n\n[1]https://github.com/openstack/neutron/blob/1ad9ca56b07ffdc9f7e0bc6a62af61961b9128eb/doc/source/contributor/internals/objects_usage.rst\n[2]https://github.com/openstack/neutron/blob/master/neutron/objects/network.py#L109","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"8f52b20954d7863e0a1937cb101fa3392b93f7af","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"1af597d6_d74ba608","in_reply_to":"771d8640_c8edb619","updated":"2021-10-27 08:38:17.000000000","message":"\u003e \"LocalIPAssociation\" is not a child but a binding record. It is used to link ports with LocalIPs.\n\nYeah, agree, I meant from an API perspective.\n\n\u003e \n\u003e There are many binding register types in Neutron that are not used in the linked OVO views. For example:\n\u003e FlavorServiceProfileBinding\n\u003e DvrFipGatewayPortAgentBinding\n\u003e L3HARouterAgentPortBinding\n\u003e SecurityGroupPortBinding\n\u003e NetworkDhcpAgentBinding\n\u003e PortSecurityBinding\n\u003e NetworkSecurityBinding\n\u003e QosNetworkPolicyBinding\n\u003e QosFIPPolicyBinding\n\u003e QosRouterGatewayIPPolicyBinding\n\u003e QosPortPolicyBinding\n\u003e \n\u003e If you still want this, I recommend you two alternatives:\n\u003e 1) Use the orm relationship, like in https://review.opendev.org/c/openstack/neutron/+/815095/5/neutron/db/models/local_ip.py (check PS5)\n\u003e 2) (The one I would use) Same as, for example, QoS bindings: create a syntethic field in LocalIP and populate the fixed_port_ids and fixed_port_ips values (I think you just need those two) when calling LocalIP.modify_fields_from_db, doing a query\n\nI think LocalIPAssociation binding is a bit new/unique here as its create/delete events are central (even only) part in server-agent communication - this is simple and straightforward IMO (better than handling LocalIP updates and iterate port_associations to get the diff). That\u0027s why I\u0027d like to have the reference to LocalIP object in LocalIPAssociation, not the other way around. \nOVO must have a native way to do this, to not go to a lower level db_obj relationship. The only native way I found is via foreign key in LocalIP - according to code this seems required. Also this is already used in [1]\nIf there is a more proper way for using synthetic object fields to reference binding \"parents\" - I\u0027m happy to use it :)\n\n[1] https://github.com/openstack/neutron/blob/master/neutron/objects/network.py#L109","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"46008e8019acd48f62620557f56f9ce78d1f655a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"771d8640_c8edb619","in_reply_to":"7bbc8a74_af7163e0","updated":"2021-10-26 16:42:23.000000000","message":"\"LocalIPAssociation\" is not a child but a binding record. It is used to link ports with LocalIPs.\n\nThere are many binding register types in Neutron that are not used in the linked OVO views. For example:\nFlavorServiceProfileBinding\nDvrFipGatewayPortAgentBinding\nL3HARouterAgentPortBinding\nSecurityGroupPortBinding\nNetworkDhcpAgentBinding\nPortSecurityBinding\nNetworkSecurityBinding\nQosNetworkPolicyBinding\nQosFIPPolicyBinding\nQosRouterGatewayIPPolicyBinding\nQosPortPolicyBinding\n\nIf you still want this, I recommend you two alternatives:\n1) Use the orm relationship, like in https://review.opendev.org/c/openstack/neutron/+/815095/5/neutron/db/models/local_ip.py (check PS5)\n2) (The one I would use) Same as, for example, QoS bindings: create a syntethic field in LocalIP and populate the fixed_port_ids and fixed_port_ips values (I think you just need those two) when calling LocalIP.modify_fields_from_db, doing a query","commit_id":"76198064dfe567605f08af715239bcea7891e0ef"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"3f9e281d9ce5316b63dde73a70761993cd9e5787","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"4d1b2824_28abfa74","updated":"2021-11-08 11:04:16.000000000","message":"I tested that API locally and it seems it\u0027s working fine.","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"2528ce6790188ac3b987e50c2c3e31565117bf53","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"ed3da5b2_24f18a1b","updated":"2021-11-09 08:36:56.000000000","message":"There are some code in agent side should be move to this commit. And the entire implementation order should be:\n1. neutron-server side (API/DB/plugin) works with some resource notification changes\n2. \"Add Local IP L2 extension flows\" which only added helper functions on br-int\n3. \"Add Local IP L2 extension\" which add the whole extension, the new extension will use the flow functions on br-int\n4. policy works\n5. test works\n...","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"dc8b16eb5d9a4aa7873b1b9b68c1a4f46e1584b3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"c6e1285a_c914d621","updated":"2021-11-03 15:23:03.000000000","message":"recheck","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"1226485c7d65c22853726a51ca67ce377780aa3d","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"0f30e357_e623eacb","in_reply_to":"0cdf7f9e_4689b770","updated":"2021-11-10 01:31:15.000000000","message":"So you implement the agent extension in two patches, same as the DB/plugin related changes. This is a merging question, there is no standard answer. But for integrality, we should not leave some tails to other commit.\n\nI have another approach is to merge that \"flows\" and \"agent extension\" into one commit. Neutron has some feature implemented like that, so it will be two patches, one is neutron-server side and another is in agent side. Then this will be:\n1) API/DB patch only has code needed for API/DB to work\n2) Agent extension patch with flow works.\nThis is also following your principle: add the flows code that is needed by agent extension.","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"73ae4778475eb02531a772ca7250a1f2e7652c50","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"4546a70d_89122807","in_reply_to":"0f30e357_e623eacb","updated":"2021-11-10 07:05:35.000000000","message":"May I wonder if there\u0027s something that blocks this DB patch? We can continue discussion about extension in related patches :)","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"3ca9c2f340d3a87f127c71505f41228b7567edb2","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"b456a2a9_303d07bd","in_reply_to":"14fc42ad_d3aea7e4","updated":"2021-11-11 07:04:23.000000000","message":"Moved https://review.opendev.org/c/openstack/neutron/+/807116/23/neutron/db/local_ip_db.py here\n\nhttps://review.opendev.org/c/openstack/neutron/+/807116/23/neutron/services/local_ip/local_ip_plugin.py should stay in agent extension patch as it\u0027s clearly related to RPC communication and not related to API/DB","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"61f28adc205f2428ab98054798ca5ac7f0a4c265","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"cb3005ac_95e1614a","in_reply_to":"4546a70d_89122807","updated":"2021-11-11 01:45:11.000000000","message":"Yes, there are some DB [1] and plugin [2] related codes in agent side patch. So, personally, I don\u0027t think this is addressed.\n\n[1] https://review.opendev.org/c/openstack/neutron/+/807116/23/neutron/db/local_ip_db.py\n[2] https://review.opendev.org/c/openstack/neutron/+/807116/23/neutron/services/local_ip/local_ip_plugin.py","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"1d69bf64b590ba034dbd7988cc670731dc059eaa","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"14fc42ad_d3aea7e4","in_reply_to":"cb3005ac_95e1614a","updated":"2021-11-11 06:56:07.000000000","message":"I\u0027d be 100% agree if this patch scope is \"All server-side related changes (ever) needed for Local IP feature\", but the scope here is API and DB code, verified by tests. I will address to unblock the patch. Thanks","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"7cdfe9adfcd80539e7a74f75f9073b168a44b547","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"0cdf7f9e_4689b770","in_reply_to":"ed3da5b2_24f18a1b","updated":"2021-11-09 09:04:45.000000000","message":"Hi Yulong. In implementation I tend to stick to the following principle: only add code that is needed in current patch. This makes review easier IMO - you don\u0027t need to open other patches to figure out how this code will be used. Thus I\u0027d prefer to stay with current order: \n\n 1) API/DB patch only has code needed for API/DB to work\n 2) Agent extension patch adds mechanism for server \u003c-\u003e agent communication on Local IPs\n 3) Agent flows patch: fills agent extension with actual flows logic.\n\nPlease share your opinion, what are major drawbacks with this approach? Is it a blocking issue?","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":8313,"name":"Lajos Katona","display_name":"lajoskatona","email":"katonalala@gmail.com","username":"elajkat","status":"Ericsson Software Technology"},"change_message_id":"da236e10a27f5a22719d7aed36296f0085bca847","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":21,"id":"a2254426_ba32c42c","updated":"2021-11-15 14:07:23.000000000","message":"Looking forward to the higher level tests","commit_id":"cd1d96863ec8f428f03cc10741e1d876b830a5df"},{"author":{"_account_id":32667,"name":"Mamatisa Nurmatov","email":"nurmatov.mamatisa@huawei.com","username":"isabek"},"change_message_id":"c3e364ac191d9d0d4b23770008baa3c5305c43e6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":21,"id":"4610669b_77871d50","updated":"2021-11-17 04:19:51.000000000","message":"recheck","commit_id":"cd1d96863ec8f428f03cc10741e1d876b830a5df"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f51d376887b68e2dbe763b2d5dcbe62df71ed6b6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":21,"id":"7fd5bca1_02d3790b","updated":"2021-11-16 07:18:55.000000000","message":"recheck","commit_id":"cd1d96863ec8f428f03cc10741e1d876b830a5df"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"3ce91cdf2c8a3b7837aa283f6bdad636137f0f9b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":21,"id":"999ba14b_c47f1b42","updated":"2021-11-17 09:22:49.000000000","message":"recheck","commit_id":"cd1d96863ec8f428f03cc10741e1d876b830a5df"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"94633bcb75f4beb2111430f0e298fd59a13b1daf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":21,"id":"a070ba41_1c227712","updated":"2021-11-16 09:42:25.000000000","message":"recheck","commit_id":"cd1d96863ec8f428f03cc10741e1d876b830a5df"},{"author":{"_account_id":32667,"name":"Mamatisa Nurmatov","email":"nurmatov.mamatisa@huawei.com","username":"isabek"},"change_message_id":"a23b8c2858ce2e34b6cc5e540e1f53ff4646127e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":21,"id":"db8197ec_040d1814","updated":"2021-11-16 20:52:37.000000000","message":"recheck","commit_id":"cd1d96863ec8f428f03cc10741e1d876b830a5df"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"4385c661cfad47210f47cf7606f2eeee4442167f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":21,"id":"ed21f1e5_382f59f7","updated":"2021-11-17 14:55:53.000000000","message":"recheck","commit_id":"cd1d96863ec8f428f03cc10741e1d876b830a5df"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"a8628b0c1ee1e0a4e0d6b774b79efa5b34a02dd5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":21,"id":"3f08e376_1c13183e","in_reply_to":"a2254426_ba32c42c","updated":"2021-11-16 14:28:56.000000000","message":"Actually I prepared a fullstack test here: https://review.opendev.org/c/openstack/neutron/+/816327 - it has some suggestions from slaweq (which I will address soon), but basically it confirms feature functionality 😊","commit_id":"cd1d96863ec8f428f03cc10741e1d876b830a5df"}],"neutron/api/rpc/callbacks/resources.py":[{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"d5e97d3f0f52cde5058be301ad7fca3bcfbd5fb2","unresolved":true,"context_lines":[{"line_number":36,"context_line":"PORTFORWARDING \u003d port_forwarding.PortForwarding.obj_name()"},{"line_number":37,"context_line":"CONNTRACKHELPER \u003d conntrack_helper.ConntrackHelper.obj_name()"},{"line_number":38,"context_line":"ADDRESSGROUP \u003d address_group.AddressGroup.obj_name()"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"_VALID_CLS \u003d ("},{"line_number":42,"context_line":"    policy.QosPolicy,"}],"source_content_type":"text/x-python","patch_set":5,"id":"f0603076_d7d2e020","line":39,"updated":"2021-09-02 03:04:04.000000000","message":"Since you did not change this file here, I wonder if this new object will use such resource API/NOTIFICATION/CALLBACK mechanism someday? I guess this should be considered for some scenarios like this: the users port changes nothing, but the none_local_port changed the IP or mac. Then this notification can be used to agent side to do flow updating. Or this will be added in another patch?","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"6d883e02f028b4aec99460035d850b320020429f","unresolved":true,"context_lines":[{"line_number":36,"context_line":"PORTFORWARDING \u003d port_forwarding.PortForwarding.obj_name()"},{"line_number":37,"context_line":"CONNTRACKHELPER \u003d conntrack_helper.ConntrackHelper.obj_name()"},{"line_number":38,"context_line":"ADDRESSGROUP \u003d address_group.AddressGroup.obj_name()"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"_VALID_CLS \u003d ("},{"line_number":42,"context_line":"    policy.QosPolicy,"}],"source_content_type":"text/x-python","patch_set":5,"id":"0dbe1f05_2e54df26","line":39,"in_reply_to":"f0603076_d7d2e020","updated":"2021-09-02 07:19:35.000000000","message":"Yes, this will be added in next patch dealing with server-agent RPC interface","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"}],"neutron/db/local_ip_db.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":true,"context_lines":[{"line_number":58,"context_line":"    def _create_local_port(self, context, network_id, ip_address):"},{"line_number":59,"context_line":"        net_db \u003d self._core_plugin._get_network(context, network_id)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"        if not any(s.ip_version \u003d\u003d 4 for s in net_db.subnets):"},{"line_number":62,"context_line":"            msg \u003d _(\"Network %s does not contain any IPv4 subnet\") % network_id"},{"line_number":63,"context_line":"            raise lib_exc.BadRequest(resource\u003d\u0027local_ip\u0027, msg\u003dmsg)"},{"line_number":64,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"b10c3467_8e34101a","line":61,"range":{"start_line":61,"start_character":35,"end_line":61,"end_character":36},"updated":"2021-10-18 09:51:49.000000000","message":"nit: use constant","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f3b898738555a0e061f3609c029fd90406f89702","unresolved":false,"context_lines":[{"line_number":58,"context_line":"    def _create_local_port(self, context, network_id, ip_address):"},{"line_number":59,"context_line":"        net_db \u003d self._core_plugin._get_network(context, network_id)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"        if not any(s.ip_version \u003d\u003d 4 for s in net_db.subnets):"},{"line_number":62,"context_line":"            msg \u003d _(\"Network %s does not contain any IPv4 subnet\") % network_id"},{"line_number":63,"context_line":"            raise lib_exc.BadRequest(resource\u003d\u0027local_ip\u0027, msg\u003dmsg)"},{"line_number":64,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"cd98e7c5_01244e14","line":61,"range":{"start_line":61,"start_character":35,"end_line":61,"end_character":36},"in_reply_to":"b10c3467_8e34101a","updated":"2021-10-19 08:24:47.000000000","message":"Done","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":true,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def _get_local_ip_address(self, port, requested_ip):"},{"line_number":87,"context_line":"        fixed_ips \u003d port.fixed_ips"},{"line_number":88,"context_line":"        if len(fixed_ips) \u003d\u003d 0:"},{"line_number":89,"context_line":"            raise lip_exc.LocalIPNoIP(port_id\u003dport.id)"},{"line_number":90,"context_line":"        if len(fixed_ips) \u003d\u003d 1:"},{"line_number":91,"context_line":"            fixed_ip \u003d str(fixed_ips[0].ip_address)"},{"line_number":92,"context_line":"            if (validators.is_attr_set(requested_ip) and"},{"line_number":93,"context_line":"                    (requested_ip !\u003d fixed_ip)):"},{"line_number":94,"context_line":"                raise lip_exc.LocalIPRequestedIPNotFound("},{"line_number":95,"context_line":"                    port_id\u003dport.id, ip\u003drequested_ip)"},{"line_number":96,"context_line":"            return fixed_ip"},{"line_number":97,"context_line":"        elif validators.is_attr_set(requested_ip):"},{"line_number":98,"context_line":"            for fixed_ip in fixed_ips:"},{"line_number":99,"context_line":"                if str(fixed_ip.ip_address) \u003d\u003d requested_ip:"}],"source_content_type":"text/x-python","patch_set":10,"id":"c6aa8739_1c41502e","line":96,"range":{"start_line":88,"start_character":0,"end_line":96,"end_character":27},"updated":"2021-10-18 09:51:49.000000000","message":"Those two branches are not needed. The third branch loop will handle it.\n\nIf I\u0027m not wrong, this is the same:\n\nif not validators.is_attr_set(requested_ip):\n  raise lip_exc.LocalIPNoRequestedIP(port_id\u003dport.id)\n\nfor fixed_ip in fixed_ips:\n  if str(fixed_ip.ip_address) \u003d\u003d requested_ip:\n    return requested_ip\n  raise lip_exc.LocalIPRequestedIPNotFound(port_id\u003dport.id, ip\u003drequested_ip)","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f3b898738555a0e061f3609c029fd90406f89702","unresolved":true,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def _get_local_ip_address(self, port, requested_ip):"},{"line_number":87,"context_line":"        fixed_ips \u003d port.fixed_ips"},{"line_number":88,"context_line":"        if len(fixed_ips) \u003d\u003d 0:"},{"line_number":89,"context_line":"            raise lip_exc.LocalIPNoIP(port_id\u003dport.id)"},{"line_number":90,"context_line":"        if len(fixed_ips) \u003d\u003d 1:"},{"line_number":91,"context_line":"            fixed_ip \u003d str(fixed_ips[0].ip_address)"},{"line_number":92,"context_line":"            if (validators.is_attr_set(requested_ip) and"},{"line_number":93,"context_line":"                    (requested_ip !\u003d fixed_ip)):"},{"line_number":94,"context_line":"                raise lip_exc.LocalIPRequestedIPNotFound("},{"line_number":95,"context_line":"                    port_id\u003dport.id, ip\u003drequested_ip)"},{"line_number":96,"context_line":"            return fixed_ip"},{"line_number":97,"context_line":"        elif validators.is_attr_set(requested_ip):"},{"line_number":98,"context_line":"            for fixed_ip in fixed_ips:"},{"line_number":99,"context_line":"                if str(fixed_ip.ip_address) \u003d\u003d requested_ip:"}],"source_content_type":"text/x-python","patch_set":10,"id":"c7af54be_1f0211b4","line":96,"range":{"start_line":88,"start_character":0,"end_line":96,"end_character":27},"in_reply_to":"c6aa8739_1c41502e","updated":"2021-10-19 08:24:47.000000000","message":"- requested_ip is not required - if None we will take existing fixed ip of the port (if single)\n- raise a specific exception if port has no IPs at all","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"44162715b711c777d7ead18a5746bd56d4c7b9fa","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def _get_local_ip_address(self, port, requested_ip):"},{"line_number":87,"context_line":"        fixed_ips \u003d port.fixed_ips"},{"line_number":88,"context_line":"        if len(fixed_ips) \u003d\u003d 0:"},{"line_number":89,"context_line":"            raise lip_exc.LocalIPNoIP(port_id\u003dport.id)"},{"line_number":90,"context_line":"        if len(fixed_ips) \u003d\u003d 1:"},{"line_number":91,"context_line":"            fixed_ip \u003d str(fixed_ips[0].ip_address)"},{"line_number":92,"context_line":"            if (validators.is_attr_set(requested_ip) and"},{"line_number":93,"context_line":"                    (requested_ip !\u003d fixed_ip)):"},{"line_number":94,"context_line":"                raise lip_exc.LocalIPRequestedIPNotFound("},{"line_number":95,"context_line":"                    port_id\u003dport.id, ip\u003drequested_ip)"},{"line_number":96,"context_line":"            return fixed_ip"},{"line_number":97,"context_line":"        elif validators.is_attr_set(requested_ip):"},{"line_number":98,"context_line":"            for fixed_ip in fixed_ips:"},{"line_number":99,"context_line":"                if str(fixed_ip.ip_address) \u003d\u003d requested_ip:"}],"source_content_type":"text/x-python","patch_set":10,"id":"92c86513_904b780a","line":96,"range":{"start_line":88,"start_character":0,"end_line":96,"end_character":27},"in_reply_to":"c7af54be_1f0211b4","updated":"2021-10-19 15:55:11.000000000","message":"Now I get that, thanks!","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":true,"context_lines":[{"line_number":208,"context_line":"    def create_local_ip_port_association(self, context, local_ip_id,"},{"line_number":209,"context_line":"                                         port_association):"},{"line_number":210,"context_line":"        fields \u003d port_association[\u0027port_association\u0027]"},{"line_number":211,"context_line":"        with db_api.CONTEXT_WRITER.using(context):"},{"line_number":212,"context_line":"            fixed_port \u003d port_obj.Port.get_object("},{"line_number":213,"context_line":"                context, id\u003dfields[\u0027fixed_port_id\u0027])"},{"line_number":214,"context_line":"            if not fixed_port:"}],"source_content_type":"text/x-python","patch_set":10,"id":"673bc63b_f49729f7","line":211,"range":{"start_line":211,"start_character":8,"end_line":211,"end_character":50},"updated":"2021-10-18 09:51:49.000000000","message":"nit: you can use the method decorator to avoid the extra indentation.","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f3b898738555a0e061f3609c029fd90406f89702","unresolved":false,"context_lines":[{"line_number":208,"context_line":"    def create_local_ip_port_association(self, context, local_ip_id,"},{"line_number":209,"context_line":"                                         port_association):"},{"line_number":210,"context_line":"        fields \u003d port_association[\u0027port_association\u0027]"},{"line_number":211,"context_line":"        with db_api.CONTEXT_WRITER.using(context):"},{"line_number":212,"context_line":"            fixed_port \u003d port_obj.Port.get_object("},{"line_number":213,"context_line":"                context, id\u003dfields[\u0027fixed_port_id\u0027])"},{"line_number":214,"context_line":"            if not fixed_port:"}],"source_content_type":"text/x-python","patch_set":10,"id":"d2c491b1_7971145a","line":211,"range":{"start_line":211,"start_character":8,"end_line":211,"end_character":50},"in_reply_to":"673bc63b_f49729f7","updated":"2021-10-19 08:24:47.000000000","message":"Done","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":true,"context_lines":[{"line_number":266,"context_line":""},{"line_number":267,"context_line":"    def delete_local_ip_port_association(self, context, fixed_port_id,"},{"line_number":268,"context_line":"                                         local_ip_id):"},{"line_number":269,"context_line":"        assoc \u003d lip_obj.LocalIPAssociation.get_object("},{"line_number":270,"context_line":"            context, local_ip_id\u003dlocal_ip_id, fixed_port_id\u003dfixed_port_id)"},{"line_number":271,"context_line":"        if not assoc:"},{"line_number":272,"context_line":"            raise lip_exc.LocalIPAssociationNotFound(local_ip_id\u003dlocal_ip_id,"},{"line_number":273,"context_line":"                                                     port_id\u003dfixed_port_id)"},{"line_number":274,"context_line":"        assoc.delete()"}],"source_content_type":"text/x-python","patch_set":10,"id":"e1f1c12e_8563109e","line":274,"range":{"start_line":269,"start_character":8,"end_line":274,"end_character":22},"updated":"2021-10-18 09:51:49.000000000","message":"This must be inside a write context, the get and the delete methods.","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f3b898738555a0e061f3609c029fd90406f89702","unresolved":false,"context_lines":[{"line_number":266,"context_line":""},{"line_number":267,"context_line":"    def delete_local_ip_port_association(self, context, fixed_port_id,"},{"line_number":268,"context_line":"                                         local_ip_id):"},{"line_number":269,"context_line":"        assoc \u003d lip_obj.LocalIPAssociation.get_object("},{"line_number":270,"context_line":"            context, local_ip_id\u003dlocal_ip_id, fixed_port_id\u003dfixed_port_id)"},{"line_number":271,"context_line":"        if not assoc:"},{"line_number":272,"context_line":"            raise lip_exc.LocalIPAssociationNotFound(local_ip_id\u003dlocal_ip_id,"},{"line_number":273,"context_line":"                                                     port_id\u003dfixed_port_id)"},{"line_number":274,"context_line":"        assoc.delete()"}],"source_content_type":"text/x-python","patch_set":10,"id":"f8ee7f51_c42cebf1","line":274,"range":{"start_line":269,"start_character":8,"end_line":274,"end_character":22},"in_reply_to":"e1f1c12e_8563109e","updated":"2021-10-19 08:24:47.000000000","message":"Done","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"}],"neutron/db/migration/alembic_migrations/versions/xena/expand/76df7844a8c6_add_local_ip.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"27121a62d9495bbf1fd0e7f2c8e5900891be83a8","unresolved":true,"context_lines":[{"line_number":51,"context_line":"            length\u003ddb_const.IP_ADDR_FIELD_SIZE)),"},{"line_number":52,"context_line":"        sa.Column(\u0027ip_mode\u0027, sa.String("},{"line_number":53,"context_line":"            length\u003d32)),"},{"line_number":54,"context_line":"        sa.ForeignKeyConstraint([\u0027local_port_id\u0027], [\u0027ports.id\u0027])"},{"line_number":55,"context_line":"    )"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    op.create_table("}],"source_content_type":"text/x-python","patch_set":5,"id":"127c669a_669e92a7","line":54,"range":{"start_line":54,"start_character":8,"end_line":54,"end_character":64},"updated":"2021-09-03 09:21:08.000000000","message":"Please, add this parameter into the field description:\n\n        sa.Column(\u0027local_port_id\u0027, sa.String(db_const.UUID_FIELD_SIZE)),\n                  sa.ForeignKey(\u0027ports.id\u0027))","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"dcd022ed6e8f235a1292038b7585277382100605","unresolved":false,"context_lines":[{"line_number":51,"context_line":"            length\u003ddb_const.IP_ADDR_FIELD_SIZE)),"},{"line_number":52,"context_line":"        sa.Column(\u0027ip_mode\u0027, sa.String("},{"line_number":53,"context_line":"            length\u003d32)),"},{"line_number":54,"context_line":"        sa.ForeignKeyConstraint([\u0027local_port_id\u0027], [\u0027ports.id\u0027])"},{"line_number":55,"context_line":"    )"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    op.create_table("}],"source_content_type":"text/x-python","patch_set":5,"id":"1e78b58a_a63864ae","line":54,"range":{"start_line":54,"start_character":8,"end_line":54,"end_character":64},"in_reply_to":"127c669a_669e92a7","updated":"2021-09-03 11:32:51.000000000","message":"Done","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"27121a62d9495bbf1fd0e7f2c8e5900891be83a8","unresolved":true,"context_lines":[{"line_number":52,"context_line":"        sa.Column(\u0027ip_mode\u0027, sa.String("},{"line_number":53,"context_line":"            length\u003d32)),"},{"line_number":54,"context_line":"        sa.ForeignKeyConstraint([\u0027local_port_id\u0027], [\u0027ports.id\u0027])"},{"line_number":55,"context_line":"    )"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    op.create_table("},{"line_number":58,"context_line":"        \u0027local_ip_associations\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"709578b0_2ce308eb","line":55,"range":{"start_line":55,"start_character":4,"end_line":55,"end_character":5},"updated":"2021-09-03 09:21:08.000000000","message":"I don\u0027t understand the concept of \"local_port_id\" in a \"local_ip\" register. If I\u0027m not wrong, we can have 1:n associations (1 \"local_ip\": n fixed ports). Why should store just one \"local_port_id\" in the \"local_ip\" register?","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"dcd022ed6e8f235a1292038b7585277382100605","unresolved":true,"context_lines":[{"line_number":52,"context_line":"        sa.Column(\u0027ip_mode\u0027, sa.String("},{"line_number":53,"context_line":"            length\u003d32)),"},{"line_number":54,"context_line":"        sa.ForeignKeyConstraint([\u0027local_port_id\u0027], [\u0027ports.id\u0027])"},{"line_number":55,"context_line":"    )"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    op.create_table("},{"line_number":58,"context_line":"        \u0027local_ip_associations\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"2954d6fe_cddbb9e3","line":55,"range":{"start_line":55,"start_character":4,"end_line":55,"end_character":5},"in_reply_to":"709578b0_2ce308eb","updated":"2021-09-03 11:32:51.000000000","message":"local_port_id is an ID of the underlying port backing Local IP - the one that actually holds an IP address. This is similar to floating_port_id in a Floating IP model (as opposed to fixed_port_id).","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"27121a62d9495bbf1fd0e7f2c8e5900891be83a8","unresolved":true,"context_lines":[{"line_number":62,"context_line":"            length\u003ddb_const.UUID_FIELD_SIZE), primary_key\u003dTrue),"},{"line_number":63,"context_line":"        sa.Column(\u0027fixed_ip\u0027, sa.String("},{"line_number":64,"context_line":"            length\u003ddb_const.IP_ADDR_FIELD_SIZE)),"},{"line_number":65,"context_line":"        sa.ForeignKeyConstraint([\u0027local_ip_id\u0027], [\u0027local_ips.id\u0027]),"},{"line_number":66,"context_line":"        sa.ForeignKeyConstraint([\u0027fixed_port_id\u0027], [\u0027ports.id\u0027],"},{"line_number":67,"context_line":"                                ondelete\u003d\u0027CASCADE\u0027)"},{"line_number":68,"context_line":"    )"}],"source_content_type":"text/x-python","patch_set":5,"id":"c744dfab_dd79601b","line":67,"range":{"start_line":65,"start_character":8,"end_line":67,"end_character":51},"updated":"2021-09-03 09:21:08.000000000","message":"ditto, please add this into the column field. It is easier to read.","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"dcd022ed6e8f235a1292038b7585277382100605","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            length\u003ddb_const.UUID_FIELD_SIZE), primary_key\u003dTrue),"},{"line_number":63,"context_line":"        sa.Column(\u0027fixed_ip\u0027, sa.String("},{"line_number":64,"context_line":"            length\u003ddb_const.IP_ADDR_FIELD_SIZE)),"},{"line_number":65,"context_line":"        sa.ForeignKeyConstraint([\u0027local_ip_id\u0027], [\u0027local_ips.id\u0027]),"},{"line_number":66,"context_line":"        sa.ForeignKeyConstraint([\u0027fixed_port_id\u0027], [\u0027ports.id\u0027],"},{"line_number":67,"context_line":"                                ondelete\u003d\u0027CASCADE\u0027)"},{"line_number":68,"context_line":"    )"}],"source_content_type":"text/x-python","patch_set":5,"id":"3c753738_de5ca2b1","line":67,"range":{"start_line":65,"start_character":8,"end_line":67,"end_character":51},"in_reply_to":"c744dfab_dd79601b","updated":"2021-09-03 11:32:51.000000000","message":"Done","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"715b89f18cd992dc82002bde58a8f95cd156de87","unresolved":true,"context_lines":[{"line_number":58,"context_line":"        \u0027local_ip_associations\u0027,"},{"line_number":59,"context_line":"        sa.Column(\u0027local_ip_id\u0027, sa.String("},{"line_number":60,"context_line":"            length\u003ddb_const.UUID_FIELD_SIZE), primary_key\u003dTrue,"},{"line_number":61,"context_line":"            sa.ForeignKey(\u0027local_ips.id\u0027)),"},{"line_number":62,"context_line":"        sa.Column(\u0027fixed_port_id\u0027, sa.String("},{"line_number":63,"context_line":"            length\u003ddb_const.UUID_FIELD_SIZE), primary_key\u003dTrue,"},{"line_number":64,"context_line":"            sa.ForeignKey(\u0027ports.id\u0027)),"}],"source_content_type":"text/x-python","patch_set":6,"id":"a275d216_24ece240","line":61,"range":{"start_line":61,"start_character":13,"end_line":61,"end_character":41},"updated":"2021-09-08 07:43:07.000000000","message":"That goes after the name and the type:\n\n        sa.Column(\u0027local_ip_id\u0027,\n                  sa.String(length\u003ddb_const.UUID_FIELD_SIZE),\n                  sa.ForeignKey(\u0027local_ips.id\u0027),\n                  primary_key\u003dTrue)","commit_id":"006925ee4be20c89a5b834808006ada1657e9326"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"e5eacba0b8384aaa248e66c6007d3deda2dbed4a","unresolved":false,"context_lines":[{"line_number":58,"context_line":"        \u0027local_ip_associations\u0027,"},{"line_number":59,"context_line":"        sa.Column(\u0027local_ip_id\u0027, sa.String("},{"line_number":60,"context_line":"            length\u003ddb_const.UUID_FIELD_SIZE), primary_key\u003dTrue,"},{"line_number":61,"context_line":"            sa.ForeignKey(\u0027local_ips.id\u0027)),"},{"line_number":62,"context_line":"        sa.Column(\u0027fixed_port_id\u0027, sa.String("},{"line_number":63,"context_line":"            length\u003ddb_const.UUID_FIELD_SIZE), primary_key\u003dTrue,"},{"line_number":64,"context_line":"            sa.ForeignKey(\u0027ports.id\u0027)),"}],"source_content_type":"text/x-python","patch_set":6,"id":"b0a15eb4_cbce81d3","line":61,"range":{"start_line":61,"start_character":13,"end_line":61,"end_character":41},"in_reply_to":"a275d216_24ece240","updated":"2021-09-08 07:47:42.000000000","message":"Done","commit_id":"006925ee4be20c89a5b834808006ada1657e9326"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"715b89f18cd992dc82002bde58a8f95cd156de87","unresolved":true,"context_lines":[{"line_number":61,"context_line":"            sa.ForeignKey(\u0027local_ips.id\u0027)),"},{"line_number":62,"context_line":"        sa.Column(\u0027fixed_port_id\u0027, sa.String("},{"line_number":63,"context_line":"            length\u003ddb_const.UUID_FIELD_SIZE), primary_key\u003dTrue,"},{"line_number":64,"context_line":"            sa.ForeignKey(\u0027ports.id\u0027)),"},{"line_number":65,"context_line":"        sa.Column(\u0027fixed_ip\u0027, sa.String("},{"line_number":66,"context_line":"            length\u003ddb_const.IP_ADDR_FIELD_SIZE)),"},{"line_number":67,"context_line":"    )"}],"source_content_type":"text/x-python","patch_set":6,"id":"3eb986eb_c4b60c39","line":64,"range":{"start_line":64,"start_character":12,"end_line":64,"end_character":37},"updated":"2021-09-08 07:43:07.000000000","message":"ditto","commit_id":"006925ee4be20c89a5b834808006ada1657e9326"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"e5eacba0b8384aaa248e66c6007d3deda2dbed4a","unresolved":false,"context_lines":[{"line_number":61,"context_line":"            sa.ForeignKey(\u0027local_ips.id\u0027)),"},{"line_number":62,"context_line":"        sa.Column(\u0027fixed_port_id\u0027, sa.String("},{"line_number":63,"context_line":"            length\u003ddb_const.UUID_FIELD_SIZE), primary_key\u003dTrue,"},{"line_number":64,"context_line":"            sa.ForeignKey(\u0027ports.id\u0027)),"},{"line_number":65,"context_line":"        sa.Column(\u0027fixed_ip\u0027, sa.String("},{"line_number":66,"context_line":"            length\u003ddb_const.IP_ADDR_FIELD_SIZE)),"},{"line_number":67,"context_line":"    )"}],"source_content_type":"text/x-python","patch_set":6,"id":"80b11496_7d458725","line":64,"range":{"start_line":64,"start_character":12,"end_line":64,"end_character":37},"in_reply_to":"3eb986eb_c4b60c39","updated":"2021-09-08 07:47:42.000000000","message":"Done","commit_id":"006925ee4be20c89a5b834808006ada1657e9326"}],"neutron/db/migration/alembic_migrations/versions/yoga/expand/76df7844a8c6_add_local_ip.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":true,"context_lines":[{"line_number":61,"context_line":"                  primary_key\u003dTrue),"},{"line_number":62,"context_line":"        sa.Column(\u0027fixed_port_id\u0027, sa.String(length\u003ddb_const.UUID_FIELD_SIZE),"},{"line_number":63,"context_line":"                  sa.ForeignKey(\u0027ports.id\u0027),"},{"line_number":64,"context_line":"                  primary_key\u003dTrue),"},{"line_number":65,"context_line":"        sa.Column(\u0027fixed_ip\u0027, sa.String("},{"line_number":66,"context_line":"            length\u003ddb_const.IP_ADDR_FIELD_SIZE)),"},{"line_number":67,"context_line":"    )"}],"source_content_type":"text/x-python","patch_set":10,"id":"22b1a51a_4ca46cea","line":64,"range":{"start_line":64,"start_character":18,"end_line":64,"end_character":29},"updated":"2021-10-18 09:51:49.000000000","message":"We should have just one primary_key per table. \"fixed_port_id\" could be an index.\n\nHowever, I think (local_ip_id, fixed_port_id) tuple should be the index of this table. If I\u0027m not wrong, this tuple will be always unique. You should create a unique constraint for both\n\n\nsa.Column(\u0027local_ip_id\u0027, sa.String(length\u003ddb_const.UUID_FIELD_SIZE),\n          sa.ForeignKey(\u0027local_ips.id\u0027)),\nsa.Column(\u0027fixed_port_id\u0027, sa.String(length\u003ddb_const.UUID_FIELD_SIZE),\n          sa.ForeignKey(\u0027ports.id\u0027)),\nsa.Column(\u0027fixed_ip\u0027, sa.String(length\u003ddb_const.IP_ADDR_FIELD_SIZE)),\nsa.PrimaryKeyConstraint(\u0027local_ip_id\u0027, \u0027fixed_port_id\u0027),\nsa.UniqueConstraint(\u0027local_ip_fixed_port\u0027, name\u003d\u0027unique_local_ip_id0fixed_port_id\u0027)","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"44162715b711c777d7ead18a5746bd56d4c7b9fa","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                  primary_key\u003dTrue),"},{"line_number":62,"context_line":"        sa.Column(\u0027fixed_port_id\u0027, sa.String(length\u003ddb_const.UUID_FIELD_SIZE),"},{"line_number":63,"context_line":"                  sa.ForeignKey(\u0027ports.id\u0027),"},{"line_number":64,"context_line":"                  primary_key\u003dTrue),"},{"line_number":65,"context_line":"        sa.Column(\u0027fixed_ip\u0027, sa.String("},{"line_number":66,"context_line":"            length\u003ddb_const.IP_ADDR_FIELD_SIZE)),"},{"line_number":67,"context_line":"    )"}],"source_content_type":"text/x-python","patch_set":10,"id":"8239c5ca_cca7877c","line":64,"range":{"start_line":64,"start_character":18,"end_line":64,"end_character":29},"in_reply_to":"1a8cf4ac_ac269c8e","updated":"2021-10-19 15:55:11.000000000","message":"note for myself: I need to check if both approaches return the same table definition.","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f3b898738555a0e061f3609c029fd90406f89702","unresolved":true,"context_lines":[{"line_number":61,"context_line":"                  primary_key\u003dTrue),"},{"line_number":62,"context_line":"        sa.Column(\u0027fixed_port_id\u0027, sa.String(length\u003ddb_const.UUID_FIELD_SIZE),"},{"line_number":63,"context_line":"                  sa.ForeignKey(\u0027ports.id\u0027),"},{"line_number":64,"context_line":"                  primary_key\u003dTrue),"},{"line_number":65,"context_line":"        sa.Column(\u0027fixed_ip\u0027, sa.String("},{"line_number":66,"context_line":"            length\u003ddb_const.IP_ADDR_FIELD_SIZE)),"},{"line_number":67,"context_line":"    )"}],"source_content_type":"text/x-python","patch_set":10,"id":"1a8cf4ac_ac269c8e","line":64,"range":{"start_line":64,"start_character":18,"end_line":64,"end_character":29},"in_reply_to":"22b1a51a_4ca46cea","updated":"2021-10-19 08:24:47.000000000","message":"\u003e\u003eWe should have just one primary_key per table.\nWhy?\n\nI think all this is already covered with composite primary key.","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":8313,"name":"Lajos Katona","display_name":"lajoskatona","email":"katonalala@gmail.com","username":"elajkat","status":"Ericsson Software Technology"},"change_message_id":"1547625bb3c6de78c72b309640ee5f4d26419344","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                  primary_key\u003dTrue),"},{"line_number":62,"context_line":"        sa.Column(\u0027fixed_port_id\u0027, sa.String(length\u003ddb_const.UUID_FIELD_SIZE),"},{"line_number":63,"context_line":"                  sa.ForeignKey(\u0027ports.id\u0027),"},{"line_number":64,"context_line":"                  primary_key\u003dTrue),"},{"line_number":65,"context_line":"        sa.Column(\u0027fixed_ip\u0027, sa.String("},{"line_number":66,"context_line":"            length\u003ddb_const.IP_ADDR_FIELD_SIZE)),"},{"line_number":67,"context_line":"    )"}],"source_content_type":"text/x-python","patch_set":10,"id":"0a31167c_a9bee75e","line":64,"range":{"start_line":64,"start_character":18,"end_line":64,"end_character":29},"in_reply_to":"8239c5ca_cca7877c","updated":"2021-10-21 09:52:06.000000000","message":"I checked quickly and seen examples for multiple primary_keys in other migration scripts, without uniqueconstraint (but had the same feeling that we should need it, though true that composite primary key for this) so as I see it is ok","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"3f9e281d9ce5316b63dde73a70761993cd9e5787","unresolved":true,"context_lines":[{"line_number":50,"context_line":"                  nullable\u003dFalse),"},{"line_number":51,"context_line":"        sa.Column(\u0027network_id\u0027, sa.String("},{"line_number":52,"context_line":"                  length\u003ddb_const.UUID_FIELD_SIZE),"},{"line_number":53,"context_line":"                  nullable\u003dFalse),"},{"line_number":54,"context_line":"        sa.Column(\u0027local_ip_address\u0027, sa.String("},{"line_number":55,"context_line":"                  length\u003ddb_const.IP_ADDR_FIELD_SIZE),"},{"line_number":56,"context_line":"                  nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":19,"id":"e1715934_22f1d7bf","line":53,"updated":"2021-11-08 11:04:16.000000000","message":"there is no \"network_id\" specified in the spec: https://review.opendev.org/c/openstack/neutron-specs/+/797798/12/specs/xena/node-local-ip.rst\nDo we really need it? It should be possible to find it by looking at \"local_port\", right?","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"0c55054f49a07bf10d546a8e5a67a30dca16ceb9","unresolved":false,"context_lines":[{"line_number":50,"context_line":"                  nullable\u003dFalse),"},{"line_number":51,"context_line":"        sa.Column(\u0027network_id\u0027, sa.String("},{"line_number":52,"context_line":"                  length\u003ddb_const.UUID_FIELD_SIZE),"},{"line_number":53,"context_line":"                  nullable\u003dFalse),"},{"line_number":54,"context_line":"        sa.Column(\u0027local_ip_address\u0027, sa.String("},{"line_number":55,"context_line":"                  length\u003ddb_const.IP_ADDR_FIELD_SIZE),"},{"line_number":56,"context_line":"                  nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":19,"id":"9a3e7565_19667836","line":53,"in_reply_to":"dd47b1f0_9bceeb9b","updated":"2021-11-12 08:20:15.000000000","message":"Hmm, how I could miss that? Sorry for the noise 😊","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"576d3414480bfbeccfadb7e8098c25428634c3aa","unresolved":true,"context_lines":[{"line_number":50,"context_line":"                  nullable\u003dFalse),"},{"line_number":51,"context_line":"        sa.Column(\u0027network_id\u0027, sa.String("},{"line_number":52,"context_line":"                  length\u003ddb_const.UUID_FIELD_SIZE),"},{"line_number":53,"context_line":"                  nullable\u003dFalse),"},{"line_number":54,"context_line":"        sa.Column(\u0027local_ip_address\u0027, sa.String("},{"line_number":55,"context_line":"                  length\u003ddb_const.IP_ADDR_FIELD_SIZE),"},{"line_number":56,"context_line":"                  nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":19,"id":"dd47b1f0_9bceeb9b","line":53,"in_reply_to":"e1715934_22f1d7bf","updated":"2021-11-08 11:20:20.000000000","message":"Actually there is: https://review.opendev.org/c/openstack/neutron-specs/+/797798/12/specs/xena/node-local-ip.rst#127 - network_id here is like floating_network_id in Floating IP resource - net from which IP was allocated","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"}],"neutron/db/models/local_ip.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"27121a62d9495bbf1fd0e7f2c8e5900891be83a8","unresolved":true,"context_lines":[{"line_number":72,"context_line":"    local_ip \u003d orm.relationship(\"LocalIP\","},{"line_number":73,"context_line":"                                lazy\u003d\u0027joined\u0027,"},{"line_number":74,"context_line":"                                foreign_keys\u003dlocal_ip_id,"},{"line_number":75,"context_line":"                                backref\u003dorm.backref(\"port_associations\","},{"line_number":76,"context_line":"                                                    uselist\u003dTrue))"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    # standard attributes support:"}],"source_content_type":"text/x-python","patch_set":5,"id":"acd9c866_cb7041d5","line":75,"range":{"start_line":75,"start_character":53,"end_line":75,"end_character":70},"updated":"2021-09-03 09:21:08.000000000","message":"To be more explicit (this is a \"port\" parameter), I would name it as \"local_ip_associations\".","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"dcd022ed6e8f235a1292038b7585277382100605","unresolved":true,"context_lines":[{"line_number":72,"context_line":"    local_ip \u003d orm.relationship(\"LocalIP\","},{"line_number":73,"context_line":"                                lazy\u003d\u0027joined\u0027,"},{"line_number":74,"context_line":"                                foreign_keys\u003dlocal_ip_id,"},{"line_number":75,"context_line":"                                backref\u003dorm.backref(\"port_associations\","},{"line_number":76,"context_line":"                                                    uselist\u003dTrue))"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    # standard attributes support:"}],"source_content_type":"text/x-python","patch_set":5,"id":"bb026d54_376d415a","line":75,"range":{"start_line":75,"start_character":53,"end_line":75,"end_character":70},"in_reply_to":"acd9c866_cb7041d5","updated":"2021-09-03 11:32:51.000000000","message":"in a local_ip object having port_associations is quite explicit IMO. For port object we don\u0027t need a backref at this point, but if we do - I\u0027d name it \"local_ip_associations\"","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":true,"context_lines":[{"line_number":41,"context_line":"    local_ip_address \u003d sa.Column(sa.String(64), nullable\u003dFalse)"},{"line_number":42,"context_line":"    ip_mode \u003d sa.Column(sa.String(32), nullable\u003dFalse)"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    # The ORM-level \"delete\" cascade relationship between port and floating_ip"},{"line_number":45,"context_line":"    # is required for causing the in-Python event \"after_delete\" that needs for"},{"line_number":46,"context_line":"    # proper quota management in case when cascade removal of the floating_ip"},{"line_number":47,"context_line":"    # happens after removal of the floating_port"}],"source_content_type":"text/x-python","patch_set":10,"id":"9857072e_49be5846","line":44,"range":{"start_line":44,"start_character":67,"end_line":44,"end_character":78},"updated":"2021-10-18 09:51:49.000000000","message":"?? Sorry, what I\u0027m missing here?","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f3b898738555a0e061f3609c029fd90406f89702","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    local_ip_address \u003d sa.Column(sa.String(64), nullable\u003dFalse)"},{"line_number":42,"context_line":"    ip_mode \u003d sa.Column(sa.String(32), nullable\u003dFalse)"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    # The ORM-level \"delete\" cascade relationship between port and floating_ip"},{"line_number":45,"context_line":"    # is required for causing the in-Python event \"after_delete\" that needs for"},{"line_number":46,"context_line":"    # proper quota management in case when cascade removal of the floating_ip"},{"line_number":47,"context_line":"    # happens after removal of the floating_port"}],"source_content_type":"text/x-python","patch_set":10,"id":"16a1d19b_60597c90","line":44,"range":{"start_line":44,"start_character":67,"end_line":44,"end_character":78},"in_reply_to":"9857072e_49be5846","updated":"2021-10-19 08:24:47.000000000","message":"Oops","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":true,"context_lines":[{"line_number":45,"context_line":"    # is required for causing the in-Python event \"after_delete\" that needs for"},{"line_number":46,"context_line":"    # proper quota management in case when cascade removal of the floating_ip"},{"line_number":47,"context_line":"    # happens after removal of the floating_port"},{"line_number":48,"context_line":"    local_port \u003d orm.relationship(models_v2.Port,"},{"line_number":49,"context_line":"                                  foreign_keys\u003dlocal_port_id)"},{"line_number":50,"context_line":"    api_collections \u003d [local_ip_apidef.COLLECTION_NAME]"},{"line_number":51,"context_line":"    collection_resource_map \u003d {"}],"source_content_type":"text/x-python","patch_set":10,"id":"921856c2_6010c164","line":48,"range":{"start_line":48,"start_character":4,"end_line":48,"end_character":14},"updated":"2021-10-18 09:51:49.000000000","message":"I would define this relationship using another lazy method. By default, it will be \"select\". That means this will add a new JOIN clause to the port query.\n\nI would use \"subquery\" instead. When this parameter is needed, from the \"port\" DB view, a new sql query will be issued.\n\nlocal_port \u003d orm.relationship(models_v2.Port,\n                              load_on_pending\u003dTrue,\n                              backref\u003dorm.backref(\"local_port_id\",\n                                                  lazy\u003d\u0027subquery\u0027,\n                                                  uselist\u003dFalse,\n                                                  cascade\u003d\u0027delete\u0027)","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"44162715b711c777d7ead18a5746bd56d4c7b9fa","unresolved":false,"context_lines":[{"line_number":45,"context_line":"    # is required for causing the in-Python event \"after_delete\" that needs for"},{"line_number":46,"context_line":"    # proper quota management in case when cascade removal of the floating_ip"},{"line_number":47,"context_line":"    # happens after removal of the floating_port"},{"line_number":48,"context_line":"    local_port \u003d orm.relationship(models_v2.Port,"},{"line_number":49,"context_line":"                                  foreign_keys\u003dlocal_port_id)"},{"line_number":50,"context_line":"    api_collections \u003d [local_ip_apidef.COLLECTION_NAME]"},{"line_number":51,"context_line":"    collection_resource_map \u003d {"}],"source_content_type":"text/x-python","patch_set":10,"id":"67267524_f1ba5529","line":48,"range":{"start_line":48,"start_character":4,"end_line":48,"end_character":14},"in_reply_to":"1c9cba00_7ddec7d2","updated":"2021-10-19 15:55:11.000000000","message":"+1","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f3b898738555a0e061f3609c029fd90406f89702","unresolved":true,"context_lines":[{"line_number":45,"context_line":"    # is required for causing the in-Python event \"after_delete\" that needs for"},{"line_number":46,"context_line":"    # proper quota management in case when cascade removal of the floating_ip"},{"line_number":47,"context_line":"    # happens after removal of the floating_port"},{"line_number":48,"context_line":"    local_port \u003d orm.relationship(models_v2.Port,"},{"line_number":49,"context_line":"                                  foreign_keys\u003dlocal_port_id)"},{"line_number":50,"context_line":"    api_collections \u003d [local_ip_apidef.COLLECTION_NAME]"},{"line_number":51,"context_line":"    collection_resource_map \u003d {"}],"source_content_type":"text/x-python","patch_set":10,"id":"1c9cba00_7ddec7d2","line":48,"range":{"start_line":48,"start_character":4,"end_line":48,"end_character":14},"in_reply_to":"921856c2_6010c164","updated":"2021-10-19 08:24:47.000000000","message":"I don\u0027t want to have a backref in a Ports table to not affect port operations performance in any way.\nLooking at it now I don\u0027t think we need this relationship here at all, even for Local IP table.\n\nAlso I need to add a callback on Port delete event to prevent port deletion if it\u0027s used as local port for any local IP.","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":true,"context_lines":[{"line_number":50,"context_line":"    api_collections \u003d [local_ip_apidef.COLLECTION_NAME]"},{"line_number":51,"context_line":"    collection_resource_map \u003d {"},{"line_number":52,"context_line":"        local_ip_apidef.COLLECTION_NAME: local_ip_apidef.RESOURCE_NAME}"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"class LocalIPAssociation(model_base.BASEV2):"},{"line_number":56,"context_line":"    \"\"\"Represents an association between a Local IP and an internal Port.\"\"\""}],"source_content_type":"text/x-python","patch_set":10,"id":"8b733e99_54c7eec5","line":53,"updated":"2021-10-18 09:51:49.000000000","message":"Shouldn\u0027t we add the condition \"revises_on_change\"? This register depends on a neutron port; if this port is updated, local_ip should too.\n revises_on_change \u003d (\u0027port\u0027, )","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"44162715b711c777d7ead18a5746bd56d4c7b9fa","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    api_collections \u003d [local_ip_apidef.COLLECTION_NAME]"},{"line_number":51,"context_line":"    collection_resource_map \u003d {"},{"line_number":52,"context_line":"        local_ip_apidef.COLLECTION_NAME: local_ip_apidef.RESOURCE_NAME}"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"class LocalIPAssociation(model_base.BASEV2):"},{"line_number":56,"context_line":"    \"\"\"Represents an association between a Local IP and an internal Port.\"\"\""}],"source_content_type":"text/x-python","patch_set":10,"id":"ecc97227_b08e773f","line":53,"in_reply_to":"6fee63e6_340e9d8e","updated":"2021-10-19 15:55:11.000000000","message":"Done","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f3b898738555a0e061f3609c029fd90406f89702","unresolved":true,"context_lines":[{"line_number":50,"context_line":"    api_collections \u003d [local_ip_apidef.COLLECTION_NAME]"},{"line_number":51,"context_line":"    collection_resource_map \u003d {"},{"line_number":52,"context_line":"        local_ip_apidef.COLLECTION_NAME: local_ip_apidef.RESOURCE_NAME}"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"class LocalIPAssociation(model_base.BASEV2):"},{"line_number":56,"context_line":"    \"\"\"Represents an association between a Local IP and an internal Port.\"\"\""}],"source_content_type":"text/x-python","patch_set":10,"id":"6fee63e6_340e9d8e","line":53,"in_reply_to":"8b733e99_54c7eec5","updated":"2021-10-19 08:24:47.000000000","message":"I\u0027d like to be consistent with Floating IP behavior, where floating port update is not handled by floating IP","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":true,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    local_ip_id \u003d sa.Column(sa.String(36),"},{"line_number":61,"context_line":"                            sa.ForeignKey(\u0027local_ips.id\u0027),"},{"line_number":62,"context_line":"                            nullable\u003dFalse,"},{"line_number":63,"context_line":"                            primary_key\u003dTrue)"},{"line_number":64,"context_line":"    fixed_port_id \u003d sa.Column(sa.String(36),"},{"line_number":65,"context_line":"                              sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\u0027CASCADE\u0027),"}],"source_content_type":"text/x-python","patch_set":10,"id":"14a86cbe_41d8c43c","line":62,"range":{"start_line":62,"start_character":28,"end_line":62,"end_character":43},"updated":"2021-10-18 09:51:49.000000000","message":"this is by default False when \"primary_key\u003dTrue\"","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f3b898738555a0e061f3609c029fd90406f89702","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    local_ip_id \u003d sa.Column(sa.String(36),"},{"line_number":61,"context_line":"                            sa.ForeignKey(\u0027local_ips.id\u0027),"},{"line_number":62,"context_line":"                            nullable\u003dFalse,"},{"line_number":63,"context_line":"                            primary_key\u003dTrue)"},{"line_number":64,"context_line":"    fixed_port_id \u003d sa.Column(sa.String(36),"},{"line_number":65,"context_line":"                              sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\u0027CASCADE\u0027),"}],"source_content_type":"text/x-python","patch_set":10,"id":"248484f5_87c859f8","line":62,"range":{"start_line":62,"start_character":28,"end_line":62,"end_character":43},"in_reply_to":"14a86cbe_41d8c43c","updated":"2021-10-19 08:24:47.000000000","message":"Done","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"}],"neutron/extensions/local_ip.py":[{"author":{"_account_id":8313,"name":"Lajos Katona","display_name":"lajoskatona","email":"katonalala@gmail.com","username":"elajkat","status":"Ericsson Software Technology"},"change_message_id":"da236e10a27f5a22719d7aed36296f0085bca847","unresolved":true,"context_lines":[{"line_number":76,"context_line":"        return PLUGIN_TYPE"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    def get_plugin_description(self):"},{"line_number":79,"context_line":"        return \"Local IP Service Plugin\""},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    @abc.abstractmethod"},{"line_number":82,"context_line":"    def create_local_ip(self, context, local_ip):"}],"source_content_type":"text/x-python","patch_set":19,"id":"ec89713e_3b4d71bd","line":79,"range":{"start_line":79,"start_character":16,"end_line":79,"end_character":39},"updated":"2021-11-15 14:07:23.000000000","message":"nit: local_ip_apidef.DESCRIPTION","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"}],"neutron/objects/local_ip.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"27121a62d9495bbf1fd0e7f2c8e5900891be83a8","unresolved":true,"context_lines":[{"line_number":33,"context_line":"        \u0027id\u0027: common_types.UUIDField(),"},{"line_number":34,"context_line":"        \u0027name\u0027: obj_fields.StringField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027description\u0027: obj_fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027project_id\u0027: obj_fields.StringField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \u0027local_port_id\u0027: common_types.UUIDField(),"},{"line_number":38,"context_line":"        \u0027network_id\u0027: common_types.UUIDField(),"},{"line_number":39,"context_line":"        \u0027local_ip_address\u0027: obj_fields.IPAddressField(),"}],"source_content_type":"text/x-python","patch_set":5,"id":"b6f9a52d_dc6cd647","line":36,"range":{"start_line":36,"start_character":45,"end_line":36,"end_character":58},"updated":"2021-09-03 09:21:08.000000000","message":"Is that correct?","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"dcd022ed6e8f235a1292038b7585277382100605","unresolved":true,"context_lines":[{"line_number":33,"context_line":"        \u0027id\u0027: common_types.UUIDField(),"},{"line_number":34,"context_line":"        \u0027name\u0027: obj_fields.StringField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027description\u0027: obj_fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027project_id\u0027: obj_fields.StringField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \u0027local_port_id\u0027: common_types.UUIDField(),"},{"line_number":38,"context_line":"        \u0027network_id\u0027: common_types.UUIDField(),"},{"line_number":39,"context_line":"        \u0027local_ip_address\u0027: obj_fields.IPAddressField(),"}],"source_content_type":"text/x-python","patch_set":5,"id":"49da7a36_0878a369","line":36,"range":{"start_line":36,"start_character":45,"end_line":36,"end_character":58},"in_reply_to":"b6f9a52d_dc6cd647","updated":"2021-09-03 11:32:51.000000000","message":"It\u0027s the same for other objects, not sure why, but I\u0027d like to be consistent.","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"27121a62d9495bbf1fd0e7f2c8e5900891be83a8","unresolved":true,"context_lines":[{"line_number":75,"context_line":"        \u0027local_ip_id\u0027: common_types.UUIDField(nullable\u003dFalse),"},{"line_number":76,"context_line":"        \u0027fixed_port_id\u0027: common_types.UUIDField(nullable\u003dFalse),"},{"line_number":77,"context_line":"        \u0027fixed_ip\u0027: obj_fields.IPAddressField(nullable\u003dFalse),"},{"line_number":78,"context_line":"        \u0027local_ip\u0027: obj_fields.ObjectField(\u0027LocalIP\u0027, nullable\u003dTrue),"},{"line_number":79,"context_line":"    }"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    primary_keys \u003d [\u0027local_ip_id\u0027, \u0027fixed_port_id\u0027]"}],"source_content_type":"text/x-python","patch_set":5,"id":"4d6a1a57_e88a4332","line":78,"range":{"start_line":78,"start_character":54,"end_line":78,"end_character":67},"updated":"2021-09-03 09:21:08.000000000","message":"How is that possible? a \"local_ip_associations\" must always have a \"local_ip\" register associated. This cannot be null.","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"dcd022ed6e8f235a1292038b7585277382100605","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        \u0027local_ip_id\u0027: common_types.UUIDField(nullable\u003dFalse),"},{"line_number":76,"context_line":"        \u0027fixed_port_id\u0027: common_types.UUIDField(nullable\u003dFalse),"},{"line_number":77,"context_line":"        \u0027fixed_ip\u0027: obj_fields.IPAddressField(nullable\u003dFalse),"},{"line_number":78,"context_line":"        \u0027local_ip\u0027: obj_fields.ObjectField(\u0027LocalIP\u0027, nullable\u003dTrue),"},{"line_number":79,"context_line":"    }"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    primary_keys \u003d [\u0027local_ip_id\u0027, \u0027fixed_port_id\u0027]"}],"source_content_type":"text/x-python","patch_set":5,"id":"60a96dc4_f4d6dda4","line":78,"range":{"start_line":78,"start_character":54,"end_line":78,"end_character":67},"in_reply_to":"4d6a1a57_e88a4332","updated":"2021-09-03 11:32:51.000000000","message":"Agree","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"27121a62d9495bbf1fd0e7f2c8e5900891be83a8","unresolved":true,"context_lines":[{"line_number":82,"context_line":"    foreign_keys \u003d {\u0027LocalIP\u0027: {\u0027local_ip_id\u0027: \u0027id\u0027},"},{"line_number":83,"context_line":"                    \u0027Port\u0027: {\u0027fixed_port_id\u0027: \u0027id\u0027}}"},{"line_number":84,"context_line":"    fields_no_update \u003d [\u0027local_ip_id\u0027, \u0027fixed_port_id\u0027, \u0027fixed_ip\u0027]"},{"line_number":85,"context_line":"    synthetic_fields \u003d [\u0027id\u0027, \u0027local_ip\u0027]"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    @classmethod"},{"line_number":88,"context_line":"    def modify_fields_to_db(cls, fields):"}],"source_content_type":"text/x-python","patch_set":5,"id":"2be7cd43_653a07c3","line":85,"range":{"start_line":85,"start_character":25,"end_line":85,"end_character":27},"updated":"2021-09-03 09:21:08.000000000","message":"why id?","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"dcd022ed6e8f235a1292038b7585277382100605","unresolved":true,"context_lines":[{"line_number":82,"context_line":"    foreign_keys \u003d {\u0027LocalIP\u0027: {\u0027local_ip_id\u0027: \u0027id\u0027},"},{"line_number":83,"context_line":"                    \u0027Port\u0027: {\u0027fixed_port_id\u0027: \u0027id\u0027}}"},{"line_number":84,"context_line":"    fields_no_update \u003d [\u0027local_ip_id\u0027, \u0027fixed_port_id\u0027, \u0027fixed_ip\u0027]"},{"line_number":85,"context_line":"    synthetic_fields \u003d [\u0027id\u0027, \u0027local_ip\u0027]"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    @classmethod"},{"line_number":88,"context_line":"    def modify_fields_to_db(cls, fields):"}],"source_content_type":"text/x-python","patch_set":5,"id":"97043e90_794033d5","line":85,"range":{"start_line":85,"start_character":25,"end_line":85,"end_character":27},"in_reply_to":"2be7cd43_653a07c3","updated":"2021-09-03 11:32:51.000000000","message":"In this DB table we don\u0027t need an explicit ID field, however \u0027id\u0027 is needed for some internal neutron processing - like push notifications framework and local resource cache in particular. So I added a synthetic \u0027id\u0027 field to this OVO.","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":true,"context_lines":[{"line_number":40,"context_line":"        \u0027ip_mode\u0027: obj_fields.StringField(),"},{"line_number":41,"context_line":"    }"},{"line_number":42,"context_line":"    foreign_keys \u003d {\u0027Port\u0027: {\u0027local_port_id\u0027: \u0027id\u0027},"},{"line_number":43,"context_line":"                    \u0027LocalIPAssociation\u0027: {\u0027id\u0027: \u0027local_ip_id\u0027}}"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    fields_no_update \u003d [\u0027project_id\u0027, \u0027local_ip_address\u0027,"},{"line_number":46,"context_line":"                        \u0027network_id\u0027, \u0027local_port_id\u0027]"}],"source_content_type":"text/x-python","patch_set":10,"id":"ad8854b5_a929972a","line":43,"range":{"start_line":43,"start_character":20,"end_line":43,"end_character":63},"updated":"2021-10-18 09:51:49.000000000","message":"You can\u0027t link LocalIP.id to LocalIPAssociation.local_ip_id\n\nYou need to create another field in this OVO.","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"c6c90ba97c78cdf5a5f24176c84292e442a58bb1","unresolved":true,"context_lines":[{"line_number":40,"context_line":"        \u0027ip_mode\u0027: obj_fields.StringField(),"},{"line_number":41,"context_line":"    }"},{"line_number":42,"context_line":"    foreign_keys \u003d {\u0027Port\u0027: {\u0027local_port_id\u0027: \u0027id\u0027},"},{"line_number":43,"context_line":"                    \u0027LocalIPAssociation\u0027: {\u0027id\u0027: \u0027local_ip_id\u0027}}"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    fields_no_update \u003d [\u0027project_id\u0027, \u0027local_ip_address\u0027,"},{"line_number":46,"context_line":"                        \u0027network_id\u0027, \u0027local_port_id\u0027]"}],"source_content_type":"text/x-python","patch_set":10,"id":"90d49979_82d900f2","line":43,"range":{"start_line":43,"start_character":20,"end_line":43,"end_character":63},"in_reply_to":"5b31a335_0e74a924","updated":"2021-10-20 07:37:08.000000000","message":"I agree this is quite weird and I was surprised with that \"NeutronSyntheticFieldsForeignKeysNotFound: LocalIP does not define a foreign key for LocalIPAssociation\" - not sure what\u0027s wrong but I get this error when removing this foreign key here.","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"39cfa733a278907bfe14115e26dc1d29328e1e97","unresolved":true,"context_lines":[{"line_number":40,"context_line":"        \u0027ip_mode\u0027: obj_fields.StringField(),"},{"line_number":41,"context_line":"    }"},{"line_number":42,"context_line":"    foreign_keys \u003d {\u0027Port\u0027: {\u0027local_port_id\u0027: \u0027id\u0027},"},{"line_number":43,"context_line":"                    \u0027LocalIPAssociation\u0027: {\u0027id\u0027: \u0027local_ip_id\u0027}}"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    fields_no_update \u003d [\u0027project_id\u0027, \u0027local_ip_address\u0027,"},{"line_number":46,"context_line":"                        \u0027network_id\u0027, \u0027local_port_id\u0027]"}],"source_content_type":"text/x-python","patch_set":10,"id":"a0923cea_45907e02","line":43,"range":{"start_line":43,"start_character":20,"end_line":43,"end_character":63},"in_reply_to":"90d49979_82d900f2","updated":"2021-10-20 08:03:04.000000000","message":"I believe this foreign key is required if I want to reference parent object from a child one: https://github.com/openstack/neutron/blob/master/neutron/objects/base.py#L826-L833","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f3b898738555a0e061f3609c029fd90406f89702","unresolved":true,"context_lines":[{"line_number":40,"context_line":"        \u0027ip_mode\u0027: obj_fields.StringField(),"},{"line_number":41,"context_line":"    }"},{"line_number":42,"context_line":"    foreign_keys \u003d {\u0027Port\u0027: {\u0027local_port_id\u0027: \u0027id\u0027},"},{"line_number":43,"context_line":"                    \u0027LocalIPAssociation\u0027: {\u0027id\u0027: \u0027local_ip_id\u0027}}"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    fields_no_update \u003d [\u0027project_id\u0027, \u0027local_ip_address\u0027,"},{"line_number":46,"context_line":"                        \u0027network_id\u0027, \u0027local_port_id\u0027]"}],"source_content_type":"text/x-python","patch_set":10,"id":"e4c7c7eb_3c8b189f","line":43,"range":{"start_line":43,"start_character":20,"end_line":43,"end_character":63},"in_reply_to":"ad8854b5_a929972a","updated":"2021-10-19 08:24:47.000000000","message":"Why not? AFAIU this is kind of a backref.\nFor example NetworkSegment object has foreign key \"\u0027PortBindingLevel\u0027: {\u0027id\u0027: \u0027segment_id\u0027},\" [1]\n\nThis lets LocalIPAssociation object to have ObjectField(\u0027LocalIP\u0027) and makes local IP objects tests happy.\n\nWithout it I have:\n \"neutron_lib.objects.exceptions.NeutronSyntheticFieldsForeignKeysNotFound: LocalIP does not define a foreign key for LocalIPAssociation\"\n\n[1] https://github.com/openstack/neutron/blob/master/neutron/objects/network.py#L109","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"44162715b711c777d7ead18a5746bd56d4c7b9fa","unresolved":true,"context_lines":[{"line_number":40,"context_line":"        \u0027ip_mode\u0027: obj_fields.StringField(),"},{"line_number":41,"context_line":"    }"},{"line_number":42,"context_line":"    foreign_keys \u003d {\u0027Port\u0027: {\u0027local_port_id\u0027: \u0027id\u0027},"},{"line_number":43,"context_line":"                    \u0027LocalIPAssociation\u0027: {\u0027id\u0027: \u0027local_ip_id\u0027}}"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    fields_no_update \u003d [\u0027project_id\u0027, \u0027local_ip_address\u0027,"},{"line_number":46,"context_line":"                        \u0027network_id\u0027, \u0027local_port_id\u0027]"}],"source_content_type":"text/x-python","patch_set":10,"id":"5b31a335_0e74a924","line":43,"range":{"start_line":43,"start_character":20,"end_line":43,"end_character":63},"in_reply_to":"e4c7c7eb_3c8b189f","updated":"2021-10-19 15:55:11.000000000","message":"Because what you link is the child object with the parent and this is done in the child. In this case, you are doing this in L82.\n\nWhy foreign_keys you are linking to the referred object (in this case \"LocalIP\"), a parameter of another. \"LocalIP\" is not aware of \"LocalIPAssociation\" at all.","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":true,"context_lines":[{"line_number":82,"context_line":"    foreign_keys \u003d {\u0027LocalIP\u0027: {\u0027local_ip_id\u0027: \u0027id\u0027},"},{"line_number":83,"context_line":"                    \u0027Port\u0027: {\u0027fixed_port_id\u0027: \u0027id\u0027}}"},{"line_number":84,"context_line":"    fields_no_update \u003d [\u0027local_ip_id\u0027, \u0027fixed_port_id\u0027, \u0027fixed_ip\u0027]"},{"line_number":85,"context_line":"    synthetic_fields \u003d [\u0027id\u0027, \u0027local_ip\u0027]"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    @classmethod"},{"line_number":88,"context_line":"    def modify_fields_to_db(cls, fields):"}],"source_content_type":"text/x-python","patch_set":10,"id":"98ec17fe_2fe848d1","line":85,"range":{"start_line":85,"start_character":25,"end_line":85,"end_character":27},"updated":"2021-10-18 09:51:49.000000000","message":"Why? Do we need an ID?","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"44162715b711c777d7ead18a5746bd56d4c7b9fa","unresolved":false,"context_lines":[{"line_number":82,"context_line":"    foreign_keys \u003d {\u0027LocalIP\u0027: {\u0027local_ip_id\u0027: \u0027id\u0027},"},{"line_number":83,"context_line":"                    \u0027Port\u0027: {\u0027fixed_port_id\u0027: \u0027id\u0027}}"},{"line_number":84,"context_line":"    fields_no_update \u003d [\u0027local_ip_id\u0027, \u0027fixed_port_id\u0027, \u0027fixed_ip\u0027]"},{"line_number":85,"context_line":"    synthetic_fields \u003d [\u0027id\u0027, \u0027local_ip\u0027]"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    @classmethod"},{"line_number":88,"context_line":"    def modify_fields_to_db(cls, fields):"}],"source_content_type":"text/x-python","patch_set":10,"id":"ad58d852_dc6ba6a1","line":85,"range":{"start_line":85,"start_character":25,"end_line":85,"end_character":27},"in_reply_to":"7d6d18f6_f4289cb1","updated":"2021-10-19 15:55:11.000000000","message":"Hmm I\u0027ll check that. We have many objects without ID (same as this one, used for binding). In any case, this is not relevant.","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f3b898738555a0e061f3609c029fd90406f89702","unresolved":true,"context_lines":[{"line_number":82,"context_line":"    foreign_keys \u003d {\u0027LocalIP\u0027: {\u0027local_ip_id\u0027: \u0027id\u0027},"},{"line_number":83,"context_line":"                    \u0027Port\u0027: {\u0027fixed_port_id\u0027: \u0027id\u0027}}"},{"line_number":84,"context_line":"    fields_no_update \u003d [\u0027local_ip_id\u0027, \u0027fixed_port_id\u0027, \u0027fixed_ip\u0027]"},{"line_number":85,"context_line":"    synthetic_fields \u003d [\u0027id\u0027, \u0027local_ip\u0027]"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    @classmethod"},{"line_number":88,"context_line":"    def modify_fields_to_db(cls, fields):"}],"source_content_type":"text/x-python","patch_set":10,"id":"7d6d18f6_f4289cb1","line":85,"range":{"start_line":85,"start_character":25,"end_line":85,"end_character":27},"in_reply_to":"98ec17fe_2fe848d1","updated":"2021-10-19 08:24:47.000000000","message":"[copying from PS5]\nIn this DB table we don\u0027t need an explicit ID field, however \u0027id\u0027 is needed for some internal neutron processing - like push notifications framework and local resource cache in particular. So I added a synthetic \u0027id\u0027 field to this OVO.","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"5efd5cd341d7055e34b06fb363fbf8a0a4e586da","unresolved":true,"context_lines":[{"line_number":103,"context_line":"            self._set_id()"},{"line_number":104,"context_line":"        super(LocalIPAssociation, self).obj_load_attr(attrname)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    def from_db_object(self, db_obj):"},{"line_number":107,"context_line":"        super(LocalIPAssociation, self).from_db_object(db_obj)"},{"line_number":108,"context_line":"        self._set_id()"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    def _set_id(self):"},{"line_number":111,"context_line":"        self.id \u003d self.local_ip_id + \u0027_\u0027 + self.fixed_port_id"},{"line_number":112,"context_line":"        self.obj_reset_changes([\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":10,"id":"66f7ed9e_3a265ce1","line":112,"range":{"start_line":106,"start_character":3,"end_line":112,"end_character":38},"updated":"2021-10-18 09:51:49.000000000","message":"Why do we need an ID?","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"44162715b711c777d7ead18a5746bd56d4c7b9fa","unresolved":false,"context_lines":[{"line_number":103,"context_line":"            self._set_id()"},{"line_number":104,"context_line":"        super(LocalIPAssociation, self).obj_load_attr(attrname)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    def from_db_object(self, db_obj):"},{"line_number":107,"context_line":"        super(LocalIPAssociation, self).from_db_object(db_obj)"},{"line_number":108,"context_line":"        self._set_id()"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    def _set_id(self):"},{"line_number":111,"context_line":"        self.id \u003d self.local_ip_id + \u0027_\u0027 + self.fixed_port_id"},{"line_number":112,"context_line":"        self.obj_reset_changes([\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa41644c_6a4d394d","line":112,"range":{"start_line":106,"start_character":3,"end_line":112,"end_character":38},"in_reply_to":"24fc89b7_fe6d3cbc","updated":"2021-10-19 15:55:11.000000000","message":"Done","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"f3b898738555a0e061f3609c029fd90406f89702","unresolved":true,"context_lines":[{"line_number":103,"context_line":"            self._set_id()"},{"line_number":104,"context_line":"        super(LocalIPAssociation, self).obj_load_attr(attrname)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    def from_db_object(self, db_obj):"},{"line_number":107,"context_line":"        super(LocalIPAssociation, self).from_db_object(db_obj)"},{"line_number":108,"context_line":"        self._set_id()"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    def _set_id(self):"},{"line_number":111,"context_line":"        self.id \u003d self.local_ip_id + \u0027_\u0027 + self.fixed_port_id"},{"line_number":112,"context_line":"        self.obj_reset_changes([\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":10,"id":"24fc89b7_fe6d3cbc","line":112,"range":{"start_line":106,"start_character":3,"end_line":112,"end_character":38},"in_reply_to":"66f7ed9e_3a265ce1","updated":"2021-10-19 08:24:47.000000000","message":"ditto","commit_id":"03284b5028ca3bdd45545ab5aa94a5cb1309d0cd"}],"neutron/plugins/ml2/plugin.py":[{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"d5e97d3f0f52cde5058be301ad7fca3bcfbd5fb2","unresolved":true,"context_lines":[{"line_number":229,"context_line":"                                    addrgrp_def.ALIAS,"},{"line_number":230,"context_line":"                                    pnap_def.ALIAS,"},{"line_number":231,"context_line":"                                    pdp_def.ALIAS,"},{"line_number":232,"context_line":"                                    local_ip_apidef.ALIAS,"},{"line_number":233,"context_line":"                                    ]"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"    # List of agent types for which all binding_failed ports should try to be"}],"source_content_type":"text/x-python","patch_set":5,"id":"900d9f2a_056e2022","line":232,"range":{"start_line":232,"start_character":36,"end_line":232,"end_character":58},"updated":"2021-09-02 03:04:04.000000000","message":"Can this be added to a new service plugin? Something like log plugin, port forwarding plugin.","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"dcd022ed6e8f235a1292038b7585277382100605","unresolved":false,"context_lines":[{"line_number":229,"context_line":"                                    addrgrp_def.ALIAS,"},{"line_number":230,"context_line":"                                    pnap_def.ALIAS,"},{"line_number":231,"context_line":"                                    pdp_def.ALIAS,"},{"line_number":232,"context_line":"                                    local_ip_apidef.ALIAS,"},{"line_number":233,"context_line":"                                    ]"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"    # List of agent types for which all binding_failed ports should try to be"}],"source_content_type":"text/x-python","patch_set":5,"id":"9848caf9_86ec5a7e","line":232,"range":{"start_line":232,"start_character":36,"end_line":232,"end_character":58},"in_reply_to":"0134c007_03d11ebc","updated":"2021-09-03 11:32:51.000000000","message":"I have no arguments against service plugin (except laziness) so I think I\u0027ll just add it without debates :)","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"e30329f35b46c43d2255c8ce217c12cbb9adcfad","unresolved":true,"context_lines":[{"line_number":229,"context_line":"                                    addrgrp_def.ALIAS,"},{"line_number":230,"context_line":"                                    pnap_def.ALIAS,"},{"line_number":231,"context_line":"                                    pdp_def.ALIAS,"},{"line_number":232,"context_line":"                                    local_ip_apidef.ALIAS,"},{"line_number":233,"context_line":"                                    ]"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"    # List of agent types for which all binding_failed ports should try to be"}],"source_content_type":"text/x-python","patch_set":5,"id":"c238aaad_5659c0bc","line":232,"range":{"start_line":232,"start_character":36,"end_line":232,"end_character":58},"in_reply_to":"4ed6895e_cad2a6f6","updated":"2021-09-02 08:30:08.000000000","message":"Personally, I\u0027d like to see the new features are configurable to aviod running potential unstable codes after upgrading.","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"6d883e02f028b4aec99460035d850b320020429f","unresolved":true,"context_lines":[{"line_number":229,"context_line":"                                    addrgrp_def.ALIAS,"},{"line_number":230,"context_line":"                                    pnap_def.ALIAS,"},{"line_number":231,"context_line":"                                    pdp_def.ALIAS,"},{"line_number":232,"context_line":"                                    local_ip_apidef.ALIAS,"},{"line_number":233,"context_line":"                                    ]"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"    # List of agent types for which all binding_failed ports should try to be"}],"source_content_type":"text/x-python","patch_set":5,"id":"4ed6895e_cad2a6f6","line":232,"range":{"start_line":232,"start_character":36,"end_line":232,"end_character":58},"in_reply_to":"900d9f2a_056e2022","updated":"2021-09-02 07:19:35.000000000","message":"What will this give us?","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"27121a62d9495bbf1fd0e7f2c8e5900891be83a8","unresolved":true,"context_lines":[{"line_number":229,"context_line":"                                    addrgrp_def.ALIAS,"},{"line_number":230,"context_line":"                                    pnap_def.ALIAS,"},{"line_number":231,"context_line":"                                    pdp_def.ALIAS,"},{"line_number":232,"context_line":"                                    local_ip_apidef.ALIAS,"},{"line_number":233,"context_line":"                                    ]"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"    # List of agent types for which all binding_failed ports should try to be"}],"source_content_type":"text/x-python","patch_set":5,"id":"0134c007_03d11ebc","line":232,"range":{"start_line":232,"start_character":36,"end_line":232,"end_character":58},"in_reply_to":"c238aaad_5659c0bc","updated":"2021-09-03 09:21:08.000000000","message":"I think you should bring this topic to the team meeting. But I\u0027m with LIU, this should be a service plugin.","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"}],"neutron/tests/unit/db/test_db_base_plugin_v2.py":[{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"d5e97d3f0f52cde5058be301ad7fca3bcfbd5fb2","unresolved":true,"context_lines":[{"line_number":250,"context_line":"                         subresource\u003dsubresource, context\u003dcontext)"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def new_list_request(self, resource, fmt\u003dNone, params\u003dNone,"},{"line_number":253,"context_line":"                         id\u003dNone, subresource\u003dNone):"},{"line_number":254,"context_line":"        return self._req("},{"line_number":255,"context_line":"            \u0027GET\u0027, resource, None, fmt, params\u003dparams, id\u003did,"},{"line_number":256,"context_line":"            subresource\u003dsubresource"}],"source_content_type":"text/x-python","patch_set":5,"id":"74b25516_94ba1887","line":253,"range":{"start_line":253,"start_character":25,"end_line":253,"end_character":34},"updated":"2021-09-02 03:04:04.000000000","message":"It\u0027s better to add new parms to the tail of the list, then the existing function caller can do few/none refactor to adjust the new parms.","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"6d883e02f028b4aec99460035d850b320020429f","unresolved":false,"context_lines":[{"line_number":250,"context_line":"                         subresource\u003dsubresource, context\u003dcontext)"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def new_list_request(self, resource, fmt\u003dNone, params\u003dNone,"},{"line_number":253,"context_line":"                         id\u003dNone, subresource\u003dNone):"},{"line_number":254,"context_line":"        return self._req("},{"line_number":255,"context_line":"            \u0027GET\u0027, resource, None, fmt, params\u003dparams, id\u003did,"},{"line_number":256,"context_line":"            subresource\u003dsubresource"}],"source_content_type":"text/x-python","patch_set":5,"id":"29ad3cb4_05d20a7b","line":253,"range":{"start_line":253,"start_character":25,"end_line":253,"end_character":34},"in_reply_to":"74b25516_94ba1887","updated":"2021-09-02 07:19:35.000000000","message":"Done","commit_id":"8e09f95a9c1d0cf66d8b36944e8f49cf3d489036"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"715b89f18cd992dc82002bde58a8f95cd156de87","unresolved":true,"context_lines":[{"line_number":250,"context_line":"                         subresource\u003dsubresource, context\u003dcontext)"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def new_list_request(self, resource, fmt\u003dNone, params\u003dNone,"},{"line_number":253,"context_line":"                         subresource\u003dNone, id\u003dNone):"},{"line_number":254,"context_line":"        return self._req("},{"line_number":255,"context_line":"            \u0027GET\u0027, resource, None, fmt, params\u003dparams, id\u003did,"},{"line_number":256,"context_line":"            subresource\u003dsubresource"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a1a9b77_af19a70e","line":253,"range":{"start_line":253,"start_character":43,"end_line":253,"end_character":45},"updated":"2021-09-08 07:43:07.000000000","message":"Sorry for being so pedantic: \"id\" shadows built-in \"id\". You should call it \"_id\" or something similar","commit_id":"006925ee4be20c89a5b834808006ada1657e9326"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"e5eacba0b8384aaa248e66c6007d3deda2dbed4a","unresolved":true,"context_lines":[{"line_number":250,"context_line":"                         subresource\u003dsubresource, context\u003dcontext)"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def new_list_request(self, resource, fmt\u003dNone, params\u003dNone,"},{"line_number":253,"context_line":"                         subresource\u003dNone, id\u003dNone):"},{"line_number":254,"context_line":"        return self._req("},{"line_number":255,"context_line":"            \u0027GET\u0027, resource, None, fmt, params\u003dparams, id\u003did,"},{"line_number":256,"context_line":"            subresource\u003dsubresource"}],"source_content_type":"text/x-python","patch_set":6,"id":"568a48f3_2cfc9560","line":253,"range":{"start_line":253,"start_character":43,"end_line":253,"end_character":45},"in_reply_to":"3a1a9b77_af19a70e","updated":"2021-09-08 07:47:42.000000000","message":"Yeah, agree","commit_id":"006925ee4be20c89a5b834808006ada1657e9326"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"715b89f18cd992dc82002bde58a8f95cd156de87","unresolved":true,"context_lines":[{"line_number":643,"context_line":"              id\u003dNone, subresource\u003dNone):"},{"line_number":644,"context_line":"        fmt \u003d fmt or self.fmt"},{"line_number":645,"context_line":"        req \u003d self.new_list_request(resource, fmt, query_params,"},{"line_number":646,"context_line":"                                    subresource\u003dsubresource, id\u003did)"},{"line_number":647,"context_line":"        if neutron_context:"},{"line_number":648,"context_line":"            req.environ[\u0027neutron.context\u0027] \u003d neutron_context"},{"line_number":649,"context_line":"        res \u003d req.get_response(self._api_for_resource(resource))"}],"source_content_type":"text/x-python","patch_set":6,"id":"bc691fa4_d5810e83","line":646,"range":{"start_line":646,"start_character":61,"end_line":646,"end_character":63},"updated":"2021-09-08 07:43:07.000000000","message":"ditto","commit_id":"006925ee4be20c89a5b834808006ada1657e9326"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"e5eacba0b8384aaa248e66c6007d3deda2dbed4a","unresolved":false,"context_lines":[{"line_number":643,"context_line":"              id\u003dNone, subresource\u003dNone):"},{"line_number":644,"context_line":"        fmt \u003d fmt or self.fmt"},{"line_number":645,"context_line":"        req \u003d self.new_list_request(resource, fmt, query_params,"},{"line_number":646,"context_line":"                                    subresource\u003dsubresource, id\u003did)"},{"line_number":647,"context_line":"        if neutron_context:"},{"line_number":648,"context_line":"            req.environ[\u0027neutron.context\u0027] \u003d neutron_context"},{"line_number":649,"context_line":"        res \u003d req.get_response(self._api_for_resource(resource))"}],"source_content_type":"text/x-python","patch_set":6,"id":"8f8965ce_3d657c35","line":646,"range":{"start_line":646,"start_character":61,"end_line":646,"end_character":63},"in_reply_to":"bc691fa4_d5810e83","updated":"2021-09-08 07:47:42.000000000","message":"Done","commit_id":"006925ee4be20c89a5b834808006ada1657e9326"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"3f7a96f31db680f0650582025f710f408fb42cb1","unresolved":true,"context_lines":[{"line_number":250,"context_line":"                         subresource\u003dsubresource, context\u003dcontext)"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def new_list_request(self, resource, fmt\u003dNone, params\u003dNone,"},{"line_number":253,"context_line":"                         subresource\u003dNone, id\u003dNone):"},{"line_number":254,"context_line":"        return self._req("},{"line_number":255,"context_line":"            \u0027GET\u0027, resource, None, fmt, params\u003dparams, id\u003did,"},{"line_number":256,"context_line":"            subresource\u003dsubresource"}],"source_content_type":"text/x-python","patch_set":7,"id":"a460b82f_9510bbc4","line":253,"range":{"start_line":253,"start_character":43,"end_line":253,"end_character":45},"updated":"2021-09-08 09:27:57.000000000","message":"if respin, please change that (id to _id)","commit_id":"141d63159ef89a39f1e2c7248feaf17995afb9bf"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"648a9afc8d0deff0d114dc3b074f1f21b0e540d8","unresolved":true,"context_lines":[{"line_number":250,"context_line":"                         subresource\u003dsubresource, context\u003dcontext)"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def new_list_request(self, resource, fmt\u003dNone, params\u003dNone,"},{"line_number":253,"context_line":"                         subresource\u003dNone, id\u003dNone):"},{"line_number":254,"context_line":"        return self._req("},{"line_number":255,"context_line":"            \u0027GET\u0027, resource, None, fmt, params\u003dparams, id\u003did,"},{"line_number":256,"context_line":"            subresource\u003dsubresource"}],"source_content_type":"text/x-python","patch_set":7,"id":"fbd847fb_29d093e2","line":253,"range":{"start_line":253,"start_character":43,"end_line":253,"end_character":45},"in_reply_to":"a460b82f_9510bbc4","updated":"2021-09-08 09:37:39.000000000","message":"Yes, sorry, I\u0027ll update right away","commit_id":"141d63159ef89a39f1e2c7248feaf17995afb9bf"}],"neutron/tests/unit/extensions/test_local_ip.py":[{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"3f9e281d9ce5316b63dde73a70761993cd9e5787","unresolved":true,"context_lines":[{"line_number":173,"context_line":"                self.assertEqual(local_port[\u0027id\u0027], lip[\u0027local_port_id\u0027])"},{"line_number":174,"context_line":"                self.assertEqual(new_ip, lip[\u0027local_ip_address\u0027])"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def test_create_local_ip_with_local_port_id_and_mult_ips_wrong_ip(self):"},{"line_number":177,"context_line":"        with self.port() as p:"},{"line_number":178,"context_line":"            local_port \u003d p[\u0027port\u0027]"},{"line_number":179,"context_line":"            self._port_add_new_ip(local_port)"}],"source_content_type":"text/x-python","patch_set":19,"id":"89881137_3bf44b9d","line":176,"range":{"start_line":176,"start_character":52,"end_line":176,"end_character":56},"updated":"2021-11-08 11:04:16.000000000","message":"nitty nit: should be \"multiple\" probably 😊","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"0c55054f49a07bf10d546a8e5a67a30dca16ceb9","unresolved":false,"context_lines":[{"line_number":173,"context_line":"                self.assertEqual(local_port[\u0027id\u0027], lip[\u0027local_port_id\u0027])"},{"line_number":174,"context_line":"                self.assertEqual(new_ip, lip[\u0027local_ip_address\u0027])"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def test_create_local_ip_with_local_port_id_and_mult_ips_wrong_ip(self):"},{"line_number":177,"context_line":"        with self.port() as p:"},{"line_number":178,"context_line":"            local_port \u003d p[\u0027port\u0027]"},{"line_number":179,"context_line":"            self._port_add_new_ip(local_port)"}],"source_content_type":"text/x-python","patch_set":19,"id":"b5a66191_5fab90b3","line":176,"range":{"start_line":176,"start_character":52,"end_line":176,"end_character":56},"in_reply_to":"616feb44_038db93c","updated":"2021-11-12 08:20:15.000000000","message":"ok, that\u0027s important reason :D","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"576d3414480bfbeccfadb7e8098c25428634c3aa","unresolved":true,"context_lines":[{"line_number":173,"context_line":"                self.assertEqual(local_port[\u0027id\u0027], lip[\u0027local_port_id\u0027])"},{"line_number":174,"context_line":"                self.assertEqual(new_ip, lip[\u0027local_ip_address\u0027])"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def test_create_local_ip_with_local_port_id_and_mult_ips_wrong_ip(self):"},{"line_number":177,"context_line":"        with self.port() as p:"},{"line_number":178,"context_line":"            local_port \u003d p[\u0027port\u0027]"},{"line_number":179,"context_line":"            self._port_add_new_ip(local_port)"}],"source_content_type":"text/x-python","patch_set":19,"id":"616feb44_038db93c","line":176,"range":{"start_line":176,"start_character":52,"end_line":176,"end_character":56},"in_reply_to":"89881137_3bf44b9d","updated":"2021-11-08 11:20:20.000000000","message":"it won\u0027t fit in 80 chars! :D","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"},{"author":{"_account_id":8313,"name":"Lajos Katona","display_name":"lajoskatona","email":"katonalala@gmail.com","username":"elajkat","status":"Ericsson Software Technology"},"change_message_id":"da236e10a27f5a22719d7aed36296f0085bca847","unresolved":false,"context_lines":[{"line_number":173,"context_line":"                self.assertEqual(local_port[\u0027id\u0027], lip[\u0027local_port_id\u0027])"},{"line_number":174,"context_line":"                self.assertEqual(new_ip, lip[\u0027local_ip_address\u0027])"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def test_create_local_ip_with_local_port_id_and_mult_ips_wrong_ip(self):"},{"line_number":177,"context_line":"        with self.port() as p:"},{"line_number":178,"context_line":"            local_port \u003d p[\u0027port\u0027]"},{"line_number":179,"context_line":"            self._port_add_new_ip(local_port)"}],"source_content_type":"text/x-python","patch_set":19,"id":"e3eeced4_3d973fcb","line":176,"range":{"start_line":176,"start_character":52,"end_line":176,"end_character":56},"in_reply_to":"b5a66191_5fab90b3","updated":"2021-11-15 14:07:23.000000000","message":"😂","commit_id":"429dd8d9c4f71b87a76b390ec7c833379f80a39e"}]}
