)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"a3394771247860e0ab66894bc95a69e3a2fef851","unresolved":false,"context_lines":[{"line_number":16,"context_line":"Routers"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"To Do:"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Tests"},{"line_number":21,"context_line":"Reduce code duplication"},{"line_number":22,"context_line":"Feedback to user"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"5a5ae5dd_c66552b5","line":19,"updated":"2016-02-05 10:09:58.000000000","message":"Support fips","commit_id":"e4cda6ab4694a853d83fccbdbc4133a9de7b7f91"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"f760baa21a4b0d236bc67fbb413cfdcaa621e6d7","unresolved":false,"context_lines":[{"line_number":16,"context_line":"Routers"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"To Do:"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Tests"},{"line_number":21,"context_line":"Reduce code duplication"},{"line_number":22,"context_line":"Feedback to user"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"5a5ae5dd_0493eb50","line":19,"in_reply_to":"5a5ae5dd_c66552b5","updated":"2016-02-09 01:51:59.000000000","message":"Done","commit_id":"e4cda6ab4694a853d83fccbdbc4133a9de7b7f91"},{"author":{"_account_id":17776,"name":"Reedip","email":"reedip.banerjee@gmail.com","username":"Reedip"},"change_message_id":"dba7118036bf9b3818c2d8c112a5fba6fdfaf27b","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"Feedback to user"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"DocImpact"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"Change-Id: I5a366d3537191045eb53f9cccd8cd0f7ce54a63b"},{"line_number":26,"context_line":"Closes-Bug: 1511574"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"dae33548_f52f52f4","line":23,"updated":"2016-02-15 03:58:41.000000000","message":"release notes as well","commit_id":"4bf11a5e9e425b3d03c7396ed2ffbf8175aa6fe2"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"8e6b3ac5f9c4df44dcb9c0571d220273134c282f","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"Feedback to user"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"DocImpact"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"Change-Id: I5a366d3537191045eb53f9cccd8cd0f7ce54a63b"},{"line_number":26,"context_line":"Closes-Bug: 1511574"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"dae33548_b4600c37","line":23,"in_reply_to":"dae33548_f52f52f4","updated":"2016-02-15 21:41:17.000000000","message":"Done","commit_id":"4bf11a5e9e425b3d03c7396ed2ffbf8175aa6fe2"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"919a0553f62fc61b650935830a40e5ed3e78625b","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     John Davidge \u003cjodavidg@cisco.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2016-02-15 12:37:52 -0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Support cleanup of tenant resources with a single API call"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The addition of the \u0027neutron purge\u0027 command allows cloud admins"},{"line_number":10,"context_line":"to conveniently delete multiple neutron resources associated"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"dae33548_00bb2928","line":7,"updated":"2016-02-16 23:32:12.000000000","message":"Did you consider some sort of progress bar for this command? A tenant could have thousands of resources.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"3e524f58639abd365b433f78677ccfc481153007","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     John Davidge \u003cjodavidg@cisco.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2016-02-15 12:37:52 -0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Support cleanup of tenant resources with a single API call"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The addition of the \u0027neutron purge\u0027 command allows cloud admins"},{"line_number":10,"context_line":"to conveniently delete multiple neutron resources associated"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"dae33548_c1b422d6","line":7,"in_reply_to":"dae33548_00bb2928","updated":"2016-02-19 01:48:19.000000000","message":"Added progress indication in the latest patch. Makes it more difficult to test the command output functionally, but it\u0027s probably better to do it with a unit test anyway.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"919a0553f62fc61b650935830a40e5ed3e78625b","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Support cleanup of tenant resources with a single API call"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The addition of the \u0027neutron purge\u0027 command allows cloud admins"},{"line_number":10,"context_line":"to conveniently delete multiple neutron resources associated"},{"line_number":11,"context_line":"with a given tenant."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"dae33548_6f9dc658","line":9,"updated":"2016-02-16 23:32:12.000000000","message":"I think that a --dry-run option would be great. My original spec talked about this I believe. It would give you a report of the amount of resources that would be deleted per resource type without actually deleting anything.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"b38fb01c0603516a7b2ef60fddca8a1d71f7bda5","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Support cleanup of tenant resources with a single API call"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The addition of the \u0027neutron purge\u0027 command allows cloud admins"},{"line_number":10,"context_line":"to conveniently delete multiple neutron resources associated"},{"line_number":11,"context_line":"with a given tenant."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"dae33548_db45b4b3","line":9,"in_reply_to":"dae33548_6f9dc658","updated":"2016-02-17 00:19:17.000000000","message":"+1, a dry-run enables to check you are about to delete the correct resources.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"3e524f58639abd365b433f78677ccfc481153007","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Support cleanup of tenant resources with a single API call"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The addition of the \u0027neutron purge\u0027 command allows cloud admins"},{"line_number":10,"context_line":"to conveniently delete multiple neutron resources associated"},{"line_number":11,"context_line":"with a given tenant."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"dae33548_d2d23bd0","line":9,"in_reply_to":"dae33548_6f9dc658","updated":"2016-02-19 01:48:19.000000000","message":"This would definitely be a useful feature. I\u0027ll look at how best to get this done.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"919a0553f62fc61b650935830a40e5ed3e78625b","unresolved":false,"context_lines":[{"line_number":11,"context_line":"with a given tenant."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"The command will delete all supported resources provided that"},{"line_number":14,"context_line":"they can be deleted (not shared, not in use, etc) and feedback"},{"line_number":15,"context_line":"the amount of each resource deleted to the user."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Currently supports deletion of:"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"dae33548_aff4ee86","line":14,"updated":"2016-02-16 23:32:12.000000000","message":"What is the rationale behind not attempting to delete shared networks? If the network is shared, and you successfully deleted it, it means it no longer had any users. I think that if you\u0027re trying to clean up a tenant, and that tenant had a shared network, the intention would be to delete all networks owned by that tenant, including shared ones. We could add a flag to control this (--purge-shared or similar), and I would argue that it should default to True.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"3e524f58639abd365b433f78677ccfc481153007","unresolved":false,"context_lines":[{"line_number":11,"context_line":"with a given tenant."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"The command will delete all supported resources provided that"},{"line_number":14,"context_line":"they can be deleted (not shared, not in use, etc) and feedback"},{"line_number":15,"context_line":"the amount of each resource deleted to the user."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Currently supports deletion of:"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"dae33548_876b5884","line":14,"in_reply_to":"dae33548_aff4ee86","updated":"2016-02-19 01:48:19.000000000","message":"Shared networks are now handled the same as other resources. If it can be deleted it will be.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"b38fb01c0603516a7b2ef60fddca8a1d71f7bda5","unresolved":false,"context_lines":[{"line_number":25,"context_line":"This feature can be easily extended to support more resource"},{"line_number":26,"context_line":"types in the future."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"DocImpact"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"Change-Id: I5a366d3537191045eb53f9cccd8cd0f7ce54a63b"},{"line_number":31,"context_line":"Closes-Bug: 1511574"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"dae33548_3bc82022","line":28,"range":{"start_line":28,"start_character":0,"end_line":28,"end_character":9},"updated":"2016-02-17 00:19:17.000000000","message":"Is it a good idea to add a DocImpact when we have a release note?","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"3e524f58639abd365b433f78677ccfc481153007","unresolved":false,"context_lines":[{"line_number":25,"context_line":"This feature can be easily extended to support more resource"},{"line_number":26,"context_line":"types in the future."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"DocImpact"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"Change-Id: I5a366d3537191045eb53f9cccd8cd0f7ce54a63b"},{"line_number":31,"context_line":"Closes-Bug: 1511574"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"dae33548_07c908ac","line":28,"range":{"start_line":28,"start_character":0,"end_line":28,"end_character":9},"in_reply_to":"dae33548_3bc82022","updated":"2016-02-19 01:48:19.000000000","message":"This change will need more documentation than just a release note, so I think it\u0027s necessary.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"2330e4949ee9c4b323122d335d8992c583797fc9","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"Change-Id: I5a366d3537191045eb53f9cccd8cd0f7ce54a63b"},{"line_number":33,"context_line":"Closes-Bug: 1511574"},{"line_number":34,"context_line":"Partially-Implements: blueprint tenant-delete"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":15,"id":"9aed3d3a_1ba51346","line":34,"updated":"2016-03-01 23:08:01.000000000","message":"Is there any other work to mark the blueprint as completed?","commit_id":"88fbd3870cf3872fb0c9b4269503c62458664b3b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"1a2a321d3f182f1eb60038ff4a44c1275c879730","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"Change-Id: I5a366d3537191045eb53f9cccd8cd0f7ce54a63b"},{"line_number":33,"context_line":"Closes-Bug: 1511574"},{"line_number":34,"context_line":"Partially-Implements: blueprint tenant-delete"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":15,"id":"7af24918_39deb16d","line":34,"in_reply_to":"7af24918_961d1276","updated":"2016-03-01 23:18:34.000000000","message":"Follow-up: Is it worth changing this now? Or can we just mark the bp as complete manually if we decide this patch is sufficient?","commit_id":"88fbd3870cf3872fb0c9b4269503c62458664b3b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"1ed6fe655a635ec2a1c6b8294c826c95a6705586","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"Change-Id: I5a366d3537191045eb53f9cccd8cd0f7ce54a63b"},{"line_number":33,"context_line":"Closes-Bug: 1511574"},{"line_number":34,"context_line":"Partially-Implements: blueprint tenant-delete"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":15,"id":"7af24918_961d1276","line":34,"in_reply_to":"9aed3d3a_1ba51346","updated":"2016-03-01 23:17:29.000000000","message":"If we\u0027re no longer working towards this eventually being done automatically on tenant deletion, then no - this patch would complete it.","commit_id":"88fbd3870cf3872fb0c9b4269503c62458664b3b"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"5170318e172682b0dba3c3e671a968fef41bcaec","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"Change-Id: I5a366d3537191045eb53f9cccd8cd0f7ce54a63b"},{"line_number":33,"context_line":"Closes-Bug: 1511574"},{"line_number":34,"context_line":"Partially-Implements: blueprint tenant-delete"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":15,"id":"7af24918_8e13f90c","line":34,"in_reply_to":"9aed3d3a_1ba51346","updated":"2016-03-02 17:45:32.000000000","message":"We\u0027ll have to do that manually in any case. Besides we\u0027re still pending on docs.","commit_id":"88fbd3870cf3872fb0c9b4269503c62458664b3b"}],"neutronclient/neutron/v2_0/purge.py":[{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"c7fdaff5b37b17882f3f26ff36bbf1940beb1bab","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"class Purge(neutronV20.NeutronCommand):"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    def _purge_networks(self, neutron_client, parsed_args):"},{"line_number":24,"context_line":"        search_opts \u003d {\u0027fields\u0027: [\u0027id\u0027, \u0027tenant_id\u0027, \u0027shared\u0027]}"},{"line_number":25,"context_line":"        networks \u003d neutron_client.list_networks(**search_opts).get(\u0027networks\u0027,"},{"line_number":26,"context_line":"                                                                   [])"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a5ae5dd_1e074119","line":23,"range":{"start_line":23,"start_character":8,"end_line":23,"end_character":23},"updated":"2016-02-05 02:39:33.000000000","message":"reducing code duplication between these _purge functions is on my to do list","commit_id":"e4cda6ab4694a853d83fccbdbc4133a9de7b7f91"},{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"a3394771247860e0ab66894bc95a69e3a2fef851","unresolved":false,"context_lines":[{"line_number":32,"context_line":"                except Exception:"},{"line_number":33,"context_line":"                    # Skip deleting this network if it has active ports or is"},{"line_number":34,"context_line":"                    # otherwise undeletable"},{"line_number":35,"context_line":"                    pass"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def _purge_subnets(self, neutron_client, parsed_args):"},{"line_number":38,"context_line":"        search_opts \u003d {\u0027fields\u0027: [\u0027id\u0027, \u0027tenant_id\u0027]}"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a5ae5dd_06512ad8","line":35,"range":{"start_line":35,"start_character":20,"end_line":35,"end_character":24},"updated":"2016-02-05 10:09:58.000000000","message":"you should not silently catch exceptions except NotFound ones","commit_id":"e4cda6ab4694a853d83fccbdbc4133a9de7b7f91"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"f760baa21a4b0d236bc67fbb413cfdcaa621e6d7","unresolved":false,"context_lines":[{"line_number":32,"context_line":"                except Exception:"},{"line_number":33,"context_line":"                    # Skip deleting this network if it has active ports or is"},{"line_number":34,"context_line":"                    # otherwise undeletable"},{"line_number":35,"context_line":"                    pass"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def _purge_subnets(self, neutron_client, parsed_args):"},{"line_number":38,"context_line":"        search_opts \u003d {\u0027fields\u0027: [\u0027id\u0027, \u0027tenant_id\u0027]}"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a5ae5dd_4effc2aa","line":35,"range":{"start_line":35,"start_character":20,"end_line":35,"end_character":24},"in_reply_to":"5a5ae5dd_06512ad8","updated":"2016-02-09 01:51:59.000000000","message":"The discussion so far seems to be in favor of failing gracefully and moving on to the next resource if a given resource cannot be deleted for some reason. See https://bugs.launchpad.net/neutron/+bug/1511574/comments/12","commit_id":"e4cda6ab4694a853d83fccbdbc4133a9de7b7f91"},{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"a3394771247860e0ab66894bc95a69e3a2fef851","unresolved":false,"context_lines":[{"line_number":34,"context_line":"                    # otherwise undeletable"},{"line_number":35,"context_line":"                    pass"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def _purge_subnets(self, neutron_client, parsed_args):"},{"line_number":38,"context_line":"        search_opts \u003d {\u0027fields\u0027: [\u0027id\u0027, \u0027tenant_id\u0027]}"},{"line_number":39,"context_line":"        subnets \u003d neutron_client.list_subnets(**search_opts).get(\u0027subnets\u0027, [])"},{"line_number":40,"context_line":"        for subnet in subnets:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a5ae5dd_263d46c4","line":37,"range":{"start_line":37,"start_character":8,"end_line":37,"end_character":22},"updated":"2016-02-05 10:09:58.000000000","message":"Do we need to purge subnets as we can delete networks with subnets","commit_id":"e4cda6ab4694a853d83fccbdbc4133a9de7b7f91"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"f760baa21a4b0d236bc67fbb413cfdcaa621e6d7","unresolved":false,"context_lines":[{"line_number":34,"context_line":"                    # otherwise undeletable"},{"line_number":35,"context_line":"                    pass"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def _purge_subnets(self, neutron_client, parsed_args):"},{"line_number":38,"context_line":"        search_opts \u003d {\u0027fields\u0027: [\u0027id\u0027, \u0027tenant_id\u0027]}"},{"line_number":39,"context_line":"        subnets \u003d neutron_client.list_subnets(**search_opts).get(\u0027subnets\u0027, [])"},{"line_number":40,"context_line":"        for subnet in subnets:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a5ae5dd_1a80298b","line":37,"range":{"start_line":37,"start_character":8,"end_line":37,"end_character":22},"in_reply_to":"5a5ae5dd_263d46c4","updated":"2016-02-09 01:51:59.000000000","message":"Good point. Not explicitly doing this will save us some API calls. Done.","commit_id":"e4cda6ab4694a853d83fccbdbc4133a9de7b7f91"},{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"a3394771247860e0ab66894bc95a69e3a2fef851","unresolved":false,"context_lines":[{"line_number":54,"context_line":"                except Exception:"},{"line_number":55,"context_line":"                    pass"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def _purge_routers(self, neutron_client, parsed_args):"},{"line_number":58,"context_line":"        search_opts \u003d {\u0027fields\u0027: [\u0027id\u0027, \u0027tenant_id\u0027]}"},{"line_number":59,"context_line":"        routers \u003d neutron_client.list_routers(**search_opts).get(\u0027routers\u0027, [])"},{"line_number":60,"context_line":"        for router in routers:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a5ae5dd_e6e5ee37","line":57,"range":{"start_line":57,"start_character":8,"end_line":57,"end_character":22},"updated":"2016-02-05 10:09:58.000000000","message":"You should delete router interfaces before the router","commit_id":"e4cda6ab4694a853d83fccbdbc4133a9de7b7f91"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"f760baa21a4b0d236bc67fbb413cfdcaa621e6d7","unresolved":false,"context_lines":[{"line_number":54,"context_line":"                except Exception:"},{"line_number":55,"context_line":"                    pass"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def _purge_routers(self, neutron_client, parsed_args):"},{"line_number":58,"context_line":"        search_opts \u003d {\u0027fields\u0027: [\u0027id\u0027, \u0027tenant_id\u0027]}"},{"line_number":59,"context_line":"        routers \u003d neutron_client.list_routers(**search_opts).get(\u0027routers\u0027, [])"},{"line_number":60,"context_line":"        for router in routers:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a5ae5dd_ae075617","line":57,"range":{"start_line":57,"start_character":8,"end_line":57,"end_character":22},"in_reply_to":"5a5ae5dd_e6e5ee37","updated":"2016-02-09 01:51:59.000000000","message":"Done","commit_id":"e4cda6ab4694a853d83fccbdbc4133a9de7b7f91"},{"author":{"_account_id":17776,"name":"Reedip","email":"reedip.banerjee@gmail.com","username":"Reedip"},"change_message_id":"fa33325ae9d68cfe1e8b015db053ffe1af1b10ee","unresolved":false,"context_lines":[{"line_number":67,"context_line":"    def get_parser(self, prog_name):"},{"line_number":68,"context_line":"        parser \u003d super(Purge, self).get_parser(prog_name)"},{"line_number":69,"context_line":"        parser.add_argument("},{"line_number":70,"context_line":"            \u0027--tenant\u0027, type\u003dstr,"},{"line_number":71,"context_line":"            help\u003d_(\u0027ID of Tenant owning the resources to be deleted.\u0027))"},{"line_number":72,"context_line":"        return parser"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"5a5ae5dd_5e3939a3","line":70,"updated":"2016-02-05 02:51:32.000000000","message":"do you need this to be optional or necessary?\nIf necessary ( as per Line#76), either make it a positional argument or provide the attribute \"required\u003dTrue\" in the add_argument function","commit_id":"e4cda6ab4694a853d83fccbdbc4133a9de7b7f91"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"f760baa21a4b0d236bc67fbb413cfdcaa621e6d7","unresolved":false,"context_lines":[{"line_number":67,"context_line":"    def get_parser(self, prog_name):"},{"line_number":68,"context_line":"        parser \u003d super(Purge, self).get_parser(prog_name)"},{"line_number":69,"context_line":"        parser.add_argument("},{"line_number":70,"context_line":"            \u0027--tenant\u0027, type\u003dstr,"},{"line_number":71,"context_line":"            help\u003d_(\u0027ID of Tenant owning the resources to be deleted.\u0027))"},{"line_number":72,"context_line":"        return parser"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"5a5ae5dd_6edcfe74","line":70,"in_reply_to":"5a5ae5dd_5e3939a3","updated":"2016-02-09 01:51:59.000000000","message":"Done","commit_id":"e4cda6ab4694a853d83fccbdbc4133a9de7b7f91"},{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"b38fb01c0603516a7b2ef60fddca8a1d71f7bda5","unresolved":false,"context_lines":[{"line_number":17,"context_line":"from neutronclient.neutron import v2_0 as neutronV20"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"class Purge(neutronV20.NeutronCommand):"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"    def _get_resources(self, neutron_client, resource_type):"},{"line_number":23,"context_line":"        opts \u003d {\u0027fields\u0027: [\u0027id\u0027, \u0027tenant_id\u0027]}"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_7b83c804","line":20,"range":{"start_line":20,"start_character":23,"end_line":20,"end_character":37},"updated":"2016-02-17 00:19:17.000000000","message":"This class command will become difficult to maintain if we add more resource-types and to extend if we want to support neutron-aas/plugin resource-types.\n\nIMO, we will need in the future to refactor this module by defining purge classes (one for each resource-type) managed by this class. It will enable inheritance usage, extension, etc AND simplify UT.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"919a0553f62fc61b650935830a40e5ed3e78625b","unresolved":false,"context_lines":[{"line_number":23,"context_line":"        opts \u003d {\u0027fields\u0027: [\u0027id\u0027, \u0027tenant_id\u0027]}"},{"line_number":24,"context_line":"        if resource_type \u003d\u003d \u0027networks\u0027:"},{"line_number":25,"context_line":"            opts[\u0027fields\u0027].append(\u0027shared\u0027)"},{"line_number":26,"context_line":"            return neutron_client.list_networks(**opts).get(resource_type, [])"},{"line_number":27,"context_line":"        elif resource_type \u003d\u003d \u0027routers\u0027:"},{"line_number":28,"context_line":"            return neutron_client.list_routers(**opts).get(resource_type, [])"},{"line_number":29,"context_line":"        elif resource_type \u003d\u003d \u0027ports\u0027:"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_a521afb6","line":26,"updated":"2016-02-16 23:32:12.000000000","message":"Similar comment to my comment on line 37. We could simplify this so that for most resource types this function is a one liner. For specific resources you can obtain additional fields (Like shared for networks, etc).","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"3e524f58639abd365b433f78677ccfc481153007","unresolved":false,"context_lines":[{"line_number":23,"context_line":"        opts \u003d {\u0027fields\u0027: [\u0027id\u0027, \u0027tenant_id\u0027]}"},{"line_number":24,"context_line":"        if resource_type \u003d\u003d \u0027networks\u0027:"},{"line_number":25,"context_line":"            opts[\u0027fields\u0027].append(\u0027shared\u0027)"},{"line_number":26,"context_line":"            return neutron_client.list_networks(**opts).get(resource_type, [])"},{"line_number":27,"context_line":"        elif resource_type \u003d\u003d \u0027routers\u0027:"},{"line_number":28,"context_line":"            return neutron_client.list_routers(**opts).get(resource_type, [])"},{"line_number":29,"context_line":"        elif resource_type \u003d\u003d \u0027ports\u0027:"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_8dc37737","line":26,"in_reply_to":"dae33548_a521afb6","updated":"2016-02-19 01:48:19.000000000","message":"Done","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"919a0553f62fc61b650935830a40e5ed3e78625b","unresolved":false,"context_lines":[{"line_number":33,"context_line":"            return neutron_client.list_floatingips(**opts).get(resource_type,"},{"line_number":34,"context_line":"                                                               [])"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    def _delete_resource(self, neutron_client, resource_type, id):"},{"line_number":37,"context_line":"        if resource_type \u003d\u003d \u0027networks\u0027:"},{"line_number":38,"context_line":"            # Deleting a network will also delete all child subnets if possible"},{"line_number":39,"context_line":"            neutron_client.delete_network(id)"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_85a0eb44","line":36,"updated":"2016-02-16 23:32:12.000000000","message":"You\u0027re shadowing the \u0027id\u0027 function here. Perhaps \u0027resource_id\u0027?","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"3e524f58639abd365b433f78677ccfc481153007","unresolved":false,"context_lines":[{"line_number":33,"context_line":"            return neutron_client.list_floatingips(**opts).get(resource_type,"},{"line_number":34,"context_line":"                                                               [])"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    def _delete_resource(self, neutron_client, resource_type, id):"},{"line_number":37,"context_line":"        if resource_type \u003d\u003d \u0027networks\u0027:"},{"line_number":38,"context_line":"            # Deleting a network will also delete all child subnets if possible"},{"line_number":39,"context_line":"            neutron_client.delete_network(id)"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_6dbef3ae","line":36,"in_reply_to":"dae33548_85a0eb44","updated":"2016-02-19 01:48:19.000000000","message":"Done","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"919a0553f62fc61b650935830a40e5ed3e78625b","unresolved":false,"context_lines":[{"line_number":34,"context_line":"                                                               [])"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    def _delete_resource(self, neutron_client, resource_type, id):"},{"line_number":37,"context_line":"        if resource_type \u003d\u003d \u0027networks\u0027:"},{"line_number":38,"context_line":"            # Deleting a network will also delete all child subnets if possible"},{"line_number":39,"context_line":"            neutron_client.delete_network(id)"},{"line_number":40,"context_line":"            self.networks +\u003d 1"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_e57d77b2","line":37,"updated":"2016-02-16 23:32:12.000000000","message":"If the list of resource_types will be exactly \u0027network\u0027, \u0027router\u0027 etc (So that it fits delete_%s), you can get rid of the switch case on the resource type and just have this:\n\ngetattr(neutron_client, \u0027delete_%s\u0027 % resource_type)(resource_id)\n\nIf you combine this with my suggestion that gets rid of the self.counters, this function is collapsed in to a single line.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"3e524f58639abd365b433f78677ccfc481153007","unresolved":false,"context_lines":[{"line_number":34,"context_line":"                                                               [])"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    def _delete_resource(self, neutron_client, resource_type, id):"},{"line_number":37,"context_line":"        if resource_type \u003d\u003d \u0027networks\u0027:"},{"line_number":38,"context_line":"            # Deleting a network will also delete all child subnets if possible"},{"line_number":39,"context_line":"            neutron_client.delete_network(id)"},{"line_number":40,"context_line":"            self.networks +\u003d 1"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_0de647e7","line":37,"in_reply_to":"dae33548_e57d77b2","updated":"2016-02-19 01:48:19.000000000","message":"Done","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"b38fb01c0603516a7b2ef60fddca8a1d71f7bda5","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            neutron_client.delete_floatingip(id)"},{"line_number":49,"context_line":"            self.floatingips +\u003d 1"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def _purge_resource(self, neutron_client, parsed_args, resource_type):"},{"line_number":52,"context_line":"        resources \u003d self._get_resources(neutron_client, resource_type)"},{"line_number":53,"context_line":"        for resource in resources:"},{"line_number":54,"context_line":"            if (resource[\u0027tenant_id\u0027] \u003d\u003d parsed_args.tenant and"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_c055c150","line":51,"range":{"start_line":51,"start_character":8,"end_line":51,"end_character":23},"updated":"2016-02-17 00:19:17.000000000","message":"this method purges resourceS so:\n\n  def _purge_resources\n\nseems better","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"3e524f58639abd365b433f78677ccfc481153007","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            neutron_client.delete_floatingip(id)"},{"line_number":49,"context_line":"            self.floatingips +\u003d 1"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def _purge_resource(self, neutron_client, parsed_args, resource_type):"},{"line_number":52,"context_line":"        resources \u003d self._get_resources(neutron_client, resource_type)"},{"line_number":53,"context_line":"        for resource in resources:"},{"line_number":54,"context_line":"            if (resource[\u0027tenant_id\u0027] \u003d\u003d parsed_args.tenant and"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_ede843b5","line":51,"range":{"start_line":51,"start_character":8,"end_line":51,"end_character":23},"in_reply_to":"dae33548_c055c150","updated":"2016-02-19 01:48:19.000000000","message":"Done","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"919a0553f62fc61b650935830a40e5ed3e78625b","unresolved":false,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def _purge_resource(self, neutron_client, parsed_args, resource_type):"},{"line_number":52,"context_line":"        resources \u003d self._get_resources(neutron_client, resource_type)"},{"line_number":53,"context_line":"        for resource in resources:"},{"line_number":54,"context_line":"            if (resource[\u0027tenant_id\u0027] \u003d\u003d parsed_args.tenant and"},{"line_number":55,"context_line":"                    not resource.get(\u0027shared\u0027, False) and"},{"line_number":56,"context_line":"                    not resource.get(\u0027device_owner\u0027, \u0027\u0027) \u003d\u003d \u0027network:dhcp\u0027):"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_20d46d45","line":53,"updated":"2016-02-16 23:32:12.000000000","message":"I wonder if we can get fancy and use multiprocessing to delete batches of the same resource type... Just thinking out loud.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"b38fb01c0603516a7b2ef60fddca8a1d71f7bda5","unresolved":false,"context_lines":[{"line_number":53,"context_line":"        for resource in resources:"},{"line_number":54,"context_line":"            if (resource[\u0027tenant_id\u0027] \u003d\u003d parsed_args.tenant and"},{"line_number":55,"context_line":"                    not resource.get(\u0027shared\u0027, False) and"},{"line_number":56,"context_line":"                    not resource.get(\u0027device_owner\u0027, \u0027\u0027) \u003d\u003d \u0027network:dhcp\u0027):"},{"line_number":57,"context_line":"                try:"},{"line_number":58,"context_line":"                    self._delete_resource(neutron_client, resource_type,"},{"line_number":59,"context_line":"                                          resource[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_dbb5b431","line":56,"range":{"start_line":56,"start_character":61,"end_line":56,"end_character":68},"updated":"2016-02-17 00:19:17.000000000","message":"IMO, we should not unbind a router from a subnet by deleting its port on subnet\u0027s network: we should use router-interface-delete as it\u0027s the one supported by neutron (AFAIK?)","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"3e524f58639abd365b433f78677ccfc481153007","unresolved":false,"context_lines":[{"line_number":53,"context_line":"        for resource in resources:"},{"line_number":54,"context_line":"            if (resource[\u0027tenant_id\u0027] \u003d\u003d parsed_args.tenant and"},{"line_number":55,"context_line":"                    not resource.get(\u0027shared\u0027, False) and"},{"line_number":56,"context_line":"                    not resource.get(\u0027device_owner\u0027, \u0027\u0027) \u003d\u003d \u0027network:dhcp\u0027):"},{"line_number":57,"context_line":"                try:"},{"line_number":58,"context_line":"                    self._delete_resource(neutron_client, resource_type,"},{"line_number":59,"context_line":"                                          resource[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_12d943f3","line":56,"range":{"start_line":56,"start_character":61,"end_line":56,"end_character":68},"in_reply_to":"dae33548_dbb5b431","updated":"2016-02-19 01:48:19.000000000","message":"Done","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"c53ae1e6e1641fc854b4e8ed21cb00235907cdbf","unresolved":false,"context_lines":[{"line_number":53,"context_line":"        for resource in resources:"},{"line_number":54,"context_line":"            if (resource[\u0027tenant_id\u0027] \u003d\u003d parsed_args.tenant and"},{"line_number":55,"context_line":"                    not resource.get(\u0027shared\u0027, False) and"},{"line_number":56,"context_line":"                    not resource.get(\u0027device_owner\u0027, \u0027\u0027) \u003d\u003d \u0027network:dhcp\u0027):"},{"line_number":57,"context_line":"                try:"},{"line_number":58,"context_line":"                    self._delete_resource(neutron_client, resource_type,"},{"line_number":59,"context_line":"                                          resource[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_1196dc3e","line":56,"range":{"start_line":56,"start_character":61,"end_line":56,"end_character":68},"in_reply_to":"dae33548_dbb5b431","updated":"2016-02-17 01:52:07.000000000","message":"Funny I just logged back on to comment on this - When deleting routers you must also clear its gateway and remove all of its internal interfaces.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"919a0553f62fc61b650935830a40e5ed3e78625b","unresolved":false,"context_lines":[{"line_number":57,"context_line":"                try:"},{"line_number":58,"context_line":"                    self._delete_resource(neutron_client, resource_type,"},{"line_number":59,"context_line":"                                          resource[\u0027id\u0027])"},{"line_number":60,"context_line":"                except Exception:"},{"line_number":61,"context_line":"                    # Skip deleting this resource if it cannot be deleted for"},{"line_number":62,"context_line":"                    # any reason and move on to the next one"},{"line_number":63,"context_line":"                    pass"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_0f319a05","line":60,"updated":"2016-02-16 23:32:12.000000000","message":"I agree with Cedric from PS 1, we should be catching NotFound  and InUse exceptions here. Can you think of other reasons why this would fail? I wouldn\u0027t want to mask unexpected failures.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":17776,"name":"Reedip","email":"reedip.banerjee@gmail.com","username":"Reedip"},"change_message_id":"7cda829456d07a5e0124d040fe91e4fa40842ff7","unresolved":false,"context_lines":[{"line_number":59,"context_line":"                                          resource[\u0027id\u0027])"},{"line_number":60,"context_line":"                except Exception:"},{"line_number":61,"context_line":"                    # Skip deleting this resource if it cannot be deleted for"},{"line_number":62,"context_line":"                    # any reason and move on to the next one"},{"line_number":63,"context_line":"                    pass"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def get_parser(self, prog_name):"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_3904e8be","line":62,"updated":"2016-02-16 00:14:19.000000000","message":"Can we put up an error/warning message here?\nThis means that if there are any resources which are skipped due to generation of an exception, no error/warning message would be generated for them.Line#91 just states the number of resources deleted, but the ones which are skipped should be notified to the user so that atleast the user doesnt think the purge was successful","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"3e524f58639abd365b433f78677ccfc481153007","unresolved":false,"context_lines":[{"line_number":59,"context_line":"                                          resource[\u0027id\u0027])"},{"line_number":60,"context_line":"                except Exception:"},{"line_number":61,"context_line":"                    # Skip deleting this resource if it cannot be deleted for"},{"line_number":62,"context_line":"                    # any reason and move on to the next one"},{"line_number":63,"context_line":"                    pass"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def get_parser(self, prog_name):"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_6dec33bb","line":62,"in_reply_to":"dae33548_3904e8be","updated":"2016-02-19 01:48:19.000000000","message":"Done","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":17776,"name":"Reedip","email":"reedip.banerjee@gmail.com","username":"Reedip"},"change_message_id":"7cda829456d07a5e0124d040fe91e4fa40842ff7","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        parser \u003d super(Purge, self).get_parser(prog_name)"},{"line_number":67,"context_line":"        parser.add_argument("},{"line_number":68,"context_line":"            \u0027tenant\u0027, metavar\u003d\u0027TENANT\u0027,"},{"line_number":69,"context_line":"            help\u003d_(\u0027ID of Tenant owning the resources to be deleted.\u0027))"},{"line_number":70,"context_line":"        return parser"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def run(self, parsed_args):"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_5930cc56","line":69,"updated":"2016-02-16 00:14:19.000000000","message":"If I do not pass the tenant ID, should it take up the Tenant ID of the current tenant? Would that be useful for the user?","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"919a0553f62fc61b650935830a40e5ed3e78625b","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        parser \u003d super(Purge, self).get_parser(prog_name)"},{"line_number":67,"context_line":"        parser.add_argument("},{"line_number":68,"context_line":"            \u0027tenant\u0027, metavar\u003d\u0027TENANT\u0027,"},{"line_number":69,"context_line":"            help\u003d_(\u0027ID of Tenant owning the resources to be deleted.\u0027))"},{"line_number":70,"context_line":"        return parser"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def run(self, parsed_args):"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_4f89e225","line":69,"in_reply_to":"dae33548_1945a316","updated":"2016-02-16 23:32:12.000000000","message":"I think one typical use case would be to invoke this script on a tenant that was already deleted, in which case you couldn\u0027t authenticate with that tenant ID, so you wouldn\u0027t be able to run this command on your own tenant ID anyway. I also agree with John about preventing accidental resource deletion.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"a4a729602b0793a25d62f5c3d946f218641ffb83","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        parser \u003d super(Purge, self).get_parser(prog_name)"},{"line_number":67,"context_line":"        parser.add_argument("},{"line_number":68,"context_line":"            \u0027tenant\u0027, metavar\u003d\u0027TENANT\u0027,"},{"line_number":69,"context_line":"            help\u003d_(\u0027ID of Tenant owning the resources to be deleted.\u0027))"},{"line_number":70,"context_line":"        return parser"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def run(self, parsed_args):"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_1945a316","line":69,"in_reply_to":"dae33548_5930cc56","updated":"2016-02-16 00:45:53.000000000","message":"From a convenience standpoint I can see how that could be useful for a user who wants to delete their own resources. However, due to the potential impact of accidental purges, I think it\u0027s better to require the tenant_id in all cases to ensure that the user DEFINITELY knows what\u0027s about to happen.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"919a0553f62fc61b650935830a40e5ed3e78625b","unresolved":false,"context_lines":[{"line_number":72,"context_line":"    def run(self, parsed_args):"},{"line_number":73,"context_line":"        neutron_client \u003d self.get_client()"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        self.floatingips \u003d 0"},{"line_number":76,"context_line":"        self.networks \u003d 0"},{"line_number":77,"context_line":"        self.routers \u003d 0"},{"line_number":78,"context_line":"        self.ports \u003d 0"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_e54577b3","line":75,"updated":"2016-02-16 23:32:12.000000000","message":"Let\u0027s get rid of these counters at the class level. You can have _purge_resource return the number of records it deleted, then change lines 84 to 89 to something like:\n\nfor resource_type in resource_types:\n    deleted \u003d self._purge_resource(...)\n    data[resource_type] \u003d deleted\n\nThis allows you to get rid of the references to self.floatingips (etc) in _delete_resource. It simplifies things by no longer sharing state between functions.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"3e524f58639abd365b433f78677ccfc481153007","unresolved":false,"context_lines":[{"line_number":72,"context_line":"    def run(self, parsed_args):"},{"line_number":73,"context_line":"        neutron_client \u003d self.get_client()"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        self.floatingips \u003d 0"},{"line_number":76,"context_line":"        self.networks \u003d 0"},{"line_number":77,"context_line":"        self.routers \u003d 0"},{"line_number":78,"context_line":"        self.ports \u003d 0"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_cd2d7fff","line":75,"in_reply_to":"dae33548_e54577b3","updated":"2016-02-19 01:48:19.000000000","message":"Done","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":17776,"name":"Reedip","email":"reedip.banerjee@gmail.com","username":"Reedip"},"change_message_id":"7cda829456d07a5e0124d040fe91e4fa40842ff7","unresolved":false,"context_lines":[{"line_number":89,"context_line":"                \u0027tenant\u0027: parsed_args.tenant}"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        print(_(\u0027Deleted %(net)s networks, %(router)s routers, %(port)s \u0027"},{"line_number":92,"context_line":"                \u0027ports, and %(fip)s floatingips for tenant \u0027"},{"line_number":93,"context_line":"                \u0027%(tenant)s.\u0027) % data)"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_999ed454","line":92,"updated":"2016-02-16 00:14:19.000000000","message":"While I think showing count is good, I think this can be improved:\na) by showing the names of each resource OR\nb) by showing (Number of Resources Deleted)/ ( Total Number of resources)\n\nOption (b) suits more because that way user does not need to be shown the exception message in Line number 62.\nUser would only require the number of successful deletions.\nUser can try to delete the rest of the resources individually, after fixing the respective problems for deletion of the resources.\n\nThis is my idea, awaiting comments from other reviewers","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"919a0553f62fc61b650935830a40e5ed3e78625b","unresolved":false,"context_lines":[{"line_number":89,"context_line":"                \u0027tenant\u0027: parsed_args.tenant}"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        print(_(\u0027Deleted %(net)s networks, %(router)s routers, %(port)s \u0027"},{"line_number":92,"context_line":"                \u0027ports, and %(fip)s floatingips for tenant \u0027"},{"line_number":93,"context_line":"                \u0027%(tenant)s.\u0027) % data)"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_655e8777","line":92,"in_reply_to":"dae33548_596e0b97","updated":"2016-02-16 23:32:12.000000000","message":"A final report is great. This goes hand in hand with my comment about --dry-run.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"a4a729602b0793a25d62f5c3d946f218641ffb83","unresolved":false,"context_lines":[{"line_number":89,"context_line":"                \u0027tenant\u0027: parsed_args.tenant}"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        print(_(\u0027Deleted %(net)s networks, %(router)s routers, %(port)s \u0027"},{"line_number":92,"context_line":"                \u0027ports, and %(fip)s floatingips for tenant \u0027"},{"line_number":93,"context_line":"                \u0027%(tenant)s.\u0027) % data)"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_596e0b97","line":92,"in_reply_to":"dae33548_999ed454","updated":"2016-02-16 00:45:53.000000000","message":"I like the idea you\u0027ve outlined in option b. Will work on a new patch to address it. Thanks","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":17776,"name":"Reedip","email":"reedip.banerjee@gmail.com","username":"Reedip"},"change_message_id":"48d069572f99837720d5cc31a2a10bb2c3193fb4","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        deleted \u003d {}"},{"line_number":58,"context_line":"        failed \u003d {}"},{"line_number":59,"context_line":"        failures \u003d False"},{"line_number":60,"context_line":"        for resource_type, resources in tenant_resources.iteritems():"},{"line_number":61,"context_line":"            failed[resource_type] \u003d 0"},{"line_number":62,"context_line":"            deleted[resource_type] \u003d 0"},{"line_number":63,"context_line":"            for resource in resources:"}],"source_content_type":"text/x-python","patch_set":7,"id":"dae33548_76a9967b","line":60,"updated":"2016-02-19 03:15:02.000000000","message":"As jenkins said, this should be converted to tenant_resources.items()","commit_id":"ae50dcb6c6d56449e0965e5d1fada3000a9a0551"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"828ed4e212165fa20dbeacdc08bc23f838d90a5c","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        deleted \u003d {}"},{"line_number":58,"context_line":"        failed \u003d {}"},{"line_number":59,"context_line":"        failures \u003d False"},{"line_number":60,"context_line":"        for resource_type, resources in tenant_resources.iteritems():"},{"line_number":61,"context_line":"            failed[resource_type] \u003d 0"},{"line_number":62,"context_line":"            deleted[resource_type] \u003d 0"},{"line_number":63,"context_line":"            for resource in resources:"}],"source_content_type":"text/x-python","patch_set":7,"id":"bae84128_8be21502","line":60,"in_reply_to":"dae33548_76a9967b","updated":"2016-02-23 19:59:33.000000000","message":"Done","commit_id":"ae50dcb6c6d56449e0965e5d1fada3000a9a0551"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"955153507664f79b9c69c82ee13cb650eb29d578","unresolved":false,"context_lines":[{"line_number":39,"context_line":"                    if resource[\u0027tenant_id\u0027] \u003d\u003d tenant_id:"},{"line_number":40,"context_line":"                        resources[resource_type].append(resource)"},{"line_number":41,"context_line":"                        self.total_resources +\u003d 1"},{"line_number":42,"context_line":"        return resources"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    def _delete_resource(self, neutron_client, resource_type, resource):"},{"line_number":45,"context_line":"        resource_id \u003d resource[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":10,"id":"bae84128_74cc376a","line":42,"range":{"start_line":42,"start_character":15,"end_line":42,"end_character":24},"updated":"2016-02-23 19:59:41.000000000","message":"This needs to return a list rather than a dict to maintain deletion order.","commit_id":"1671b63dd809aa5780a846c8f75fc1e4c2ae232a"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"df18429eb0c9d50bf8e499664a69ef58d4950450","unresolved":false,"context_lines":[{"line_number":119,"context_line":""},{"line_number":120,"context_line":"        # A list of the types of resources supported in the order in which"},{"line_number":121,"context_line":"        # they should be deleted."},{"line_number":122,"context_line":"        resource_types \u003d [\u0027floatingip\u0027, \u0027port\u0027, \u0027router\u0027, \u0027network\u0027]"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        deleted \u003d {}"},{"line_number":125,"context_line":"        failed \u003d {}"}],"source_content_type":"text/x-python","patch_set":10,"id":"bae84128_06eb1a79","line":122,"updated":"2016-02-23 13:05:51.000000000","message":"what about security groups? Are they ignored for any particular reason?","commit_id":"1671b63dd809aa5780a846c8f75fc1e4c2ae232a"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"955153507664f79b9c69c82ee13cb650eb29d578","unresolved":false,"context_lines":[{"line_number":119,"context_line":""},{"line_number":120,"context_line":"        # A list of the types of resources supported in the order in which"},{"line_number":121,"context_line":"        # they should be deleted."},{"line_number":122,"context_line":"        resource_types \u003d [\u0027floatingip\u0027, \u0027port\u0027, \u0027router\u0027, \u0027network\u0027]"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        deleted \u003d {}"},{"line_number":125,"context_line":"        failed \u003d {}"}],"source_content_type":"text/x-python","patch_set":10,"id":"bae84128_5ea2f499","line":122,"in_reply_to":"bae84128_06eb1a79","updated":"2016-02-23 19:59:41.000000000","message":"No, I missed these from the ospurge list. Will add them.","commit_id":"1671b63dd809aa5780a846c8f75fc1e4c2ae232a"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"3d88436fc58330fb206013888cc4b6466d050104","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def _build_message(self, deleted, failed, failures):"},{"line_number":87,"context_line":"        msg \u003d []"},{"line_number":88,"context_line":"        for resource, value in deleted.items():"},{"line_number":89,"context_line":"            if value:"},{"line_number":90,"context_line":"                if not msg:"},{"line_number":91,"context_line":"                    msg \u003d list(_(\u0027Deleted\u0027))"}],"source_content_type":"text/x-python","patch_set":13,"id":"9aed3d3a_1383fccd","line":88,"updated":"2016-02-25 18:04:53.000000000","message":"Seems like lots of work to convert strings to lists of characters, manipulate the list, and then then convert them back to a a string.\n\nHow about creating a list of strings for the deleted items, and a then at the end join them with a \u0027,\u0027 and add a period. Then do the same for failures?","commit_id":"a1aa01f3dd4a2ac7e788797369154b216bae32cf"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"cba9530cb1f28bc8475c43423f93c042062516e0","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def _build_message(self, deleted, failed, failures):"},{"line_number":87,"context_line":"        msg \u003d []"},{"line_number":88,"context_line":"        for resource, value in deleted.items():"},{"line_number":89,"context_line":"            if value:"},{"line_number":90,"context_line":"                if not msg:"},{"line_number":91,"context_line":"                    msg \u003d list(_(\u0027Deleted\u0027))"}],"source_content_type":"text/x-python","patch_set":13,"id":"9aed3d3a_0be2a003","line":88,"in_reply_to":"9aed3d3a_1383fccd","updated":"2016-02-25 19:19:57.000000000","message":"Done","commit_id":"a1aa01f3dd4a2ac7e788797369154b216bae32cf"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"3d88436fc58330fb206013888cc4b6466d050104","unresolved":false,"context_lines":[{"line_number":89,"context_line":"            if value:"},{"line_number":90,"context_line":"                if not msg:"},{"line_number":91,"context_line":"                    msg \u003d list(_(\u0027Deleted\u0027))"},{"line_number":92,"context_line":"                if not value \u003d\u003d 1:"},{"line_number":93,"context_line":"                    resource \u003d resource + \u0027s\u0027"},{"line_number":94,"context_line":"                msg +\u003d list(\" %d %s,\" % (value, resource))"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        if failures:"}],"source_content_type":"text/x-python","patch_set":13,"id":"9aed3d3a_33d8c0ef","line":93,"range":{"start_line":92,"start_character":0,"end_line":93,"end_character":45},"updated":"2016-02-25 18:04:53.000000000","message":"Considering pluralizing is used a couple of times, could maybe use a method?","commit_id":"a1aa01f3dd4a2ac7e788797369154b216bae32cf"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"cba9530cb1f28bc8475c43423f93c042062516e0","unresolved":false,"context_lines":[{"line_number":89,"context_line":"            if value:"},{"line_number":90,"context_line":"                if not msg:"},{"line_number":91,"context_line":"                    msg \u003d list(_(\u0027Deleted\u0027))"},{"line_number":92,"context_line":"                if not value \u003d\u003d 1:"},{"line_number":93,"context_line":"                    resource \u003d resource + \u0027s\u0027"},{"line_number":94,"context_line":"                msg +\u003d list(\" %d %s,\" % (value, resource))"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        if failures:"}],"source_content_type":"text/x-python","patch_set":13,"id":"9aed3d3a_4be4a80c","line":93,"range":{"start_line":92,"start_character":0,"end_line":93,"end_character":45},"in_reply_to":"9aed3d3a_33d8c0ef","updated":"2016-02-25 19:19:57.000000000","message":"Done","commit_id":"a1aa01f3dd4a2ac7e788797369154b216bae32cf"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"b8aefabe6ee63ffc1e2bab7a54d9137a1e09395a","unresolved":false,"context_lines":[{"line_number":93,"context_line":"            if value:"},{"line_number":94,"context_line":"                if not msg:"},{"line_number":95,"context_line":"                    msg \u003d \u0027Deleted\u0027"},{"line_number":96,"context_line":"                if not value \u003d\u003d 1:"},{"line_number":97,"context_line":"                    resource \u003d self._pluralize(resource)"},{"line_number":98,"context_line":"                deleted_msg.append(\" %d %s\" % (value, resource))"},{"line_number":99,"context_line":"        if deleted_msg:"}],"source_content_type":"text/x-python","patch_set":14,"id":"9aed3d3a_63cb55a6","line":96,"updated":"2016-02-26 16:42:10.000000000","message":"Nit: You could roll the conditional up into the method and have it either return the resource or the resource with an \u0027s\u0027 appended.","commit_id":"b376cedf5a9fbd5c9864ac2beee0a9e81e4238d7"}],"neutronclient/tests/functional/core/test_purge.py":[{"author":{"_account_id":17776,"name":"Reedip","email":"reedip.banerjee@gmail.com","username":"Reedip"},"change_message_id":"5ec2d03dacfb22438fae66f39050fc6d2061cec0","unresolved":false,"context_lines":[{"line_number":40,"context_line":"    def _create_non_purge_resources(self, tenant_id):"},{"line_number":41,"context_line":"        self.neutron(\u0027net-create\u0027,"},{"line_number":42,"context_line":"                     params\u003d(\u0027no-purge --router:external True \u0027"},{"line_number":43,"context_line":"                             \u0027--tenant-id %s\u0027 % tenant_id))"},{"line_number":44,"context_line":"        self.addCleanup(self.neutron, \u0027net-delete no-purge\u0027)"},{"line_number":45,"context_line":"        self.neutron(\u0027subnet-create\u0027,"},{"line_number":46,"context_line":"                     params\u003d(\u0027no-purge --name no-purge --gateway 192.168.77.1 \u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"dae33548_35037a75","line":43,"updated":"2016-02-15 03:58:11.000000000","message":"How about a test case with one of the networks as \"Shared\"","commit_id":"4bf11a5e9e425b3d03c7396ed2ffbf8175aa6fe2"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"8e6b3ac5f9c4df44dcb9c0571d220273134c282f","unresolved":false,"context_lines":[{"line_number":40,"context_line":"    def _create_non_purge_resources(self, tenant_id):"},{"line_number":41,"context_line":"        self.neutron(\u0027net-create\u0027,"},{"line_number":42,"context_line":"                     params\u003d(\u0027no-purge --router:external True \u0027"},{"line_number":43,"context_line":"                             \u0027--tenant-id %s\u0027 % tenant_id))"},{"line_number":44,"context_line":"        self.addCleanup(self.neutron, \u0027net-delete no-purge\u0027)"},{"line_number":45,"context_line":"        self.neutron(\u0027subnet-create\u0027,"},{"line_number":46,"context_line":"                     params\u003d(\u0027no-purge --name no-purge --gateway 192.168.77.1 \u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"dae33548_3f4cd5c6","line":43,"in_reply_to":"dae33548_35037a75","updated":"2016-02-15 21:41:17.000000000","message":"Done","commit_id":"4bf11a5e9e425b3d03c7396ed2ffbf8175aa6fe2"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"919a0553f62fc61b650935830a40e5ed3e78625b","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"        if not purged:"},{"line_number":87,"context_line":"            if resource_type \u003d\u003d \u0027network\u0027:"},{"line_number":88,"context_line":"                self.addCleanup(self.neutron, \u0027net-delete purge-me\u0027)"},{"line_number":89,"context_line":"            elif resource_type \u003d\u003d \u0027subnet\u0027:"},{"line_number":90,"context_line":"                self.addCleanup(self.neutron, \u0027subnet-delete purge-me\u0027)"},{"line_number":91,"context_line":"            elif resource_type \u003d\u003d \u0027router\u0027:"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_202aad7e","line":88,"updated":"2016-02-16 23:32:12.000000000","message":"What if you move these addCleanups to the body of _create_purge_resources? I suggest to use a wrapper around the delete functions (Something like \u0027safeCleanup\u0027) that catches NotFound exceptions, so that if the purge command was successful, the cleanup won\u0027t fail.\n\nIf you do this, you can also collapse _create_purge_resources and _create_non_purge_resources, the only different would be the naming of the resources created.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"3e524f58639abd365b433f78677ccfc481153007","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"        if not purged:"},{"line_number":87,"context_line":"            if resource_type \u003d\u003d \u0027network\u0027:"},{"line_number":88,"context_line":"                self.addCleanup(self.neutron, \u0027net-delete purge-me\u0027)"},{"line_number":89,"context_line":"            elif resource_type \u003d\u003d \u0027subnet\u0027:"},{"line_number":90,"context_line":"                self.addCleanup(self.neutron, \u0027subnet-delete purge-me\u0027)"},{"line_number":91,"context_line":"            elif resource_type \u003d\u003d \u0027router\u0027:"}],"source_content_type":"text/x-python","patch_set":5,"id":"dae33548_b2f05768","line":88,"in_reply_to":"dae33548_202aad7e","updated":"2016-02-19 01:48:19.000000000","message":"Thanks for the suggestion. Done.","commit_id":"26d1b6ae341945665ee870c43be80d2d989ef16b"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"3d88436fc58330fb206013888cc4b6466d050104","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2016 Cisco Systems"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":4,"context_line":"# not use this file except in compliance with the License. You may obtain"},{"line_number":5,"context_line":"# a copy of the License at"}],"source_content_type":"text/x-python","patch_set":13,"id":"9aed3d3a_d317d452","line":2,"updated":"2016-02-25 18:04:53.000000000","message":"I think the convention has been not to include company copyright into OS files now, but if you leave it, you want the \"All Rights Reserved\"","commit_id":"a1aa01f3dd4a2ac7e788797369154b216bae32cf"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"cba9530cb1f28bc8475c43423f93c042062516e0","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2016 Cisco Systems"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":4,"context_line":"# not use this file except in compliance with the License. You may obtain"},{"line_number":5,"context_line":"# a copy of the License at"}],"source_content_type":"text/x-python","patch_set":13,"id":"9aed3d3a_8beeb0ea","line":2,"in_reply_to":"9aed3d3a_d317d452","updated":"2016-02-25 19:19:57.000000000","message":"Done","commit_id":"a1aa01f3dd4a2ac7e788797369154b216bae32cf"}],"neutronclient/tests/unit/test_cli20_purge.py":[{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"3d88436fc58330fb206013888cc4b6466d050104","unresolved":false,"context_lines":[{"line_number":42,"context_line":"                if value !\u003d 1:"},{"line_number":43,"context_line":"                    suffix.append(\u0027s\u0027)"},{"line_number":44,"context_line":"                suffix \u003d \u0027\u0027.join(suffix)"},{"line_number":45,"context_line":"                self.assertTrue(suffix in message)"},{"line_number":46,"context_line":"            else:"},{"line_number":47,"context_line":"                self.assertFalse(resource in message)"},{"line_number":48,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"9aed3d3a_6e5fff0e","line":45,"range":{"start_line":45,"start_character":21,"end_line":45,"end_character":31},"updated":"2016-02-25 18:04:53.000000000","message":"assertIn() here and other places","commit_id":"a1aa01f3dd4a2ac7e788797369154b216bae32cf"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"cba9530cb1f28bc8475c43423f93c042062516e0","unresolved":false,"context_lines":[{"line_number":42,"context_line":"                if value !\u003d 1:"},{"line_number":43,"context_line":"                    suffix.append(\u0027s\u0027)"},{"line_number":44,"context_line":"                suffix \u003d \u0027\u0027.join(suffix)"},{"line_number":45,"context_line":"                self.assertTrue(suffix in message)"},{"line_number":46,"context_line":"            else:"},{"line_number":47,"context_line":"                self.assertFalse(resource in message)"},{"line_number":48,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"9aed3d3a_abc45440","line":45,"range":{"start_line":45,"start_character":21,"end_line":45,"end_character":31},"in_reply_to":"9aed3d3a_6e5fff0e","updated":"2016-02-25 19:19:57.000000000","message":"Done","commit_id":"a1aa01f3dd4a2ac7e788797369154b216bae32cf"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"3d88436fc58330fb206013888cc4b6466d050104","unresolved":false,"context_lines":[{"line_number":44,"context_line":"                suffix \u003d \u0027\u0027.join(suffix)"},{"line_number":45,"context_line":"                self.assertTrue(suffix in message)"},{"line_number":46,"context_line":"            else:"},{"line_number":47,"context_line":"                self.assertFalse(resource in message)"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def _verify_message(self, message, deleted, failed):"},{"line_number":50,"context_line":"        message \u003d message.split(\u0027.\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9aed3d3a_0e6e33c9","line":47,"range":{"start_line":47,"start_character":21,"end_line":47,"end_character":32},"updated":"2016-02-25 18:04:53.000000000","message":"assertNotIn() here and other places","commit_id":"a1aa01f3dd4a2ac7e788797369154b216bae32cf"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"cba9530cb1f28bc8475c43423f93c042062516e0","unresolved":false,"context_lines":[{"line_number":44,"context_line":"                suffix \u003d \u0027\u0027.join(suffix)"},{"line_number":45,"context_line":"                self.assertTrue(suffix in message)"},{"line_number":46,"context_line":"            else:"},{"line_number":47,"context_line":"                self.assertFalse(resource in message)"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def _verify_message(self, message, deleted, failed):"},{"line_number":50,"context_line":"        message \u003d message.split(\u0027.\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9aed3d3a_8bc19031","line":47,"range":{"start_line":47,"start_character":21,"end_line":47,"end_character":32},"in_reply_to":"9aed3d3a_0e6e33c9","updated":"2016-02-25 19:19:57.000000000","message":"Done","commit_id":"a1aa01f3dd4a2ac7e788797369154b216bae32cf"}],"releasenotes/notes/add-neutron-purge-a89e3d1179dce4b1.yaml":[{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"2330e4949ee9c4b323122d335d8992c583797fc9","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    New command \u0027neutron purge \u003ctenant_id\u003e\u0027 will delete all"},{"line_number":5,"context_line":"    supported resources owned by the given tenant, provided"},{"line_number":6,"context_line":"    that the user has sufficient authorization and the"},{"line_number":7,"context_line":"    resources in question are not shared, in use, or"},{"line_number":8,"context_line":"    otherwise undeletable."},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"    Supported resources are:"}],"source_content_type":"text/x-yaml","patch_set":15,"id":"9aed3d3a_1b8eb3cf","line":7,"updated":"2016-03-01 23:08:01.000000000","message":"You actually do attempt to delete shared resources. The note as it is implies otherwise, don\u0027t you think?","commit_id":"88fbd3870cf3872fb0c9b4269503c62458664b3b"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"5170318e172682b0dba3c3e671a968fef41bcaec","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    New command \u0027neutron purge \u003ctenant_id\u003e\u0027 will delete all"},{"line_number":5,"context_line":"    supported resources owned by the given tenant, provided"},{"line_number":6,"context_line":"    that the user has sufficient authorization and the"},{"line_number":7,"context_line":"    resources in question are not shared, in use, or"},{"line_number":8,"context_line":"    otherwise undeletable."},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"    Supported resources are:"}],"source_content_type":"text/x-yaml","patch_set":15,"id":"7af24918_4ebe11d5","line":7,"in_reply_to":"7af24918_796319dd","updated":"2016-03-02 17:45:32.000000000","message":"Feel free to follow up and further elaborate what you mean. The merge should be super quick after my skip-if clause [1] \n\n[1] https://review.openstack.org/#/c/286982/","commit_id":"88fbd3870cf3872fb0c9b4269503c62458664b3b"},{"author":{"_account_id":6635,"name":"John Davidge","email":"john.davidge@rackspace.com","username":"john-davidge"},"change_message_id":"1ed6fe655a635ec2a1c6b8294c826c95a6705586","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    New command \u0027neutron purge \u003ctenant_id\u003e\u0027 will delete all"},{"line_number":5,"context_line":"    supported resources owned by the given tenant, provided"},{"line_number":6,"context_line":"    that the user has sufficient authorization and the"},{"line_number":7,"context_line":"    resources in question are not shared, in use, or"},{"line_number":8,"context_line":"    otherwise undeletable."},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"    Supported resources are:"}],"source_content_type":"text/x-yaml","patch_set":15,"id":"7af24918_796319dd","line":7,"in_reply_to":"9aed3d3a_1b8eb3cf","updated":"2016-03-01 23:17:29.000000000","message":"What I\u0027m trying to say here is that if a resource is shared and has dependent resources owned by another tenant then it wont be deleted. That\u0027s probably technically covered by \u0027in use\u0027, but I wanted to be specific. We attempt to delete \u0027in use\u0027 resources as well, but they don\u0027t actually get deleted.","commit_id":"88fbd3870cf3872fb0c9b4269503c62458664b3b"}]}
