)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"6b14175727a635af96c0d168137e26fdffed1967","unresolved":false,"context_lines":[{"line_number":20,"context_line":"DocImpact"},{"line_number":21,"context_line":"APIImpact"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"Closes-bug: #1512587"},{"line_number":24,"context_line":"Change-Id: I1c59073daa181005a3e878bc2fe033a0709fbf31"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"9a8ffd7b_d19453e3","line":23,"updated":"2015-11-26 01:53:56.000000000","message":"Until the RFE is approved, if you feel the urge to continue working on this one, please consider replacing Closes-bug with Related-bug.\n\nMost likely this will need a spec and bp, and if you continue respinning the patchset with the Closes-bug tag, it will trigger a bug state change all the time.","commit_id":"ebd846ad6930ef7ee98e9fa7d61d8a5081b27c09"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"07684bf723b68d68ea3704e10a64f420a65ec650","unresolved":false,"context_lines":[{"line_number":20,"context_line":"DocImpact"},{"line_number":21,"context_line":"APIImpact"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"Closes-bug: #1512587"},{"line_number":24,"context_line":"Change-Id: I1c59073daa181005a3e878bc2fe033a0709fbf31"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"9a8ffd7b_03acc39e","line":23,"in_reply_to":"9a8ffd7b_d19453e3","updated":"2015-11-26 09:39:50.000000000","message":"Done","commit_id":"ebd846ad6930ef7ee98e9fa7d61d8a5081b27c09"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"e997782aaf49c1c408e5e40394e068c40b6076c2","unresolved":false,"context_lines":[{"line_number":17,"context_line":"drivers, services) must not check for the \u0027shared\u0027 attribute on qos-policy db"},{"line_number":18,"context_line":"objects any more."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"This patchset manages to unbreak the existing API and all related tests."},{"line_number":21,"context_line":"The new resource based access tests patch is on his way."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"DocImpact"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"9a8ffd7b_03a5a302","line":20,"updated":"2015-12-02 11:02:38.000000000","message":"How is it unbreaking a thing? Which specific issue do you mean? I don\u0027t see it mentioned in the commit message.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"6ac3dce0b6e6c31f95c62f5a0495dc40c35d3ed6","unresolved":false,"context_lines":[{"line_number":17,"context_line":"drivers, services) must not check for the \u0027shared\u0027 attribute on qos-policy db"},{"line_number":18,"context_line":"objects any more."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"This patchset manages to unbreak the existing API and all related tests."},{"line_number":21,"context_line":"The new resource based access tests patch is on his way."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"DocImpact"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"9a8ffd7b_bf006703","line":20,"in_reply_to":"9a8ffd7b_03a5a302","updated":"2015-12-02 11:33:45.000000000","message":"Do you mean maintaining compatibility with the previous API?","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"756036fff71797af367e36a24fd3ccaad7c89455","unresolved":false,"context_lines":[{"line_number":17,"context_line":"drivers, services) must not check for the \u0027shared\u0027 attribute on qos-policy db"},{"line_number":18,"context_line":"objects any more."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"This patchset manages to unbreak the existing API and all related tests."},{"line_number":21,"context_line":"The new resource based access tests patch is on his way."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"DocImpact"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"9a8ffd7b_a3c37756","line":20,"in_reply_to":"9a8ffd7b_03a5a302","updated":"2015-12-02 12:22:59.000000000","message":"I meant it keeps the unit tests sane. and avoids breaking them. This isn\u0027t the case for system (tempest) tests.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"7648de4f3f7b67eb7ce97d6634320c0d247fe36d","unresolved":false,"context_lines":[{"line_number":17,"context_line":"drivers, services) must not check for the \u0027shared\u0027 attribute on qos-policy db"},{"line_number":18,"context_line":"objects any more."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"This patchset manages to unbreak the existing API and all related tests."},{"line_number":21,"context_line":"The new resource based access tests patch is on his way."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"DocImpact"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"9a8ffd7b_a29050ee","line":20,"in_reply_to":"9a8ffd7b_bf006703","updated":"2015-12-02 11:53:02.000000000","message":"I don\u0027t know. That\u0027s the goal of commit message to make it clear what we try to achieve. I don\u0027t see any issue mentioned before, and then I read \u0027to unbreak\u0027. Looks like some context is missing?","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"d957af8792db876becf419afd4eb8498dc2fc767","unresolved":false,"context_lines":[{"line_number":20,"context_line":"This patchset manages to unbreak the existing API and all related tests."},{"line_number":21,"context_line":"The new resource based access tests patch is on his way."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"DocImpact"},{"line_number":24,"context_line":"APIImpact"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"Related-bug: #1512587"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"7a740942_c8863ab9","line":23,"updated":"2015-12-04 01:15:34.000000000","message":"Please follow guidelines as detailed here:\n\nhttp://lists.openstack.org/pipermail/openstack-dev/2015-November/080294.html\n\n\"you will need to add a description whenever you add a DocImpact flag in your commit message.\"","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"74c7ccb25ccfc4fab0ce0f926081c285cc26aca7","unresolved":false,"context_lines":[{"line_number":21,"context_line":"The new resource based access tests patch is on his way."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"DocImpact"},{"line_number":24,"context_line":"APIImpact"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"Related-bug: #1512587"},{"line_number":27,"context_line":"Change-Id: I1c59073daa181005a3e878bc2fe033a0709fbf31"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"9a8ffd7b_08caa0a1","line":24,"updated":"2015-12-02 10:47:24.000000000","message":"ok, we need a spec, we will have to link the blueprint from here, as I understood from [1] : \"If a spec is necessary, a member of the Neutron release team will register a matching Launchpad blueprint to be used for milestone tracking purpose\"\n\n\n[1] http://docs.openstack.org/developer/neutron/policies/blueprints.html","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Qos policy RBAC DB setup and migration"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch implements a new database model required for the"},{"line_number":10,"context_line":"qos-policy RBAC support. In addition it migrates the current qos-policy \u0027shared\u0027"},{"line_number":11,"context_line":"attribute to leverage the new \u0027qospolicyrbacs\u0027 table."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"\u0027shared\u0027 is no longer a property of the QosPolicy DB model. Its status is based"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"3a7e1126_cd6882bd","line":10,"range":{"start_line":10,"start_character":65,"end_line":10,"end_character":71},"updated":"2015-12-17 13:17:04.000000000","message":"I hate to be super-nitty, but lines in the commit message should not be longer than 72 chars per line, as can be observed from the dotted red line and in [1]\n\n[1]: https://wiki.openstack.org/wiki/GitCommitMessages (look for \"Summary of Git commit message structure\").","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"30599cd74aa21f58b1c83a0b115dfe06302ef5c4","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Qos policy RBAC DB setup and migration"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch implements a new database model required for the"},{"line_number":10,"context_line":"qos-policy RBAC support. In addition it migrates the current qos-policy \u0027shared\u0027"},{"line_number":11,"context_line":"attribute to leverage the new \u0027qospolicyrbacs\u0027 table."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"\u0027shared\u0027 is no longer a property of the QosPolicy DB model. Its status is based"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"3a7e1126_733a7938","line":10,"range":{"start_line":10,"start_character":65,"end_line":10,"end_character":71},"in_reply_to":"3a7e1126_cd6882bd","updated":"2015-12-17 15:59:47.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"46700008826cc88fbbfef7ce857bbc8c84e8948d","unresolved":false,"context_lines":[{"line_number":16,"context_line":"shared with them. However, internal callers (e.g. plugins, drivers, services)"},{"line_number":17,"context_line":"must not check for the \u0027shared\u0027 attribute on qos-policy db objects any more."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"DocImpact"},{"line_number":20,"context_line":"APIImpact"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"Related-bug: #1512587"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"3a7e1126_afddf871","line":19,"updated":"2015-12-17 07:24:02.000000000","message":"please add the release notes to the patch","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":14605,"name":"vikram.choudhary","email":"vikschw@gmail.com","username":"vikram.choudhary"},"change_message_id":"43714b0d09ef14173bb7ee9ae4cdebd83322e4cd","unresolved":false,"context_lines":[{"line_number":16,"context_line":"shared with them. However, internal callers (e.g. plugins, drivers, services)"},{"line_number":17,"context_line":"must not check for the \u0027shared\u0027 attribute on qos-policy db objects any more."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"DocImpact"},{"line_number":20,"context_line":"APIImpact"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"Related-bug: #1512587"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"3a7e1126_f3968693","line":19,"in_reply_to":"3a7e1126_afddf871","updated":"2015-12-17 08:10:00.000000000","message":"+1","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"30599cd74aa21f58b1c83a0b115dfe06302ef5c4","unresolved":false,"context_lines":[{"line_number":16,"context_line":"shared with them. However, internal callers (e.g. plugins, drivers, services)"},{"line_number":17,"context_line":"must not check for the \u0027shared\u0027 attribute on qos-policy db objects any more."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"DocImpact"},{"line_number":20,"context_line":"APIImpact"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"Related-bug: #1512587"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"3a7e1126_13cf7580","line":19,"in_reply_to":"3a7e1126_afddf871","updated":"2015-12-17 15:59:47.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"de7f57fa57f8939b2885af4abcd9809f5d0e0c9a","unresolved":false,"context_lines":[{"line_number":16,"context_line":"shared with them. However, internal callers (e.g. plugins, drivers, services)"},{"line_number":17,"context_line":"must not check for the \u0027shared\u0027 attribute on qos-policy db objects any more."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"DocImpact"},{"line_number":20,"context_line":"APIImpact"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"Related-bug: #1512587"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"3a7e1126_ffc40793","line":19,"in_reply_to":"3a7e1126_f3968693","updated":"2016-01-11 08:58:11.000000000","message":"Good point, \n\nAn example here: https://review.openstack.org/#/c/246923/12/releasenotes/notes/direct-physical-vnic-878d15bdb758b70e.yaml","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":14605,"name":"vikram.choudhary","email":"vikschw@gmail.com","username":"vikram.choudhary"},"change_message_id":"4660bd4fd7d7879b8e540450bd7b412ede65101d","unresolved":false,"context_lines":[{"line_number":17,"context_line":"(e.g. plugins, drivers, services) must not check for the \u0027shared\u0027"},{"line_number":18,"context_line":"attribute on qos-policy db objects any more."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"DocImpact"},{"line_number":21,"context_line":"APIImpact"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"Blueprint: rbac-qos"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":13,"id":"5a5ae5dd_5d8c087f","line":20,"updated":"2016-02-04 12:05:26.000000000","message":"Please write a word about the change. We need to add a description for the DocImpact flag. Guideline can be found @:\nhttp://lists.openstack.org/pipermail/openstack-dev/2015-November/080294.html","commit_id":"c6166ed15b80654010a4c23dea104690d30c8459"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"bda6c10036944ebfd08a1ab4968fd20a805b9026","unresolved":false,"context_lines":[{"line_number":16,"context_line":"in case the qos-policy is shared with them). However, internal callers"},{"line_number":17,"context_line":"(e.g. plugins, drivers, services) must not check for the \u0027shared\u0027"},{"line_number":18,"context_line":"attribute on qos-policy db objects any more."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"DocImpact"},{"line_number":21,"context_line":"APIImpact"},{"line_number":22,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":19,"id":"dae33548_5df64a8f","line":19,"updated":"2016-02-18 16:17:21.000000000","message":"It\u0027s also worth mentioning that this patch adds previously-missing unit tests for NeutronDbObject.","commit_id":"b6ed80c05295c90d28a470a1efdff9812e4841d1"}],"neutron/db/migration/alembic_migrations/versions/mitaka/contract/c6c112992c9_rbac_qos_policy.py":[{"author":{"_account_id":14605,"name":"vikram.choudhary","email":"vikschw@gmail.com","username":"vikram.choudhary"},"change_message_id":"8502a436be14d45ce8e5e5056ce8bde4ad81973e","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"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"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a7e1126_cff0fdff","line":1,"updated":"2015-12-19 11:36:12.000000000","message":"Plz update company details.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"74c7ccb25ccfc4fab0ce0f926081c285cc26aca7","unresolved":false,"context_lines":[{"line_number":47,"context_line":""},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"def upgrade():"},{"line_number":50,"context_line":"    op.bulk_insert(qos_rbacs, get_values())"},{"line_number":51,"context_line":"    op.drop_column(\u0027qos_policies\u0027, \u0027shared\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_edcc0e63","line":50,"updated":"2015-12-02 10:47:24.000000000","message":"shouldn\u0027t the bulk insert happen in expand so that data is available to the new servers? (I certainly could be wrong here), pinging @ihar for this question.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"6ac3dce0b6e6c31f95c62f5a0495dc40c35d3ed6","unresolved":false,"context_lines":[{"line_number":47,"context_line":""},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"def upgrade():"},{"line_number":50,"context_line":"    op.bulk_insert(qos_rbacs, get_values())"},{"line_number":51,"context_line":"    op.drop_column(\u0027qos_policies\u0027, \u0027shared\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_9ff9e350","line":50,"in_reply_to":"9a8ffd7b_482bc8eb","updated":"2015-12-02 11:33:45.000000000","message":"Hmm, and how do new servers function while this haven\u0027t happened?. (f.e. on this specific case, permissions will not work because they don\u0027t check the shared column anymore).","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"066f53fd0092f41b5e59db0be90fd7ff243b1286","unresolved":false,"context_lines":[{"line_number":47,"context_line":""},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"def upgrade():"},{"line_number":50,"context_line":"    op.bulk_insert(qos_rbacs, get_values())"},{"line_number":51,"context_line":"    op.drop_column(\u0027qos_policies\u0027, \u0027shared\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_a21db0bf","line":50,"in_reply_to":"9a8ffd7b_8849b0d2","updated":"2015-12-02 11:48:16.000000000","message":"Thank you for the bit of education here, I understood the process now.\n\nSo we expand (while old server code is still running), stop servers, contract, start (with new code in place).\n\nThat makes sense.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"99090b476f640e238f4541c7761861b0ed4ddf4b","unresolved":false,"context_lines":[{"line_number":47,"context_line":""},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"def upgrade():"},{"line_number":50,"context_line":"    op.bulk_insert(qos_rbacs, get_values())"},{"line_number":51,"context_line":"    op.drop_column(\u0027qos_policies\u0027, \u0027shared\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_62890826","line":50,"in_reply_to":"9a8ffd7b_9ff9e350","updated":"2015-12-02 11:43:59.000000000","message":"Quoting http://docs.openstack.org/developer/neutron/devref/upgrade.html#server-upgrade\n\n\"The former step can be executed while old neutron-server code is running. The latter step requires all neutron-server instances to be shut down. Once it’s complete, neutron-servers can be started again.\"\n\nMeaning, we don\u0027t currently support multiple versions of neutron-server running in a cloud. All servers must have the same version.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"7648de4f3f7b67eb7ce97d6634320c0d247fe36d","unresolved":false,"context_lines":[{"line_number":47,"context_line":""},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"def upgrade():"},{"line_number":50,"context_line":"    op.bulk_insert(qos_rbacs, get_values())"},{"line_number":51,"context_line":"    op.drop_column(\u0027qos_policies\u0027, \u0027shared\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_82698cfb","line":50,"in_reply_to":"9a8ffd7b_a21db0bf","updated":"2015-12-02 11:53:02.000000000","message":"It does NOT make sense for a cloud. But that\u0027s what we have so far. :)","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"f56b6dd491d9f489fa946b491661d104f80acb16","unresolved":false,"context_lines":[{"line_number":47,"context_line":""},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"def upgrade():"},{"line_number":50,"context_line":"    op.bulk_insert(qos_rbacs, get_values())"},{"line_number":51,"context_line":"    op.drop_column(\u0027qos_policies\u0027, \u0027shared\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_8849b0d2","line":50,"in_reply_to":"9a8ffd7b_edcc0e63","updated":"2015-12-02 11:46:29.000000000","message":"No, at this moment all operations with data can be done only in contract.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"e997782aaf49c1c408e5e40394e068c40b6076c2","unresolved":false,"context_lines":[{"line_number":47,"context_line":""},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"def upgrade():"},{"line_number":50,"context_line":"    op.bulk_insert(qos_rbacs, get_values())"},{"line_number":51,"context_line":"    op.drop_column(\u0027qos_policies\u0027, \u0027shared\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_482bc8eb","line":50,"in_reply_to":"9a8ffd7b_edcc0e63","updated":"2015-12-02 11:02:38.000000000","message":"it belongs to contract because otherwise servers that are still running old code after expand rules are applied can create new policies, that would not result in creating new rbac models for them; so once you restart servers, they will lack those models.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"94ad0796728171af23a3cd07757f814804865658","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"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"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa69d971_cce671af","line":1,"updated":"2016-01-07 01:39:53.000000000","message":"No, we\u0027ve been moving away from that. For new files don\u0027t add in extra company information in the header.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":14605,"name":"vikram.choudhary","email":"vikschw@gmail.com","username":"vikram.choudhary"},"change_message_id":"fe321e941b8c577adbe1105d3df203ae02a2f564","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"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"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_cf79dd83","line":1,"updated":"2015-12-19 11:37:00.000000000","message":"Plz add your company detaills.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"db20907040224f878c70fbf9aa693816d50edd7e","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"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"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_c0a1a747","line":1,"in_reply_to":"3a7e1126_cf79dd83","updated":"2015-12-20 07:29:11.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"bda6c10036944ebfd08a1ab4968fd20a805b9026","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"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"}],"source_content_type":"text/x-python","patch_set":19,"id":"dae33548_ddbffacd","line":1,"range":{"start_line":1,"start_character":0,"end_line":1,"end_character":37},"updated":"2016-02-18 16:17:21.000000000","message":"# Copyright 2016 Red Hat, Inc.","commit_id":"b6ed80c05295c90d28a470a1efdff9812e4841d1"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"a51056aa217fb67b6cf21cd7e1de19b6d7886136","unresolved":false,"context_lines":[{"line_number":39,"context_line":"              nullable\u003dTrue),"},{"line_number":40,"context_line":"    sa.Column(\u0027target_tenant\u0027, sa.String(length\u003dattrs.TENANT_ID_MAX_LEN),"},{"line_number":41,"context_line":"              nullable\u003dFalse),"},{"line_number":42,"context_line":"    sa.Column(\u0027action\u0027, sa.String(length\u003dattrs.TENANT_ID_MAX_LEN),"},{"line_number":43,"context_line":"              nullable\u003dFalse),"},{"line_number":44,"context_line":"    sa.Column(\u0027object_id\u0027, sa.String(length\u003d36), nullable\u003dFalse))"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_86afbce2","line":42,"range":{"start_line":42,"start_character":41,"end_line":42,"end_character":64},"updated":"2016-02-19 14:29:26.000000000","message":"Seems like this is misleading, unless action is a tenant ID. :)\n\nIs the target_tenant a tenant ID?","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"57b0d348fb5c654912c0fe78279702c327042ec7","unresolved":false,"context_lines":[{"line_number":39,"context_line":"              nullable\u003dTrue),"},{"line_number":40,"context_line":"    sa.Column(\u0027target_tenant\u0027, sa.String(length\u003dattrs.TENANT_ID_MAX_LEN),"},{"line_number":41,"context_line":"              nullable\u003dFalse),"},{"line_number":42,"context_line":"    sa.Column(\u0027action\u0027, sa.String(length\u003dattrs.TENANT_ID_MAX_LEN),"},{"line_number":43,"context_line":"              nullable\u003dFalse),"},{"line_number":44,"context_line":"    sa.Column(\u0027object_id\u0027, sa.String(length\u003d36), nullable\u003dFalse))"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_3c2cfc49","line":42,"range":{"start_line":42,"start_character":41,"end_line":42,"end_character":64},"in_reply_to":"bae84128_86afbce2","updated":"2016-02-19 16:14:34.000000000","message":"nope - will fix.","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"593b66178030b97f5f45d0daf68b36ec515cc684","unresolved":false,"context_lines":[{"line_number":33,"context_line":"depends_on \u003d (\u002715e43b934f81\u0027,)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"qos_rbacs \u003d sa.Table("},{"line_number":36,"context_line":"    \u0027qospolicyrbacs\u0027, sa.MetaData(),"},{"line_number":37,"context_line":"    sa.Column(\u0027id\u0027, sa.String(length\u003d36), nullable\u003dFalse),"},{"line_number":38,"context_line":"    sa.Column(\u0027tenant_id\u0027, sa.String(length\u003dattrs.TENANT_ID_MAX_LEN),"},{"line_number":39,"context_line":"              nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_f3944fe3","line":36,"updated":"2016-02-21 10:28:59.000000000","message":"why not qospolicyrbac?","commit_id":"2aab0cd1cda881dbdadeb6e923f373675f889489"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"14b8a9553977b4ba56a43f5dfb276912b8fa97c7","unresolved":false,"context_lines":[{"line_number":33,"context_line":"depends_on \u003d (\u002715e43b934f81\u0027,)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"qos_rbacs \u003d sa.Table("},{"line_number":36,"context_line":"    \u0027qospolicyrbacs\u0027, sa.MetaData(),"},{"line_number":37,"context_line":"    sa.Column(\u0027id\u0027, sa.String(length\u003d36), nullable\u003dFalse),"},{"line_number":38,"context_line":"    sa.Column(\u0027tenant_id\u0027, sa.String(length\u003dattrs.TENANT_ID_MAX_LEN),"},{"line_number":39,"context_line":"              nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_f330cf03","line":36,"in_reply_to":"bae84128_f3944fe3","updated":"2016-02-21 11:06:33.000000000","message":"1. Because network rbac table\u0027s name is networkrbacs\n2. Because there might be more than one rbac policy in the table.\n3. Because only 9 of neutron tables\u0027 names arent in plural form.","commit_id":"2aab0cd1cda881dbdadeb6e923f373675f889489"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    for row in session.query(qos_policy).filter(qos_policy.c.shared).all():"},{"line_number":63,"context_line":"        values.append({\u0027id\u0027: uuidutils.generate_uuid(), \u0027object_id\u0027: row[0],"},{"line_number":64,"context_line":"                       \u0027tenant_id\u0027: row[1], \u0027target_tenant\u0027: \u0027*\u0027,"},{"line_number":65,"context_line":"                       \u0027action\u0027: \u0027access_as_shared\u0027})"},{"line_number":66,"context_line":"    session.commit()"},{"line_number":67,"context_line":"    return values"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_83af997c","line":65,"range":{"start_line":65,"start_character":33,"end_line":65,"end_character":51},"updated":"2016-02-25 11:00:39.000000000","message":"nit: could use constant here","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    for row in session.query(qos_policy).filter(qos_policy.c.shared).all():"},{"line_number":63,"context_line":"        values.append({\u0027id\u0027: uuidutils.generate_uuid(), \u0027object_id\u0027: row[0],"},{"line_number":64,"context_line":"                       \u0027tenant_id\u0027: row[1], \u0027target_tenant\u0027: \u0027*\u0027,"},{"line_number":65,"context_line":"                       \u0027action\u0027: \u0027access_as_shared\u0027})"},{"line_number":66,"context_line":"    session.commit()"},{"line_number":67,"context_line":"    return values"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_2da5d6b4","line":65,"range":{"start_line":65,"start_character":33,"end_line":65,"end_character":51},"in_reply_to":"bae84128_83af997c","updated":"2016-02-25 17:24:55.000000000","message":"Done","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"}],"neutron/db/migration/alembic_migrations/versions/mitaka/expand/15e43b934f81_rbac_qos_policy.py":[{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"a3b4b8defef49a7a829b85537fdbd88d76294462","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                                 )"},{"line_number":62,"context_line":"    op.create_index(op.f(\u0027ix_qospolicyrbacs_tenant_id\u0027), \u0027qospolicyrbacs\u0027,"},{"line_number":63,"context_line":"                    [\u0027tenant_id\u0027], unique\u003dFalse)"},{"line_number":64,"context_line":"    op.bulk_insert(rbac_table, get_values())"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"def get_values():"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a8ffd7b_e8f5dcca","line":64,"updated":"2015-11-26 09:13:51.000000000","message":"Inserting data is related to contract branch.","commit_id":"ebd846ad6930ef7ee98e9fa7d61d8a5081b27c09"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"d1a32f9194ad2d333ac82c9ae2c59aaee5953983","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                                 )"},{"line_number":62,"context_line":"    op.create_index(op.f(\u0027ix_qospolicyrbacs_tenant_id\u0027), \u0027qospolicyrbacs\u0027,"},{"line_number":63,"context_line":"                    [\u0027tenant_id\u0027], unique\u003dFalse)"},{"line_number":64,"context_line":"    op.bulk_insert(rbac_table, get_values())"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"def get_values():"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a8ffd7b_6ee18129","line":64,"in_reply_to":"9a8ffd7b_4875952f","updated":"2015-11-30 09:17:07.000000000","message":"@ajo: http://docs.openstack.org/developer/neutron/devref/alembic_migrations.html#expand-and-contract-scripts.\n\nlook for \"For the time being, data migration rules also belong to contract\"","commit_id":"ebd846ad6930ef7ee98e9fa7d61d8a5081b27c09"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"df21d95f67f27cedeabf13ecbf61fac36fa9ad2f","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                                 )"},{"line_number":62,"context_line":"    op.create_index(op.f(\u0027ix_qospolicyrbacs_tenant_id\u0027), \u0027qospolicyrbacs\u0027,"},{"line_number":63,"context_line":"                    [\u0027tenant_id\u0027], unique\u003dFalse)"},{"line_number":64,"context_line":"    op.bulk_insert(rbac_table, get_values())"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"def get_values():"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a8ffd7b_c178642e","line":64,"in_reply_to":"9a8ffd7b_6ee18129","updated":"2015-11-30 16:56:38.000000000","message":"@Miguel the reason for that is that if we insert those while running, then create more objects that should link to those new tables, then they miss the migration rule, so after restart those new objects won\u0027t have corresponding models inserted.","commit_id":"ebd846ad6930ef7ee98e9fa7d61d8a5081b27c09"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"93d8c78de40dbc7303e34286728861c178a96828","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                                 )"},{"line_number":62,"context_line":"    op.create_index(op.f(\u0027ix_qospolicyrbacs_tenant_id\u0027), \u0027qospolicyrbacs\u0027,"},{"line_number":63,"context_line":"                    [\u0027tenant_id\u0027], unique\u003dFalse)"},{"line_number":64,"context_line":"    op.bulk_insert(rbac_table, get_values())"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"def get_values():"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a8ffd7b_4875952f","line":64,"in_reply_to":"9a8ffd7b_a3ee17b2","updated":"2015-11-30 09:09:22.000000000","message":"@ann, just out of ignorance, why inserts are contract?, do we have any documentation explaining this?.  Thank you.","commit_id":"ebd846ad6930ef7ee98e9fa7d61d8a5081b27c09"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"07684bf723b68d68ea3704e10a64f420a65ec650","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                                 )"},{"line_number":62,"context_line":"    op.create_index(op.f(\u0027ix_qospolicyrbacs_tenant_id\u0027), \u0027qospolicyrbacs\u0027,"},{"line_number":63,"context_line":"                    [\u0027tenant_id\u0027], unique\u003dFalse)"},{"line_number":64,"context_line":"    op.bulk_insert(rbac_table, get_values())"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"def get_values():"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a8ffd7b_a3ee17b2","line":64,"in_reply_to":"9a8ffd7b_e8f5dcca","updated":"2015-11-26 09:39:50.000000000","message":"Done","commit_id":"ebd846ad6930ef7ee98e9fa7d61d8a5081b27c09"},{"author":{"_account_id":14605,"name":"vikram.choudhary","email":"vikschw@gmail.com","username":"vikram.choudhary"},"change_message_id":"8502a436be14d45ce8e5e5056ce8bde4ad81973e","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"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"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a7e1126_4fe5ed35","line":1,"updated":"2015-12-19 11:36:12.000000000","message":"Plz update company details.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"f56b6dd491d9f489fa946b491661d104f80acb16","unresolved":false,"context_lines":[{"line_number":32,"context_line":"def upgrade():"},{"line_number":33,"context_line":"    op.create_table(\u0027qospolicyrbacs\u0027,"},{"line_number":34,"context_line":"                    sa.Column(\u0027id\u0027, sa.String(length\u003d36), nullable\u003dFalse),"},{"line_number":35,"context_line":"                    sa.Column(\u0027tenant_id\u0027, sa.String(length\u003d255),"},{"line_number":36,"context_line":"                              nullable\u003dTrue),"},{"line_number":37,"context_line":"                    sa.Column(\u0027target_tenant\u0027, sa.String(length\u003d255),"},{"line_number":38,"context_line":"                              nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_a81b54c9","line":35,"range":{"start_line":35,"start_character":31,"end_line":35,"end_character":40},"updated":"2015-12-02 11:46:29.000000000","message":"You don\u0027t need to create index separately. Just add index\u003dTrue here.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"49b829c4296c6d81134e25f9b35ac35734edb422","unresolved":false,"context_lines":[{"line_number":32,"context_line":"def upgrade():"},{"line_number":33,"context_line":"    op.create_table(\u0027qospolicyrbacs\u0027,"},{"line_number":34,"context_line":"                    sa.Column(\u0027id\u0027, sa.String(length\u003d36), nullable\u003dFalse),"},{"line_number":35,"context_line":"                    sa.Column(\u0027tenant_id\u0027, sa.String(length\u003d255),"},{"line_number":36,"context_line":"                              nullable\u003dTrue),"},{"line_number":37,"context_line":"                    sa.Column(\u0027target_tenant\u0027, sa.String(length\u003d255),"},{"line_number":38,"context_line":"                              nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a7e1126_1be25204","line":35,"range":{"start_line":35,"start_character":31,"end_line":35,"end_character":41},"updated":"2015-12-17 06:34:36.000000000","message":"You can create index on this column just adding index\u003dTrue.","commit_id":"c9c60ae22c72a15cdf2d948e047fe86a88e279c4"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"a5e821a1bc5c133b350b8dc847a3a45f21ac023e","unresolved":false,"context_lines":[{"line_number":32,"context_line":"def upgrade():"},{"line_number":33,"context_line":"    op.create_table(\u0027qospolicyrbacs\u0027,"},{"line_number":34,"context_line":"                    sa.Column(\u0027id\u0027, sa.String(length\u003d36), nullable\u003dFalse),"},{"line_number":35,"context_line":"                    sa.Column(\u0027tenant_id\u0027, sa.String(length\u003d255),"},{"line_number":36,"context_line":"                              nullable\u003dTrue),"},{"line_number":37,"context_line":"                    sa.Column(\u0027target_tenant\u0027, sa.String(length\u003d255),"},{"line_number":38,"context_line":"                              nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a7e1126_9e5f100e","line":35,"range":{"start_line":35,"start_character":31,"end_line":35,"end_character":41},"in_reply_to":"3a7e1126_1be25204","updated":"2015-12-17 06:43:35.000000000","message":"Do you mean instead of L49 ?","commit_id":"c9c60ae22c72a15cdf2d948e047fe86a88e279c4"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"c59b65465096922ba0756e2405d9ce1dfe478f8f","unresolved":false,"context_lines":[{"line_number":32,"context_line":"def upgrade():"},{"line_number":33,"context_line":"    op.create_table(\u0027qospolicyrbacs\u0027,"},{"line_number":34,"context_line":"                    sa.Column(\u0027id\u0027, sa.String(length\u003d36), nullable\u003dFalse),"},{"line_number":35,"context_line":"                    sa.Column(\u0027tenant_id\u0027, sa.String(length\u003d255),"},{"line_number":36,"context_line":"                              nullable\u003dTrue),"},{"line_number":37,"context_line":"                    sa.Column(\u0027target_tenant\u0027, sa.String(length\u003d255),"},{"line_number":38,"context_line":"                              nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a7e1126_9e52b0dc","line":35,"range":{"start_line":35,"start_character":31,"end_line":35,"end_character":41},"in_reply_to":"3a7e1126_9e5f100e","updated":"2015-12-17 06:44:53.000000000","message":"yes","commit_id":"c9c60ae22c72a15cdf2d948e047fe86a88e279c4"},{"author":{"_account_id":14605,"name":"vikram.choudhary","email":"vikschw@gmail.com","username":"vikram.choudhary"},"change_message_id":"fe321e941b8c577adbe1105d3df203ae02a2f564","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"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"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_ef7e1969","line":1,"updated":"2015-12-19 11:37:00.000000000","message":"Plz add your company detaills.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"db20907040224f878c70fbf9aa693816d50edd7e","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"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"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_608b13c4","line":1,"in_reply_to":"3a7e1126_ef7e1969","updated":"2015-12-20 07:29:11.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"07f8140c3caf9072cc1ae3a86ccbc7d3ade2155b","unresolved":false,"context_lines":[{"line_number":32,"context_line":"def upgrade():"},{"line_number":33,"context_line":"    op.create_table(\u0027qospolicyrbacs\u0027,"},{"line_number":34,"context_line":"                    sa.Column(\u0027id\u0027, sa.String(length\u003d36), nullable\u003dFalse),"},{"line_number":35,"context_line":"                    sa.Column(\u0027tenant_id\u0027, sa.String(length\u003d255),"},{"line_number":36,"context_line":"                              nullable\u003dTrue),"},{"line_number":37,"context_line":"                    sa.Column(\u0027target_tenant\u0027, sa.String(length\u003d255),"},{"line_number":38,"context_line":"                              nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_c03f1fb2","line":35,"range":{"start_line":35,"start_character":60,"end_line":35,"end_character":63},"updated":"2016-02-08 16:16:13.000000000","message":"Can use TENANT_ID_MAX_LEN","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":32,"context_line":"def upgrade():"},{"line_number":33,"context_line":"    op.create_table(\u0027qospolicyrbacs\u0027,"},{"line_number":34,"context_line":"                    sa.Column(\u0027id\u0027, sa.String(length\u003d36), nullable\u003dFalse),"},{"line_number":35,"context_line":"                    sa.Column(\u0027tenant_id\u0027, sa.String(length\u003d255),"},{"line_number":36,"context_line":"                              nullable\u003dTrue),"},{"line_number":37,"context_line":"                    sa.Column(\u0027target_tenant\u0027, sa.String(length\u003d255),"},{"line_number":38,"context_line":"                              nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":14,"id":"3a57f1b5_90ded50f","line":35,"range":{"start_line":35,"start_character":60,"end_line":35,"end_character":63},"in_reply_to":"5a5ae5dd_c03f1fb2","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"f172c53fdf42fa3969e2b1a0b7be0f57fb3dd610","unresolved":false,"context_lines":[{"line_number":32,"context_line":"def upgrade():"},{"line_number":33,"context_line":"    op.create_table(\u0027qospolicyrbacs\u0027,"},{"line_number":34,"context_line":"                    sa.Column(\u0027id\u0027, sa.String(length\u003d36), nullable\u003dFalse),"},{"line_number":35,"context_line":"                    sa.Column(\u0027tenant_id\u0027, sa.String(length\u003d255),"},{"line_number":36,"context_line":"                              nullable\u003dTrue),"},{"line_number":37,"context_line":"                    sa.Column(\u0027target_tenant\u0027, sa.String(length\u003d255),"},{"line_number":38,"context_line":"                              nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_e9b0bb45","line":35,"updated":"2016-02-16 19:39:04.000000000","message":"Comment from PS14","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"bda6c10036944ebfd08a1ab4968fd20a805b9026","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"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"}],"source_content_type":"text/x-python","patch_set":19,"id":"dae33548_7dea2edc","line":1,"range":{"start_line":1,"start_character":0,"end_line":1,"end_character":37},"updated":"2016-02-18 16:17:21.000000000","message":"# Copyright 2016 Red Hat, Inc.","commit_id":"b6ed80c05295c90d28a470a1efdff9812e4841d1"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"a51056aa217fb67b6cf21cd7e1de19b6d7886136","unresolved":false,"context_lines":[{"line_number":40,"context_line":"                    sa.Column(\u0027target_tenant\u0027,"},{"line_number":41,"context_line":"                              sa.String(length\u003dattrs.TENANT_ID_MAX_LEN),"},{"line_number":42,"context_line":"                              nullable\u003dFalse),"},{"line_number":43,"context_line":"                    sa.Column(\u0027action\u0027,"},{"line_number":44,"context_line":"                              sa.String(length\u003dattrs.TENANT_ID_MAX_LEN),"},{"line_number":45,"context_line":"                              nullable\u003dFalse),"},{"line_number":46,"context_line":"                    sa.Column(\u0027object_id\u0027, sa.String(length\u003d36),"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_a6b6403b","line":43,"range":{"start_line":43,"start_character":31,"end_line":43,"end_character":37},"updated":"2016-02-19 14:29:26.000000000","message":"ditto","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"57b0d348fb5c654912c0fe78279702c327042ec7","unresolved":false,"context_lines":[{"line_number":40,"context_line":"                    sa.Column(\u0027target_tenant\u0027,"},{"line_number":41,"context_line":"                              sa.String(length\u003dattrs.TENANT_ID_MAX_LEN),"},{"line_number":42,"context_line":"                              nullable\u003dFalse),"},{"line_number":43,"context_line":"                    sa.Column(\u0027action\u0027,"},{"line_number":44,"context_line":"                              sa.String(length\u003dattrs.TENANT_ID_MAX_LEN),"},{"line_number":45,"context_line":"                              nullable\u003dFalse),"},{"line_number":46,"context_line":"                    sa.Column(\u0027object_id\u0027, sa.String(length\u003d36),"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_1cf3f874","line":43,"range":{"start_line":43,"start_character":31,"end_line":43,"end_character":37},"in_reply_to":"bae84128_a6b6403b","updated":"2016-02-19 16:14:34.000000000","message":"Done","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"}],"neutron/db/rbac_db_mixin.py":[{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from neutron.callbacks import registry"},{"line_number":21,"context_line":"from neutron.common import exceptions as n_exc"},{"line_number":22,"context_line":"from neutron.db import api as db_api"},{"line_number":23,"context_line":"from neutron.db import common_db_mixin as db"},{"line_number":24,"context_line":"from neutron.db import rbac_db_models as models"},{"line_number":25,"context_line":"from neutron.db.rbac_db_models import ACCESS_SHARED"},{"line_number":26,"context_line":"from neutron.extensions import rbac as ext_rbac"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_f0f51183","line":23,"range":{"start_line":23,"start_character":23,"end_line":23,"end_character":38},"updated":"2015-12-17 13:17:04.000000000","message":"Any particular reason to rename \u0027common_db_mixin\u0027 to \u0027db\u0027? I don\u0027t see any really-long-lines affected, and it\u0027s no where in your code so it\u0027s an unrelated change. Please revert.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"db20907040224f878c70fbf9aa693816d50edd7e","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from neutron.callbacks import registry"},{"line_number":21,"context_line":"from neutron.common import exceptions as n_exc"},{"line_number":22,"context_line":"from neutron.db import api as db_api"},{"line_number":23,"context_line":"from neutron.db import common_db_mixin as db"},{"line_number":24,"context_line":"from neutron.db import rbac_db_models as models"},{"line_number":25,"context_line":"from neutron.db.rbac_db_models import ACCESS_SHARED"},{"line_number":26,"context_line":"from neutron.extensions import rbac as ext_rbac"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_20918bf1","line":23,"range":{"start_line":23,"start_character":23,"end_line":23,"end_character":38},"in_reply_to":"3a7e1126_f0f51183","updated":"2015-12-20 07:29:11.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from neutron.db import api as db_api"},{"line_number":23,"context_line":"from neutron.db import common_db_mixin as db"},{"line_number":24,"context_line":"from neutron.db import rbac_db_models as models"},{"line_number":25,"context_line":"from neutron.db.rbac_db_models import ACCESS_SHARED"},{"line_number":26,"context_line":"from neutron.extensions import rbac as ext_rbac"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"# resource name using in callbacks"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_707e01e6","line":25,"updated":"2015-12-17 13:17:04.000000000","message":"One mustn\u0027t import objects/variables, only modules:\n\n from neutron.db import rbac_db_models\n # ...\n rbac_db_models.ACCESS_SHARED","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"db20907040224f878c70fbf9aa693816d50edd7e","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from neutron.db import api as db_api"},{"line_number":23,"context_line":"from neutron.db import common_db_mixin as db"},{"line_number":24,"context_line":"from neutron.db import rbac_db_models as models"},{"line_number":25,"context_line":"from neutron.db.rbac_db_models import ACCESS_SHARED"},{"line_number":26,"context_line":"from neutron.extensions import rbac as ext_rbac"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"# resource name using in callbacks"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_408e17d1","line":25,"in_reply_to":"3a7e1126_707e01e6","updated":"2015-12-20 07:29:11.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        raise ext_rbac.RbacPolicyNotFound(id\u003dentry_id, object_type\u003d\u0027unknown\u0027)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"class RBACNeutronObject(RbacPluginMixin):"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def __init__(self, context, rbac_db_model):"},{"line_number":131,"context_line":"        self.context \u003d context"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_0b8752b6","line":128,"range":{"start_line":128,"start_character":6,"end_line":128,"end_character":23},"updated":"2015-12-17 13:17:04.000000000","message":"Rename RBACNeutronObject to RbacNeutronObject to match RbacPluginMixin.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"db20907040224f878c70fbf9aa693816d50edd7e","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        raise ext_rbac.RbacPolicyNotFound(id\u003dentry_id, object_type\u003d\u0027unknown\u0027)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"class RBACNeutronObject(RbacPluginMixin):"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def __init__(self, context, rbac_db_model):"},{"line_number":131,"context_line":"        self.context \u003d context"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_20a8ab1f","line":128,"range":{"start_line":128,"start_character":6,"end_line":128,"end_character":23},"in_reply_to":"3a7e1126_0b8752b6","updated":"2015-12-20 07:29:11.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":140,"context_line":"        return self.create_rbac_policy(self.context, rbac_polily)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def _validate_update_shared(self, obj_id, bound_objects):"},{"line_number":143,"context_line":"        \"\"\"@raise InUse: If the update causes the policy to be"},{"line_number":144,"context_line":"        hidden from current bindings"},{"line_number":145,"context_line":"        \"\"\""},{"line_number":146,"context_line":"        with db_api.autonested_transaction(self.context.session):"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_e6af9be1","line":143,"range":{"start_line":143,"start_character":12,"end_line":143,"end_character":17},"updated":"2015-12-17 13:17:04.000000000","message":"This docstring is wrong for a few reasons. Please review http://docs.openstack.org/developer/hacking/#docstrings","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"db20907040224f878c70fbf9aa693816d50edd7e","unresolved":false,"context_lines":[{"line_number":140,"context_line":"        return self.create_rbac_policy(self.context, rbac_polily)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def _validate_update_shared(self, obj_id, bound_objects):"},{"line_number":143,"context_line":"        \"\"\"@raise InUse: If the update causes the policy to be"},{"line_number":144,"context_line":"        hidden from current bindings"},{"line_number":145,"context_line":"        \"\"\""},{"line_number":146,"context_line":"        with db_api.autonested_transaction(self.context.session):"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_e064e322","line":143,"range":{"start_line":143,"start_character":12,"end_line":143,"end_character":17},"in_reply_to":"3a7e1126_e6af9be1","updated":"2015-12-20 07:29:11.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":144,"context_line":"        hidden from current bindings"},{"line_number":145,"context_line":"        \"\"\""},{"line_number":146,"context_line":"        with db_api.autonested_transaction(self.context.session):"},{"line_number":147,"context_line":"            for db_obj in bound_objects or ():"},{"line_number":148,"context_line":"                if db_api.get_object(self.context,"},{"line_number":149,"context_line":"                                     self.rbac_db_model,"},{"line_number":150,"context_line":"                                     target_tenant\u003ddb_obj.tenant_id):"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_c67e1fae","line":147,"range":{"start_line":147,"start_character":40,"end_line":147,"end_character":45},"updated":"2015-12-17 13:17:04.000000000","message":"Suggestion: I think you\u0027re better off setting \u0027bound_objects\u003d()\u0027 as a default value in the functions\u0027 declaration.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"db20907040224f878c70fbf9aa693816d50edd7e","unresolved":false,"context_lines":[{"line_number":144,"context_line":"        hidden from current bindings"},{"line_number":145,"context_line":"        \"\"\""},{"line_number":146,"context_line":"        with db_api.autonested_transaction(self.context.session):"},{"line_number":147,"context_line":"            for db_obj in bound_objects or ():"},{"line_number":148,"context_line":"                if db_api.get_object(self.context,"},{"line_number":149,"context_line":"                                     self.rbac_db_model,"},{"line_number":150,"context_line":"                                     target_tenant\u003ddb_obj.tenant_id):"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_a0381bef","line":147,"range":{"start_line":147,"start_character":40,"end_line":147,"end_character":45},"in_reply_to":"3a7e1126_c67e1fae","updated":"2015-12-20 07:29:11.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        \"\"\""},{"line_number":146,"context_line":"        with db_api.autonested_transaction(self.context.session):"},{"line_number":147,"context_line":"            for db_obj in bound_objects or ():"},{"line_number":148,"context_line":"                if db_api.get_object(self.context,"},{"line_number":149,"context_line":"                                     self.rbac_db_model,"},{"line_number":150,"context_line":"                                     target_tenant\u003ddb_obj.tenant_id):"},{"line_number":151,"context_line":"                    raise n_exc.InUse()"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_a1765d3c","line":148,"range":{"start_line":148,"start_character":26,"end_line":148,"end_character":36},"updated":"2015-12-17 13:17:04.000000000","message":"So basically, for each db_obj we shall see if a matching one exists. Suppose I feed this function with some (really big) N objects - this can take a long time seeing as this is, ultimately, python code.\n\nThe (better, IMO) alternative is to allow the SQL do this instead. You can probably do a \u0027target_tenant.in_(\u003clist of tenants\u003e)\u0027 to reach the same result.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"db20907040224f878c70fbf9aa693816d50edd7e","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        \"\"\""},{"line_number":146,"context_line":"        with db_api.autonested_transaction(self.context.session):"},{"line_number":147,"context_line":"            for db_obj in bound_objects or ():"},{"line_number":148,"context_line":"                if db_api.get_object(self.context,"},{"line_number":149,"context_line":"                                     self.rbac_db_model,"},{"line_number":150,"context_line":"                                     target_tenant\u003ddb_obj.tenant_id):"},{"line_number":151,"context_line":"                    raise n_exc.InUse()"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_1b2de094","line":148,"range":{"start_line":148,"start_character":26,"end_line":148,"end_character":36},"in_reply_to":"3a7e1126_a1765d3c","updated":"2015-12-20 07:29:11.000000000","message":"The counter case of what you\u0027re suggesting is having two SQL queries (one for the get_bound_objecs and the other is for the target_tenant_in_(\u003clist_of_tenant_ids). I suggest avoiding premature optimization for now.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    @classmethod"},{"line_number":160,"context_line":"    def is_shared_with_tenant(cls, context, rbac_db_model, obj_id, tenant_id):"},{"line_number":161,"context_line":"        for e in cls._get_rbac_policies(context, rbac_db_model, obj_id):"},{"line_number":162,"context_line":"            if (e.action \u003d\u003d ACCESS_SHARED and e.target_tenant in ("},{"line_number":163,"context_line":"                    \u0027*\u0027, tenant_id)):"},{"line_number":164,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_8117a1a2","line":161,"range":{"start_line":161,"start_character":12,"end_line":161,"end_character":13},"updated":"2015-12-17 13:17:04.000000000","message":"Please rename \u0027e\u0027 to something more descriptive. Hint: renaming to \u0027entry\u0027 still leaves you on the green side of the 80-chars-per-line limitation.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"db20907040224f878c70fbf9aa693816d50edd7e","unresolved":false,"context_lines":[{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    @classmethod"},{"line_number":160,"context_line":"    def is_shared_with_tenant(cls, context, rbac_db_model, obj_id, tenant_id):"},{"line_number":161,"context_line":"        for e in cls._get_rbac_policies(context, rbac_db_model, obj_id):"},{"line_number":162,"context_line":"            if (e.action \u003d\u003d ACCESS_SHARED and e.target_tenant in ("},{"line_number":163,"context_line":"                    \u0027*\u0027, tenant_id)):"},{"line_number":164,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_8024ffc4","line":161,"range":{"start_line":161,"start_character":12,"end_line":161,"end_character":13},"in_reply_to":"3a7e1126_8117a1a2","updated":"2015-12-20 07:29:11.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":165,"context_line":"        return False"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    def update_shared(self, shared_new, bound_objects, obj_id):"},{"line_number":168,"context_line":"        \"\"\"The shared attribute reflects whether the policy is shared to"},{"line_number":169,"context_line":"        the calling tenant via RBAC entry."},{"line_number":170,"context_line":"        \"\"\""},{"line_number":171,"context_line":"        shared_prev \u003d self._get_rbac_policies(self.context, self.rbac_db_model,"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_81656146","line":168,"range":{"start_line":168,"start_character":11,"end_line":168,"end_character":14},"updated":"2015-12-17 13:17:04.000000000","message":"Ditto re: docstring formatting.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"db20907040224f878c70fbf9aa693816d50edd7e","unresolved":false,"context_lines":[{"line_number":165,"context_line":"        return False"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    def update_shared(self, shared_new, bound_objects, obj_id):"},{"line_number":168,"context_line":"        \"\"\"The shared attribute reflects whether the policy is shared to"},{"line_number":169,"context_line":"        the calling tenant via RBAC entry."},{"line_number":170,"context_line":"        \"\"\""},{"line_number":171,"context_line":"        shared_prev \u003d self._get_rbac_policies(self.context, self.rbac_db_model,"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_202d0ba8","line":168,"range":{"start_line":168,"start_character":11,"end_line":168,"end_character":14},"in_reply_to":"3a7e1126_81656146","updated":"2015-12-20 07:29:11.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    def update_shared(self, shared_new, bound_objects, obj_id):"},{"line_number":168,"context_line":"        \"\"\"The shared attribute reflects whether the policy is shared to"},{"line_number":169,"context_line":"        the calling tenant via RBAC entry."},{"line_number":170,"context_line":"        \"\"\""},{"line_number":171,"context_line":"        shared_prev \u003d self._get_rbac_policies(self.context, self.rbac_db_model,"},{"line_number":172,"context_line":"                                             obj_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_7ca6dac2","line":169,"range":{"start_line":169,"start_character":27,"end_line":169,"end_character":35},"updated":"2015-12-17 13:17:04.000000000","message":"nit: s/via RBAC/via a RBAC/g","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"db20907040224f878c70fbf9aa693816d50edd7e","unresolved":false,"context_lines":[{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    def update_shared(self, shared_new, bound_objects, obj_id):"},{"line_number":168,"context_line":"        \"\"\"The shared attribute reflects whether the policy is shared to"},{"line_number":169,"context_line":"        the calling tenant via RBAC entry."},{"line_number":170,"context_line":"        \"\"\""},{"line_number":171,"context_line":"        shared_prev \u003d self._get_rbac_policies(self.context, self.rbac_db_model,"},{"line_number":172,"context_line":"                                             obj_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_402a9791","line":169,"range":{"start_line":169,"start_character":27,"end_line":169,"end_character":35},"in_reply_to":"3a7e1126_7ca6dac2","updated":"2015-12-20 07:29:11.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":171,"context_line":"        shared_prev \u003d self._get_rbac_policies(self.context, self.rbac_db_model,"},{"line_number":172,"context_line":"                                             obj_id)"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        if bool(shared_prev) \u003d\u003d shared_new:"},{"line_number":175,"context_line":"            return"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"        # \u0027sharing\u0027 goes False -\u003e True"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_018731b6","line":174,"range":{"start_line":174,"start_character":11,"end_line":174,"end_character":28},"updated":"2015-12-17 13:17:04.000000000","message":"nit: since this is done twice throughout the code, how about we save it to some variable?","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"db20907040224f878c70fbf9aa693816d50edd7e","unresolved":false,"context_lines":[{"line_number":171,"context_line":"        shared_prev \u003d self._get_rbac_policies(self.context, self.rbac_db_model,"},{"line_number":172,"context_line":"                                             obj_id)"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        if bool(shared_prev) \u003d\u003d shared_new:"},{"line_number":175,"context_line":"            return"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"        # \u0027sharing\u0027 goes False -\u003e True"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_001faf6c","line":174,"range":{"start_line":174,"start_character":11,"end_line":174,"end_character":28},"in_reply_to":"3a7e1126_018731b6","updated":"2015-12-20 07:29:11.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":"        # \u0027sharing\u0027 goes True -\u003e False"},{"line_number":183,"context_line":"        self._validate_update_shared(obj_id, bound_objects)"},{"line_number":184,"context_line":"        for e in shared_prev:"},{"line_number":185,"context_line":"            if e.action \u003d\u003d ACCESS_SHARED and e.target_tenant \u003d\u003d \u0027*\u0027:"},{"line_number":186,"context_line":"                return self.context.session.delete(e)"},{"line_number":187,"context_line":"        raise n_exc.PolicyCheckError(policy\u003dobj_id, reason\u003d\u0027not shared\u0027)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_a1817d91","line":184,"range":{"start_line":184,"start_character":12,"end_line":184,"end_character":13},"updated":"2015-12-17 13:17:04.000000000","message":"Ditto re: renaming of \u0027e\u0027. Overall we prefer descriptive variable names in the price of longer lines.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"46700008826cc88fbbfef7ce857bbc8c84e8948d","unresolved":false,"context_lines":[{"line_number":184,"context_line":"        for e in shared_prev:"},{"line_number":185,"context_line":"            if e.action \u003d\u003d ACCESS_SHARED and e.target_tenant \u003d\u003d \u0027*\u0027:"},{"line_number":186,"context_line":"                return self.context.session.delete(e)"},{"line_number":187,"context_line":"        raise n_exc.PolicyCheckError(policy\u003dobj_id, reason\u003d\u0027not shared\u0027)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_7481238f","line":187,"updated":"2015-12-17 07:24:02.000000000","message":"missing translation for the reason","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"30599cd74aa21f58b1c83a0b115dfe06302ef5c4","unresolved":false,"context_lines":[{"line_number":184,"context_line":"        for e in shared_prev:"},{"line_number":185,"context_line":"            if e.action \u003d\u003d ACCESS_SHARED and e.target_tenant \u003d\u003d \u0027*\u0027:"},{"line_number":186,"context_line":"                return self.context.session.delete(e)"},{"line_number":187,"context_line":"        raise n_exc.PolicyCheckError(policy\u003dobj_id, reason\u003d\u0027not shared\u0027)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_53209d9b","line":187,"in_reply_to":"3a7e1126_7481238f","updated":"2015-12-17 15:59:47.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"fe55d9cd73219555a689b319cbd9069f80554b52","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        raise ext_rbac.RbacPolicyNotFound(id\u003dentry_id, object_type\u003d\u0027unknown\u0027)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"class RbacNeutronObject(RbacPluginMixin, NeutronDbObject):"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def attach_rbac(self, obj_id, tenant_id, target_tenant\u003d\u0027*\u0027):"},{"line_number":131,"context_line":"        obj_type \u003d self.rbac_db_model.object_type"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a5de9d1_eec51a5b","line":128,"range":{"start_line":128,"start_character":6,"end_line":128,"end_character":23},"updated":"2016-01-28 10:48:26.000000000","message":"super nice that you made something generic for any neutron object!!\n\namazing work.","commit_id":"78a8bd43e98932225962826f0c2115b501cdbf6c"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"ae40ab1f9dbe455e86689db0fd28a605152e5788","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        raise ext_rbac.RbacPolicyNotFound(id\u003dentry_id, object_type\u003d\u0027unknown\u0027)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"class RbacNeutronObject(RbacPluginMixin, NeutronDbObject):"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def attach_rbac(self, obj_id, tenant_id, target_tenant\u003d\u0027*\u0027):"},{"line_number":131,"context_line":"        obj_type \u003d self.rbac_db_model.object_type"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a5de9d1_a9307c57","line":128,"range":{"start_line":128,"start_character":6,"end_line":128,"end_character":23},"in_reply_to":"7a5de9d1_eec51a5b","updated":"2016-01-28 11:18:02.000000000","message":"\u003cblushes on\u003e Thanks! \u003c/blushes\u003e","commit_id":"78a8bd43e98932225962826f0c2115b501cdbf6c"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"fe55d9cd73219555a689b319cbd9069f80554b52","unresolved":false,"context_lines":[{"line_number":223,"context_line":"        return res"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":""},{"line_number":226,"context_line":"class RbacNeutronMetaclass(type):"},{"line_number":227,"context_line":"    \"\"\"Adds support for Rbac in NeutronDbObjects"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    Injects code for CRUD operations to add the rbac support"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a5de9d1_cef13ecf","line":226,"range":{"start_line":226,"start_character":6,"end_line":226,"end_character":26},"updated":"2016-01-28 10:48:26.000000000","message":"I don\u0027t get to totally grasp what\u0027s the advantage of a metaclass compared to subclass yet.\n\nI guess @ihar and you could give me more details about it, but I suspect you didn\u0027t go into this for no reason :)","commit_id":"78a8bd43e98932225962826f0c2115b501cdbf6c"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"ae40ab1f9dbe455e86689db0fd28a605152e5788","unresolved":false,"context_lines":[{"line_number":223,"context_line":"        return res"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":""},{"line_number":226,"context_line":"class RbacNeutronMetaclass(type):"},{"line_number":227,"context_line":"    \"\"\"Adds support for Rbac in NeutronDbObjects"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    Injects code for CRUD operations to add the rbac support"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a5de9d1_a9e2bcd3","line":226,"range":{"start_line":226,"start_character":6,"end_line":226,"end_character":26},"in_reply_to":"7a5de9d1_cef13ecf","updated":"2016-01-28 11:18:02.000000000","message":"well the logic doesn\u0027t actually fits a subclass, since the rbac is more of a \"thing I have\" than the \"thing I am\", but still implementing in that way requires modifying of the subject class (e.g QosPolicy). That what @ihrasys wanted to avoid. Hence the attempt to make it generic.","commit_id":"78a8bd43e98932225962826f0c2115b501cdbf6c"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"89dc6c8a83f2209990487100aaaa8ffea9924539","unresolved":false,"context_lines":[{"line_number":130,"context_line":""},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"@add_metaclass(abc.ABCMeta)"},{"line_number":133,"context_line":"class RbacNeutronObject(RbacPluginMixin, NeutronDbObject):"},{"line_number":134,"context_line":"    @classmethod"},{"line_number":135,"context_line":"    @abc.abstractmethod"},{"line_number":136,"context_line":"    def get_bound_tenant_ids(cls, context, obj_id):"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_8131f7ee","line":133,"range":{"start_line":133,"start_character":6,"end_line":133,"end_character":23},"updated":"2016-02-03 13:44:40.000000000","message":"Please push a newline after the end of this one.","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":130,"context_line":""},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"@add_metaclass(abc.ABCMeta)"},{"line_number":133,"context_line":"class RbacNeutronObject(RbacPluginMixin, NeutronDbObject):"},{"line_number":134,"context_line":"    @classmethod"},{"line_number":135,"context_line":"    @abc.abstractmethod"},{"line_number":136,"context_line":"    def get_bound_tenant_ids(cls, context, obj_id):"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_f5ce5f59","line":133,"range":{"start_line":133,"start_character":6,"end_line":133,"end_character":23},"in_reply_to":"5a5ae5dd_8131f7ee","updated":"2016-02-04 10:11:00.000000000","message":"Done","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"96f163e46f88fdbd1e16bbf6bfcfa7c4e2f9e425","unresolved":false,"context_lines":[{"line_number":155,"context_line":"    def is_shared_with_tenant(cls, context, rbac_db_model, obj_id, tenant_id):"},{"line_number":156,"context_line":"        for e in cls._get_rbac_policies(context, rbac_db_model, obj_id):"},{"line_number":157,"context_line":"            if (e.action \u003d\u003d models.ACCESS_SHARED and e.target_tenant in ("},{"line_number":158,"context_line":"                    \u0027*\u0027, tenant_id)):"},{"line_number":159,"context_line":"                return True"},{"line_number":160,"context_line":"        return False"},{"line_number":161,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_5c0a0ed4","line":158,"range":{"start_line":158,"start_character":25,"end_line":158,"end_character":34},"updated":"2016-02-03 11:34:57.000000000","message":"supernit:\nsince e.action has always to be models.ACCESS_SHARED, could we filter the _get_rbac_polices at the db_api query level\n\naction\u003d\u003dmodels.ACCESS_SHARED and (target_tenant\u003d\u003dtenant_id or target_tenant\u003d\u003d\u0027*\u0027)\n\nThis way we\u0027d reduce any future overhead due to other actions existing in the table.","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":155,"context_line":"    def is_shared_with_tenant(cls, context, rbac_db_model, obj_id, tenant_id):"},{"line_number":156,"context_line":"        for e in cls._get_rbac_policies(context, rbac_db_model, obj_id):"},{"line_number":157,"context_line":"            if (e.action \u003d\u003d models.ACCESS_SHARED and e.target_tenant in ("},{"line_number":158,"context_line":"                    \u0027*\u0027, tenant_id)):"},{"line_number":159,"context_line":"                return True"},{"line_number":160,"context_line":"        return False"},{"line_number":161,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_5c63d81a","line":158,"range":{"start_line":158,"start_character":25,"end_line":158,"end_character":34},"in_reply_to":"5a5ae5dd_5c0a0ed4","updated":"2016-02-04 10:11:00.000000000","message":"Done","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"96f163e46f88fdbd1e16bbf6bfcfa7c4e2f9e425","unresolved":false,"context_lines":[{"line_number":166,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    @classmethod"},{"line_number":169,"context_line":"    def validate_rbac_policy_delete(cls, resource, event, trigger, context,"},{"line_number":170,"context_line":"                                    object_type, policy, **kwargs):"},{"line_number":171,"context_line":"        if object_type !\u003d cls.rbac_db_model.object_type:"},{"line_number":172,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_3f74e49a","line":169,"range":{"start_line":169,"start_character":8,"end_line":169,"end_character":35},"updated":"2016-02-03 11:34:57.000000000","message":"can we add a docstring explaining this is a callback which will be registered in the callback subsystem to handle RBAC_POLICY, BEFORE_DELETE?","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":166,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    @classmethod"},{"line_number":169,"context_line":"    def validate_rbac_policy_delete(cls, resource, event, trigger, context,"},{"line_number":170,"context_line":"                                    object_type, policy, **kwargs):"},{"line_number":171,"context_line":"        if object_type !\u003d cls.rbac_db_model.object_type:"},{"line_number":172,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_a11ae515","line":169,"range":{"start_line":169,"start_character":8,"end_line":169,"end_character":35},"in_reply_to":"5a5ae5dd_3f74e49a","updated":"2016-02-04 10:11:00.000000000","message":"Done","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"89dc6c8a83f2209990487100aaaa8ffea9924539","unresolved":false,"context_lines":[{"line_number":166,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    @classmethod"},{"line_number":169,"context_line":"    def validate_rbac_policy_delete(cls, resource, event, trigger, context,"},{"line_number":170,"context_line":"                                    object_type, policy, **kwargs):"},{"line_number":171,"context_line":"        if object_type !\u003d cls.rbac_db_model.object_type:"},{"line_number":172,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_89f35d73","line":169,"range":{"start_line":169,"start_character":8,"end_line":169,"end_character":35},"in_reply_to":"5a5ae5dd_3f74e49a","updated":"2016-02-03 13:44:40.000000000","message":"Yes, please do this :)","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":166,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    @classmethod"},{"line_number":169,"context_line":"    def validate_rbac_policy_delete(cls, resource, event, trigger, context,"},{"line_number":170,"context_line":"                                    object_type, policy, **kwargs):"},{"line_number":171,"context_line":"        if object_type !\u003d cls.rbac_db_model.object_type:"},{"line_number":172,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_e120dd4b","line":169,"range":{"start_line":169,"start_character":8,"end_line":169,"end_character":35},"in_reply_to":"5a5ae5dd_89f35d73","updated":"2016-02-04 10:11:00.000000000","message":"Done","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"96f163e46f88fdbd1e16bbf6bfcfa7c4e2f9e425","unresolved":false,"context_lines":[{"line_number":169,"context_line":"    def validate_rbac_policy_delete(cls, resource, event, trigger, context,"},{"line_number":170,"context_line":"                                    object_type, policy, **kwargs):"},{"line_number":171,"context_line":"        if object_type !\u003d cls.rbac_db_model.object_type:"},{"line_number":172,"context_line":"            return"},{"line_number":173,"context_line":"        if policy[\u0027action\u0027] !\u003d models.ACCESS_SHARED:"},{"line_number":174,"context_line":"            return"},{"line_number":175,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_fc989a6c","line":172,"range":{"start_line":172,"start_character":12,"end_line":172,"end_character":18},"updated":"2016-02-03 11:34:57.000000000","message":"Isn\u0027t this an unexpected case?,\n\nMay we raise an exception in this case?","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":169,"context_line":"    def validate_rbac_policy_delete(cls, resource, event, trigger, context,"},{"line_number":170,"context_line":"                                    object_type, policy, **kwargs):"},{"line_number":171,"context_line":"        if object_type !\u003d cls.rbac_db_model.object_type:"},{"line_number":172,"context_line":"            return"},{"line_number":173,"context_line":"        if policy[\u0027action\u0027] !\u003d models.ACCESS_SHARED:"},{"line_number":174,"context_line":"            return"},{"line_number":175,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_c15fe10c","line":172,"range":{"start_line":172,"start_character":12,"end_line":172,"end_character":18},"in_reply_to":"5a5ae5dd_fc989a6c","updated":"2016-02-04 10:11:00.000000000","message":"since the network rbac lives in a separate module, and it uses the callback manager as well, this function will be hit with network-rbac delete event as well - so raising here will be a bug.","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"96f163e46f88fdbd1e16bbf6bfcfa7c4e2f9e425","unresolved":false,"context_lines":[{"line_number":170,"context_line":"                                    object_type, policy, **kwargs):"},{"line_number":171,"context_line":"        if object_type !\u003d cls.rbac_db_model.object_type:"},{"line_number":172,"context_line":"            return"},{"line_number":173,"context_line":"        if policy[\u0027action\u0027] !\u003d models.ACCESS_SHARED:"},{"line_number":174,"context_line":"            return"},{"line_number":175,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"},{"line_number":176,"context_line":"        if not target_tenant or target_tenant \u003d\u003d policy[\u0027tenant_id\u0027]:"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_32e97b1b","line":173,"range":{"start_line":173,"start_character":8,"end_line":173,"end_character":10},"updated":"2016-02-03 11:34:57.000000000","message":"suggestion/opinion/nit:\n\nif policy[\u0027action\u0027] !\u003d models.ACCESS_SHARED:\n    self._validate_rbac_access_shared_delete(.....)\nelse: \n    raise .....\n\nand then refactor down here to a separate function.\n\nThis way you lay the land for anyone coming after and trying to implement different actions.","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":170,"context_line":"                                    object_type, policy, **kwargs):"},{"line_number":171,"context_line":"        if object_type !\u003d cls.rbac_db_model.object_type:"},{"line_number":172,"context_line":"            return"},{"line_number":173,"context_line":"        if policy[\u0027action\u0027] !\u003d models.ACCESS_SHARED:"},{"line_number":174,"context_line":"            return"},{"line_number":175,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"},{"line_number":176,"context_line":"        if not target_tenant or target_tenant \u003d\u003d policy[\u0027tenant_id\u0027]:"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_21b035dd","line":173,"range":{"start_line":173,"start_character":8,"end_line":173,"end_character":10},"in_reply_to":"5a5ae5dd_32e97b1b","updated":"2016-02-04 10:11:00.000000000","message":"Not sure why should the else branch raise an exception ?","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"96f163e46f88fdbd1e16bbf6bfcfa7c4e2f9e425","unresolved":false,"context_lines":[{"line_number":171,"context_line":"        if object_type !\u003d cls.rbac_db_model.object_type:"},{"line_number":172,"context_line":"            return"},{"line_number":173,"context_line":"        if policy[\u0027action\u0027] !\u003d models.ACCESS_SHARED:"},{"line_number":174,"context_line":"            return"},{"line_number":175,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"},{"line_number":176,"context_line":"        if not target_tenant or target_tenant \u003d\u003d policy[\u0027tenant_id\u0027]:"},{"line_number":177,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_3cb632dd","line":174,"range":{"start_line":174,"start_character":12,"end_line":174,"end_character":18},"updated":"2016-02-03 11:34:57.000000000","message":"and here (ditto) ?","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"96f163e46f88fdbd1e16bbf6bfcfa7c4e2f9e425","unresolved":false,"context_lines":[{"line_number":174,"context_line":"            return"},{"line_number":175,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"},{"line_number":176,"context_line":"        if not target_tenant or target_tenant \u003d\u003d policy[\u0027tenant_id\u0027]:"},{"line_number":177,"context_line":"            return"},{"line_number":178,"context_line":"        ctx_admin \u003d context.elevated()"},{"line_number":179,"context_line":"        obj_id \u003d policy[\u0027object_id\u0027]"},{"line_number":180,"context_line":"        rb_model \u003d cls.rbac_db_model"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_7caa6a1b","line":177,"range":{"start_line":177,"start_character":12,"end_line":177,"end_character":18},"updated":"2016-02-03 11:34:57.000000000","message":"I assume return \u003d you let it delete.\n\nnit: Can we document this in the docstring of the method?","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":174,"context_line":"            return"},{"line_number":175,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"},{"line_number":176,"context_line":"        if not target_tenant or target_tenant \u003d\u003d policy[\u0027tenant_id\u0027]:"},{"line_number":177,"context_line":"            return"},{"line_number":178,"context_line":"        ctx_admin \u003d context.elevated()"},{"line_number":179,"context_line":"        obj_id \u003d policy[\u0027object_id\u0027]"},{"line_number":180,"context_line":"        rb_model \u003d cls.rbac_db_model"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_01f6598f","line":177,"range":{"start_line":177,"start_character":12,"end_line":177,"end_character":18},"in_reply_to":"5a5ae5dd_7caa6a1b","updated":"2016-02-04 10:11:00.000000000","message":"Done","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"96f163e46f88fdbd1e16bbf6bfcfa7c4e2f9e425","unresolved":false,"context_lines":[{"line_number":196,"context_line":"                    object_id\u003dobj_id,"},{"line_number":197,"context_line":"                    details\u003d\u0027tenant_id\u003d{}\u0027.format(target_tenant))"},{"line_number":198,"context_line":"        else:"},{"line_number":199,"context_line":"            def flatten(x):"},{"line_number":200,"context_line":"                return list(itertools.chain.from_iterable(x))"},{"line_number":201,"context_line":"            # for the wildcard we need to get all of the rbac entries to"},{"line_number":202,"context_line":"            # see if any allow the object sharing"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_b2c48b92","line":199,"range":{"start_line":199,"start_character":16,"end_line":199,"end_character":23},"updated":"2016-02-03 11:34:57.000000000","message":"why do you need this, what\u0027s the return of filter?\n\nCan\u0027t you just do \n\n[tenant for other_target_tenants.filter(...).all()]   ? \n\nI\u0027m likely missing something here :)","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":196,"context_line":"                    object_id\u003dobj_id,"},{"line_number":197,"context_line":"                    details\u003d\u0027tenant_id\u003d{}\u0027.format(target_tenant))"},{"line_number":198,"context_line":"        else:"},{"line_number":199,"context_line":"            def flatten(x):"},{"line_number":200,"context_line":"                return list(itertools.chain.from_iterable(x))"},{"line_number":201,"context_line":"            # for the wildcard we need to get all of the rbac entries to"},{"line_number":202,"context_line":"            # see if any allow the object sharing"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_579bb3c9","line":199,"range":{"start_line":199,"start_character":16,"end_line":199,"end_character":23},"in_reply_to":"5a5ae5dd_b2c48b92","updated":"2016-02-04 10:11:00.000000000","message":"because other_target_tenants is a column selection - which sqlalchemy kindly does as a list of single tuples. I need that to be flat list of tenant ids.","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"96f163e46f88fdbd1e16bbf6bfcfa7c4e2f9e425","unresolved":false,"context_lines":[{"line_number":208,"context_line":"                    details\u003d\u0027tenant_id\u003d{}\u0027.format(target_tenant))"},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"    @classmethod"},{"line_number":211,"context_line":"    def validate_rbac_policy_update(cls, resource, event, trigger, context,"},{"line_number":212,"context_line":"                                    object_type, policy, **kwargs):"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"        prev_tenant \u003d policy[\u0027target_tenant\u0027]"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_ff6deccc","line":211,"updated":"2016-02-03 11:34:57.000000000","message":"same about Docstring for callbacks","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":208,"context_line":"                    details\u003d\u0027tenant_id\u003d{}\u0027.format(target_tenant))"},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"    @classmethod"},{"line_number":211,"context_line":"    def validate_rbac_policy_update(cls, resource, event, trigger, context,"},{"line_number":212,"context_line":"                                    object_type, policy, **kwargs):"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"        prev_tenant \u003d policy[\u0027target_tenant\u0027]"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_215a7584","line":211,"in_reply_to":"5a5ae5dd_ff6deccc","updated":"2016-02-04 10:11:00.000000000","message":"Done","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"96f163e46f88fdbd1e16bbf6bfcfa7c4e2f9e425","unresolved":false,"context_lines":[{"line_number":338,"context_line":"        mcs.replace_method(bases, dct, \u0027to_dict\u0027,"},{"line_number":339,"context_line":"                           RbacNeutronObject.to_dict_hook)"},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"        dct[\u0027synthetic_fields\u0027].append(\u0027shared\u0027)"},{"line_number":342,"context_line":"        cls \u003d type(name, (RbacNeutronObject,) + bases, dct)"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        registry.subscribe(cls.validate_rbac_policy_delete,"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_9f1ab86d","line":341,"range":{"start_line":341,"start_character":32,"end_line":341,"end_character":38},"updated":"2016-02-03 11:34:57.000000000","message":"may we raise an exception if shared was already there for some reason?","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":338,"context_line":"        mcs.replace_method(bases, dct, \u0027to_dict\u0027,"},{"line_number":339,"context_line":"                           RbacNeutronObject.to_dict_hook)"},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"        dct[\u0027synthetic_fields\u0027].append(\u0027shared\u0027)"},{"line_number":342,"context_line":"        cls \u003d type(name, (RbacNeutronObject,) + bases, dct)"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        registry.subscribe(cls.validate_rbac_policy_delete,"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_1c7c8071","line":341,"range":{"start_line":341,"start_character":32,"end_line":341,"end_character":38},"in_reply_to":"5a5ae5dd_9f1ab86d","updated":"2016-02-04 10:11:00.000000000","message":"IMO that\u0027s a bit harsh - perhaps avoiding a duplicate append ?","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    object_type_cache \u003d {}"},{"line_number":40,"context_line":"    supported_extension_aliases \u003d [\u0027rbac-policies\u0027]"},{"line_number":41,"context_line":"    rbac_db_model \u003d None"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def create_rbac_policy(self, context, rbac_policy):"},{"line_number":44,"context_line":"        e \u003d rbac_policy[\u0027rbac_policy\u0027]"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_d7e61943","line":41,"updated":"2016-02-08 12:40:03.000000000","message":"I assume that\u0027s redundant and is really versioned objects only, so should be moved to RbacNeutronObject.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    object_type_cache \u003d {}"},{"line_number":40,"context_line":"    supported_extension_aliases \u003d [\u0027rbac-policies\u0027]"},{"line_number":41,"context_line":"    rbac_db_model \u003d None"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def create_rbac_policy(self, context, rbac_policy):"},{"line_number":44,"context_line":"        e \u003d rbac_policy[\u0027rbac_policy\u0027]"}],"source_content_type":"text/x-python","patch_set":14,"id":"3a57f1b5_ce49f7b8","line":41,"in_reply_to":"5a5ae5dd_d7e61943","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":53,"context_line":"            db_entry \u003d dbmodel(object_id\u003de[\u0027object_id\u0027],"},{"line_number":54,"context_line":"                               target_tenant\u003de[\u0027target_tenant\u0027],"},{"line_number":55,"context_line":"                               action\u003de[\u0027action\u0027],"},{"line_number":56,"context_line":"                               tenant_id\u003dcontext.tenant_id)"},{"line_number":57,"context_line":"            context.session.add(db_entry)"},{"line_number":58,"context_line":"        return self._make_rbac_policy_dict(db_entry)"},{"line_number":59,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_174fd137","line":56,"updated":"2016-02-08 12:40:03.000000000","message":"Hm. I suspect it\u0027s not directly related to your patch, right? It\u0027s a bug where we allow a tenant to create RBAC entries that would be owned by other tenants?.. If that\u0027s the case, we may want to backport the fix to stable branches, and hence it should be in a separate patch.\n\nI want Kevin to chime in here.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":139,"context_line":"        raise ext_rbac.RbacPolicyNotFound(id\u003dentry_id, object_type\u003d\u0027unknown\u0027)"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"@add_metaclass(abc.ABCMeta)"},{"line_number":143,"context_line":"class RbacNeutronObject(RbacPluginMixin, NeutronDbObject):"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_99a770bc","line":142,"updated":"2016-02-08 12:40:03.000000000","message":"All this code is not covered by unit tests. There should be a whole new test class that targets just that code (using fake RBAC aware objects, not QoS policies).","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":139,"context_line":"        raise ext_rbac.RbacPolicyNotFound(id\u003dentry_id, object_type\u003d\u0027unknown\u0027)"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"@add_metaclass(abc.ABCMeta)"},{"line_number":143,"context_line":"class RbacNeutronObject(RbacPluginMixin, NeutronDbObject):"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_43bf3bfb","line":142,"in_reply_to":"5a5ae5dd_99a770bc","updated":"2016-02-15 22:48:57.000000000","message":"Will do, after rebasing this patchset on master, due to bugfix https://bugs.launchpad.net/neutron/+bug/1542815","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":140,"context_line":""},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"@add_metaclass(abc.ABCMeta)"},{"line_number":143,"context_line":"class RbacNeutronObject(RbacPluginMixin, NeutronDbObject):"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"    @classmethod"},{"line_number":146,"context_line":"    @abc.abstractmethod"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_b437dbfd","line":143,"updated":"2016-02-08 12:40:03.000000000","message":"The class should live under neutron/objects. I also suggest to rename it into RbacNeutronDbObject.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":140,"context_line":""},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"@add_metaclass(abc.ABCMeta)"},{"line_number":143,"context_line":"class RbacNeutronObject(RbacPluginMixin, NeutronDbObject):"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"    @classmethod"},{"line_number":146,"context_line":"    @abc.abstractmethod"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_ded7d421","line":143,"in_reply_to":"5a5ae5dd_b437dbfd","updated":"2016-02-15 22:48:57.000000000","message":"I renamed the class. Do you suggest moving the RbacPluginMixin class there as well ?","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":152,"context_line":"        object to them. E.g: for QosPolicy that would be the tenants using the"},{"line_number":153,"context_line":"        Networks and Ports with the shared QosPolicy applied to them."},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"        :returns: list -- a list of tenants\u0027 ids dependant on this object."},{"line_number":156,"context_line":"        \"\"\""},{"line_number":157,"context_line":"        pass"},{"line_number":158,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_b7a7ddbb","line":155,"updated":"2016-02-08 12:40:03.000000000","message":"nit: dependent","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"d08687721f3ac76091cf0b8bd9b35571aa2eac22","unresolved":false,"context_lines":[{"line_number":152,"context_line":"        object to them. E.g: for QosPolicy that would be the tenants using the"},{"line_number":153,"context_line":"        Networks and Ports with the shared QosPolicy applied to them."},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"        :returns: list -- a list of tenants\u0027 ids dependant on this object."},{"line_number":156,"context_line":"        \"\"\""},{"line_number":157,"context_line":"        pass"},{"line_number":158,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_c46bbcb5","line":155,"in_reply_to":"5a5ae5dd_b7a7ddbb","updated":"2016-02-08 16:01:54.000000000","message":"dependant is correct for British English (AFAIK)","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":152,"context_line":"        object to them. E.g: for QosPolicy that would be the tenants using the"},{"line_number":153,"context_line":"        Networks and Ports with the shared QosPolicy applied to them."},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"        :returns: list -- a list of tenants\u0027 ids dependant on this object."},{"line_number":156,"context_line":"        \"\"\""},{"line_number":157,"context_line":"        pass"},{"line_number":158,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_feb9f8ed","line":155,"in_reply_to":"5a5ae5dd_c46bbcb5","updated":"2016-02-15 22:48:57.000000000","message":"I\u0027ve updated it to dependent, just in case :)","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":175,"context_line":"    @classmethod"},{"line_number":176,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":177,"context_line":"        return (context.is_admin or"},{"line_number":178,"context_line":"                cls.is_shared_with_tenant(context, cls.rbac_db_model,"},{"line_number":179,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_b7503d33","line":178,"updated":"2016-02-08 12:40:03.000000000","message":"what about the case when you actually own the resource?","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":175,"context_line":"    @classmethod"},{"line_number":176,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":177,"context_line":"        return (context.is_admin or"},{"line_number":178,"context_line":"                cls.is_shared_with_tenant(context, cls.rbac_db_model,"},{"line_number":179,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_bec81076","line":178,"in_reply_to":"5a5ae5dd_443a6c9a","updated":"2016-02-15 22:48:57.000000000","message":"Fixed-thanks","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"d08687721f3ac76091cf0b8bd9b35571aa2eac22","unresolved":false,"context_lines":[{"line_number":175,"context_line":"    @classmethod"},{"line_number":176,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":177,"context_line":"        return (context.is_admin or"},{"line_number":178,"context_line":"                cls.is_shared_with_tenant(context, cls.rbac_db_model,"},{"line_number":179,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_443a6c9a","line":178,"in_reply_to":"5a5ae5dd_b7503d33","updated":"2016-02-08 16:01:54.000000000","message":"Yikes, non nit detail :)\n\ncontext.is_admin or\ncls.is_owned_by_tenant(...) or\ncls.is_shared_with_tenant(...) ?","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":179,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"    @classmethod"},{"line_number":182,"context_line":"    def validate_rbac_policy_delete(cls, resource, event, trigger, context,"},{"line_number":183,"context_line":"                                    object_type, policy, **kwargs):"},{"line_number":184,"context_line":"        \"\"\"Callback to handle RBAC_POLICY, BEFORE_DELETE callback."},{"line_number":185,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_3e08a227","line":182,"updated":"2016-02-08 12:40:03.000000000","message":"I see a lot of code here duplicates what we have in common_db_mixin.py right now. I understand it may be extremely complex to reuse the code here, and I won\u0027t request it as part of the patch. [Especially since eventually the code here should be used for networks too.]\n\nThat said, I think we should add a NOTE/TODO both here and in common_db_mixin.py cross-referring to another piece of code with similar logic, so that in case we detect a bug in one place, we are notified we should fix it in another place too.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":179,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"    @classmethod"},{"line_number":182,"context_line":"    def validate_rbac_policy_delete(cls, resource, event, trigger, context,"},{"line_number":183,"context_line":"                                    object_type, policy, **kwargs):"},{"line_number":184,"context_line":"        \"\"\"Callback to handle RBAC_POLICY, BEFORE_DELETE callback."},{"line_number":185,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_3e99a06f","line":182,"in_reply_to":"5a5ae5dd_3e08a227","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":255,"context_line":"        hidden from current bindings."},{"line_number":256,"context_line":"        \"\"\""},{"line_number":257,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":258,"context_line":"            for db_obj in bound_objects or ():"},{"line_number":259,"context_line":"                if db_api.get_object(self._context,"},{"line_number":260,"context_line":"                                     self.rbac_db_model,"},{"line_number":261,"context_line":"                                     target_tenant\u003ddb_obj.tenant_id):"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_e3b83313","line":258,"updated":"2016-02-08 12:40:03.000000000","message":"nit: I think \u0027or ()\u0027 is redundant since bound_objects is always an iterable.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":255,"context_line":"        hidden from current bindings."},{"line_number":256,"context_line":"        \"\"\""},{"line_number":257,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":258,"context_line":"            for db_obj in bound_objects or ():"},{"line_number":259,"context_line":"                if db_api.get_object(self._context,"},{"line_number":260,"context_line":"                                     self.rbac_db_model,"},{"line_number":261,"context_line":"                                     target_tenant\u003ddb_obj.tenant_id):"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_1e9e5c56","line":258,"in_reply_to":"5a5ae5dd_e3b83313","updated":"2016-02-15 22:48:57.000000000","message":"That function has been brutally removed - its place is taken now by _validate_rbac_policy_delete(), basically we validate a global rbac policy (target_tenant \u003d \u0027*\u0027) can be done when \u0027shared\u0027 goes True -\u003e False.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":258,"context_line":"            for db_obj in bound_objects or ():"},{"line_number":259,"context_line":"                if db_api.get_object(self._context,"},{"line_number":260,"context_line":"                                     self.rbac_db_model,"},{"line_number":261,"context_line":"                                     target_tenant\u003ddb_obj.tenant_id):"},{"line_number":262,"context_line":"                    raise n_exc.InUse()"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":"    def update_shared(self, shared_new, bound_objects, obj_id):"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_23e64b15","line":261,"updated":"2016-02-08 12:40:03.000000000","message":"should we also make sure that the type of the RBAC is access_as_shared?","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":258,"context_line":"            for db_obj in bound_objects or ():"},{"line_number":259,"context_line":"                if db_api.get_object(self._context,"},{"line_number":260,"context_line":"                                     self.rbac_db_model,"},{"line_number":261,"context_line":"                                     target_tenant\u003ddb_obj.tenant_id):"},{"line_number":262,"context_line":"                    raise n_exc.InUse()"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":"    def update_shared(self, shared_new, bound_objects, obj_id):"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_260a1bd3","line":261,"in_reply_to":"5a5ae5dd_23e64b15","updated":"2016-02-15 22:48:57.000000000","message":"Done, that\u0027s a part of _validate_rbac_policy_delete() now.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"d08687721f3ac76091cf0b8bd9b35571aa2eac22","unresolved":false,"context_lines":[{"line_number":258,"context_line":"            for db_obj in bound_objects or ():"},{"line_number":259,"context_line":"                if db_api.get_object(self._context,"},{"line_number":260,"context_line":"                                     self.rbac_db_model,"},{"line_number":261,"context_line":"                                     target_tenant\u003ddb_obj.tenant_id):"},{"line_number":262,"context_line":"                    raise n_exc.InUse()"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":"    def update_shared(self, shared_new, bound_objects, obj_id):"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_0498f468","line":261,"in_reply_to":"5a5ae5dd_23e64b15","updated":"2016-02-08 16:01:54.000000000","message":"I guess yes. I think now it\u0027s ok, but won\u0027t be when we have more types of actions ?","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":259,"context_line":"                if db_api.get_object(self._context,"},{"line_number":260,"context_line":"                                     self.rbac_db_model,"},{"line_number":261,"context_line":"                                     target_tenant\u003ddb_obj.tenant_id):"},{"line_number":262,"context_line":"                    raise n_exc.InUse()"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":"    def update_shared(self, shared_new, bound_objects, obj_id):"},{"line_number":265,"context_line":"        shared_prev \u003d self._get_rbac_policies(self._context,"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_63b683fa","line":262,"updated":"2016-02-08 12:40:03.000000000","message":"Should we raise RbacPolicyInUse to match behaviour for networks?","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"d08687721f3ac76091cf0b8bd9b35571aa2eac22","unresolved":false,"context_lines":[{"line_number":259,"context_line":"                if db_api.get_object(self._context,"},{"line_number":260,"context_line":"                                     self.rbac_db_model,"},{"line_number":261,"context_line":"                                     target_tenant\u003ddb_obj.tenant_id):"},{"line_number":262,"context_line":"                    raise n_exc.InUse()"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":"    def update_shared(self, shared_new, bound_objects, obj_id):"},{"line_number":265,"context_line":"        shared_prev \u003d self._get_rbac_policies(self._context,"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_04aa3485","line":262,"in_reply_to":"5a5ae5dd_63b683fa","updated":"2016-02-08 16:01:54.000000000","message":"+1","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":259,"context_line":"                if db_api.get_object(self._context,"},{"line_number":260,"context_line":"                                     self.rbac_db_model,"},{"line_number":261,"context_line":"                                     target_tenant\u003ddb_obj.tenant_id):"},{"line_number":262,"context_line":"                    raise n_exc.InUse()"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":"    def update_shared(self, shared_new, bound_objects, obj_id):"},{"line_number":265,"context_line":"        shared_prev \u003d self._get_rbac_policies(self._context,"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_c6f9afca","line":262,"in_reply_to":"5a5ae5dd_63b683fa","updated":"2016-02-15 22:48:57.000000000","message":"Ditto","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":265,"context_line":"        shared_prev \u003d self._get_rbac_policies(self._context,"},{"line_number":266,"context_line":"                                              self.rbac_db_model, obj_id)"},{"line_number":267,"context_line":"        is_shared_prev \u003d bool(shared_prev)"},{"line_number":268,"context_line":"        if is_shared_prev \u003d\u003d shared_new:"},{"line_number":269,"context_line":"            return"},{"line_number":270,"context_line":""},{"line_number":271,"context_line":"        # \u0027sharing\u0027 goes False -\u003e True"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_a37a3b86","line":268,"updated":"2016-02-08 12:40:03.000000000","message":"IIUC _get_rbac_policies will return a list of any RBACs attached to the object. If a RBAC is not global (not *), then it\u0027s not probably right to consider that it will result in shared\u003dTrue on calculation.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":265,"context_line":"        shared_prev \u003d self._get_rbac_policies(self._context,"},{"line_number":266,"context_line":"                                              self.rbac_db_model, obj_id)"},{"line_number":267,"context_line":"        is_shared_prev \u003d bool(shared_prev)"},{"line_number":268,"context_line":"        if is_shared_prev \u003d\u003d shared_new:"},{"line_number":269,"context_line":"            return"},{"line_number":270,"context_line":""},{"line_number":271,"context_line":"        # \u0027sharing\u0027 goes False -\u003e True"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_4ae630b5","line":268,"in_reply_to":"5a5ae5dd_a37a3b86","updated":"2016-02-15 22:48:57.000000000","message":"the logic was fixed to handle \u0027shared\u0027 as globally shared on update.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":279,"context_line":"            if (entry.action \u003d\u003d models.ACCESS_SHARED and"},{"line_number":280,"context_line":"                    entry.target_tenant \u003d\u003d \u0027*\u0027):"},{"line_number":281,"context_line":"                return self._context.session.delete(entry)"},{"line_number":282,"context_line":"        raise n_exc.PolicyCheckError(policy\u003dobj_id, reason\u003d\u0027not shared\u0027)"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"    def update_post(self):"},{"line_number":285,"context_line":"        self.update_shared(self.shared,"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_03d54fe6","line":282,"updated":"2016-02-08 12:40:03.000000000","message":"I am not sure why we want to fail here: if I unshare the object twice, I don\u0027t want the 2nd attempt to fail, since the REST operation should be idempotent.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":279,"context_line":"            if (entry.action \u003d\u003d models.ACCESS_SHARED and"},{"line_number":280,"context_line":"                    entry.target_tenant \u003d\u003d \u0027*\u0027):"},{"line_number":281,"context_line":"                return self._context.session.delete(entry)"},{"line_number":282,"context_line":"        raise n_exc.PolicyCheckError(policy\u003dobj_id, reason\u003d\u0027not shared\u0027)"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"    def update_post(self):"},{"line_number":285,"context_line":"        self.update_shared(self.shared,"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_beadb08a","line":282,"in_reply_to":"5a5ae5dd_03d54fe6","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"d08687721f3ac76091cf0b8bd9b35571aa2eac22","unresolved":false,"context_lines":[{"line_number":279,"context_line":"            if (entry.action \u003d\u003d models.ACCESS_SHARED and"},{"line_number":280,"context_line":"                    entry.target_tenant \u003d\u003d \u0027*\u0027):"},{"line_number":281,"context_line":"                return self._context.session.delete(entry)"},{"line_number":282,"context_line":"        raise n_exc.PolicyCheckError(policy\u003dobj_id, reason\u003d\u0027not shared\u0027)"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"    def update_post(self):"},{"line_number":285,"context_line":"        self.update_shared(self.shared,"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_2485f0cd","line":282,"in_reply_to":"5a5ae5dd_03d54fe6","updated":"2016-02-08 16:01:54.000000000","message":"I agree, I think you can set a network as not shared twice, and it won\u0027t fail.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":281,"context_line":"                return self._context.session.delete(entry)"},{"line_number":282,"context_line":"        raise n_exc.PolicyCheckError(policy\u003dobj_id, reason\u003d\u0027not shared\u0027)"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"    def update_post(self):"},{"line_number":285,"context_line":"        self.update_shared(self.shared,"},{"line_number":286,"context_line":"                           self.get_bound_objects(self._context, self.id),"},{"line_number":287,"context_line":"                           self.id)"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_e3ecb3bc","line":284,"updated":"2016-02-08 12:40:03.000000000","message":"I think there is a more clean way to extend existing methods (see below).","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":309,"context_line":"        return dict_"},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"    @classmethod"},{"line_number":312,"context_line":"    def get_bound_objects(cls, context, obj_id):"},{"line_number":313,"context_line":"        # return all db bindings which are dependent on id"},{"line_number":314,"context_line":"        res \u003d []"},{"line_number":315,"context_line":"        for model in cls.binding_models.values():"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_a350fb32","line":312,"updated":"2016-02-08 12:40:03.000000000","message":"This method is qos policy specific (it relies on particular format for binding models). Probably belongs to somewhere else (or just its implementation).","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":309,"context_line":"        return dict_"},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"    @classmethod"},{"line_number":312,"context_line":"    def get_bound_objects(cls, context, obj_id):"},{"line_number":313,"context_line":"        # return all db bindings which are dependent on id"},{"line_number":314,"context_line":"        res \u003d []"},{"line_number":315,"context_line":"        for model in cls.binding_models.values():"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_46c75f12","line":312,"in_reply_to":"5a5ae5dd_a350fb32","updated":"2016-02-15 22:48:57.000000000","message":"Removed that tumor - it was the remains of my prev attempts to rewrite the rbac logic.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"d08687721f3ac76091cf0b8bd9b35571aa2eac22","unresolved":false,"context_lines":[{"line_number":314,"context_line":"        res \u003d []"},{"line_number":315,"context_line":"        for model in cls.binding_models.values():"},{"line_number":316,"context_line":"            for obj in db_api.get_objects(context, model,"},{"line_number":317,"context_line":"                                          policy_id\u003dobj_id):"},{"line_number":318,"context_line":"                res.append(obj)"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"        return res"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_c4289c9c","line":317,"range":{"start_line":317,"start_character":42,"end_line":317,"end_character":51},"updated":"2016-02-08 16:01:54.000000000","message":"I guess Ihar means that policy_id.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":314,"context_line":"        res \u003d []"},{"line_number":315,"context_line":"        for model in cls.binding_models.values():"},{"line_number":316,"context_line":"            for obj in db_api.get_objects(context, model,"},{"line_number":317,"context_line":"                                          policy_id\u003dobj_id):"},{"line_number":318,"context_line":"                res.append(obj)"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"        return res"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_26ccdb34","line":317,"range":{"start_line":317,"start_character":42,"end_line":317,"end_character":51},"in_reply_to":"5a5ae5dd_c4289c9c","updated":"2016-02-15 22:48:57.000000000","message":"Ditto","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"07f8140c3caf9072cc1ae3a86ccbc7d3ade2155b","unresolved":false,"context_lines":[{"line_number":329,"context_line":"    @classmethod"},{"line_number":330,"context_line":"    def _get_method(mcs, method_name, bases, dct):"},{"line_number":331,"context_line":"        for b in bases:"},{"line_number":332,"context_line":"            org_m \u003d getattr(b, method_name)"},{"line_number":333,"context_line":"            if org_m:"},{"line_number":334,"context_line":"                return org_m"},{"line_number":335,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_40180fd3","line":332,"range":{"start_line":332,"start_character":20,"end_line":332,"end_character":43},"updated":"2016-02-08 16:16:13.000000000","message":"Just looking at this from a pythonic standpoint. If the method doesn\u0027t exist, is the intent to have an AttributeError raised?  If not, this could be:\n\n    return getattr(b, method_name, None)","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":329,"context_line":"    @classmethod"},{"line_number":330,"context_line":"    def _get_method(mcs, method_name, bases, dct):"},{"line_number":331,"context_line":"        for b in bases:"},{"line_number":332,"context_line":"            org_m \u003d getattr(b, method_name)"},{"line_number":333,"context_line":"            if org_m:"},{"line_number":334,"context_line":"                return org_m"},{"line_number":335,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_3909ba2d","line":332,"range":{"start_line":332,"start_character":20,"end_line":332,"end_character":43},"in_reply_to":"5a5ae5dd_40180fd3","updated":"2016-02-15 22:48:57.000000000","message":"Yep, you\u0027re right - the idea was replacing of implemented CRUD methods, so raising AttributeError is a bad idea here. \nFixed.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":339,"context_line":"                mcs._get_method(method_name, bases, dct))"},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"    @classmethod"},{"line_number":342,"context_line":"    def replace_method(mcs, bases, dct, org_method, new_method):"},{"line_number":343,"context_line":"        \"\"\"Code replacement logic."},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"        The original method will be renamed with _orig suffix: e.g:"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_2aaf002b","line":342,"updated":"2016-02-08 12:40:03.000000000","message":"nit: org_method -\u003e orig_method","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"d08687721f3ac76091cf0b8bd9b35571aa2eac22","unresolved":false,"context_lines":[{"line_number":339,"context_line":"                mcs._get_method(method_name, bases, dct))"},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"    @classmethod"},{"line_number":342,"context_line":"    def replace_method(mcs, bases, dct, org_method, new_method):"},{"line_number":343,"context_line":"        \"\"\"Code replacement logic."},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"        The original method will be renamed with _orig suffix: e.g:"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_67052a0f","line":342,"in_reply_to":"5a5ae5dd_2aaf002b","updated":"2016-02-08 16:01:54.000000000","message":"+1","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":339,"context_line":"                mcs._get_method(method_name, bases, dct))"},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"    @classmethod"},{"line_number":342,"context_line":"    def replace_method(mcs, bases, dct, org_method, new_method):"},{"line_number":343,"context_line":"        \"\"\"Code replacement logic."},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"        The original method will be renamed with _orig suffix: e.g:"}],"source_content_type":"text/x-python","patch_set":14,"id":"3a57f1b5_e9986dc2","line":342,"in_reply_to":"5a5ae5dd_67052a0f","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":349,"context_line":"        - new_class.create() --\u003e RbacNeutronObject.create_hook()"},{"line_number":350,"context_line":"        - new_class.create_orig() --\u003e orig_class.create()."},{"line_number":351,"context_line":"        \"\"\""},{"line_number":352,"context_line":"        org \u003d mcs.get_method(org_method, bases, dct)"},{"line_number":353,"context_line":"        dct[org_method + \u0027_orig\u0027] \u003d org"},{"line_number":354,"context_line":"        dct[org_method] \u003d new_method"},{"line_number":355,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_a8953833","line":352,"updated":"2016-02-08 12:40:03.000000000","message":"nit: org -\u003e orig","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":349,"context_line":"        - new_class.create() --\u003e RbacNeutronObject.create_hook()"},{"line_number":350,"context_line":"        - new_class.create_orig() --\u003e orig_class.create()."},{"line_number":351,"context_line":"        \"\"\""},{"line_number":352,"context_line":"        org \u003d mcs.get_method(org_method, bases, dct)"},{"line_number":353,"context_line":"        dct[org_method + \u0027_orig\u0027] \u003d org"},{"line_number":354,"context_line":"        dct[org_method] \u003d new_method"},{"line_number":355,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"3a57f1b5_898f7929","line":352,"in_reply_to":"5a5ae5dd_a8953833","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":350,"context_line":"        - new_class.create_orig() --\u003e orig_class.create()."},{"line_number":351,"context_line":"        \"\"\""},{"line_number":352,"context_line":"        org \u003d mcs.get_method(org_method, bases, dct)"},{"line_number":353,"context_line":"        dct[org_method + \u0027_orig\u0027] \u003d org"},{"line_number":354,"context_line":"        dct[org_method] \u003d new_method"},{"line_number":355,"context_line":""},{"line_number":356,"context_line":"    def __new__(mcs, name, bases, dct):"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_48e7e4ab","line":353,"updated":"2016-02-08 12:40:03.000000000","message":"There is no reason to pollute the object with the backup method. You should instead pass the method into create_hook as an argument, and make create_hook to return a method for you that calls the passed callable + messes with RBACs.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":350,"context_line":"        - new_class.create_orig() --\u003e orig_class.create()."},{"line_number":351,"context_line":"        \"\"\""},{"line_number":352,"context_line":"        org \u003d mcs.get_method(org_method, bases, dct)"},{"line_number":353,"context_line":"        dct[org_method + \u0027_orig\u0027] \u003d org"},{"line_number":354,"context_line":"        dct[org_method] \u003d new_method"},{"line_number":355,"context_line":""},{"line_number":356,"context_line":"    def __new__(mcs, name, bases, dct):"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_0397f390","line":353,"in_reply_to":"5a5ae5dd_48e7e4ab","updated":"2016-02-15 22:48:57.000000000","message":"Not sure I completely understand how it can be accomplished.\nLets say I want to replace the NeutronDbObject.create(self) method with RbacNeutronDbObject.hook_create():\n\nclass RbacNeutronDbObject():\n  def hook_create(self, create_orig):\n    update_orig()\n    supplemental_logic()\n\nBut, since the original NeutronDbObject.create() takes only self as param,  the same function prototype needs to be kept in dct[\u0027create\u0027]. What am I missing here ?","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"d08687721f3ac76091cf0b8bd9b35571aa2eac22","unresolved":false,"context_lines":[{"line_number":359,"context_line":"        mcs.replace_method(bases, dct, \u0027to_dict\u0027,"},{"line_number":360,"context_line":"                           RbacNeutronObject.to_dict_hook)"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"        dct[\u0027synthetic_fields\u0027].append(\u0027shared\u0027)"},{"line_number":363,"context_line":"        cls \u003d type(name, (RbacNeutronObject,) + bases, dct)"},{"line_number":364,"context_line":""},{"line_number":365,"context_line":"        registry.subscribe(cls.validate_rbac_policy_delete,"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_07a47605","line":362,"range":{"start_line":362,"start_character":13,"end_line":362,"end_character":29},"updated":"2016-02-08 16:01:54.000000000","message":"It\u0027s not necessarily harsh to throw an exception if shared is already in the dict. It would be indicative that there\u0027s something really wrong with the code/use of this.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":359,"context_line":"        mcs.replace_method(bases, dct, \u0027to_dict\u0027,"},{"line_number":360,"context_line":"                           RbacNeutronObject.to_dict_hook)"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"        dct[\u0027synthetic_fields\u0027].append(\u0027shared\u0027)"},{"line_number":363,"context_line":"        cls \u003d type(name, (RbacNeutronObject,) + bases, dct)"},{"line_number":364,"context_line":""},{"line_number":365,"context_line":"        registry.subscribe(cls.validate_rbac_policy_delete,"}],"source_content_type":"text/x-python","patch_set":14,"id":"3a57f1b5_e9970d46","line":362,"range":{"start_line":362,"start_character":13,"end_line":362,"end_character":29},"in_reply_to":"5a5ae5dd_07a47605","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":335,"context_line":"    def _get_method(mcs, method_name, bases):"},{"line_number":336,"context_line":"        for b in bases:"},{"line_number":337,"context_line":"            orig_method \u003d getattr(b, method_name, None)"},{"line_number":338,"context_line":"            if orig_method:"},{"line_number":339,"context_line":"                return orig_method"},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"    @classmethod"},{"line_number":342,"context_line":"    def get_method(mcs, method_name, bases, dct):"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_2c13f6b9","line":339,"range":{"start_line":338,"start_character":12,"end_line":339,"end_character":34},"updated":"2016-02-16 10:19:33.000000000","message":"This block can be removed, since if orig_method is None (ie. \u0027if orig_method\u0027 will be False), None will be returned either way. This block doesn\u0027t do anything.","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"6e92863490e1beb8001bf52cbb7f30e747332393","unresolved":false,"context_lines":[{"line_number":335,"context_line":"    def _get_method(mcs, method_name, bases):"},{"line_number":336,"context_line":"        for b in bases:"},{"line_number":337,"context_line":"            orig_method \u003d getattr(b, method_name, None)"},{"line_number":338,"context_line":"            if orig_method:"},{"line_number":339,"context_line":"                return orig_method"},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"    @classmethod"},{"line_number":342,"context_line":"    def get_method(mcs, method_name, bases, dct):"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_c966ae28","line":339,"range":{"start_line":338,"start_character":12,"end_line":339,"end_character":34},"in_reply_to":"dae33548_2c13f6b9","updated":"2016-02-16 13:27:58.000000000","message":"I missed the fact that this is in a \u0027for\u0027 loop. I deeply apologize to any disturbances in the force I\u0027ve caused.","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":355,"context_line":"        - new_class.create_orig() --\u003e orig_class.create()."},{"line_number":356,"context_line":"        \"\"\""},{"line_number":357,"context_line":"        orig \u003d mcs.get_method(orig_method, bases, dct)"},{"line_number":358,"context_line":"        dct[orig_method + \u0027_orig\u0027] \u003d orig"},{"line_number":359,"context_line":"        dct[orig_method] \u003d new_method"},{"line_number":360,"context_line":""},{"line_number":361,"context_line":"    def __new__(mcs, name, bases, dct):"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_e71be919","line":358,"range":{"start_line":358,"start_character":8,"end_line":358,"end_character":11},"updated":"2016-02-16 10:19:33.000000000","message":"This class sports \u0027dct\u0027, whereas the above class sports \u0027dict_\u0027. Can we stick to only one convention in this file? :)","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":366,"context_line":"        mcs.replace_method(bases, dct, \u0027to_dict\u0027,"},{"line_number":367,"context_line":"                           RbacNeutronDbObject.to_dict_hook)"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"        if \u0027shared\u0027 in dct[\u0027synthetic_fields\u0027]:"},{"line_number":370,"context_line":"            raise n_exc.Conflict()"},{"line_number":371,"context_line":"        dct[\u0027synthetic_fields\u0027].append(\u0027shared\u0027)"},{"line_number":372,"context_line":"        cls \u003d type(name, (RbacNeutronDbObject,) + bases, dct)"},{"line_number":373,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_8c7322e7","line":370,"range":{"start_line":369,"start_character":8,"end_line":370,"end_character":34},"updated":"2016-02-16 10:19:33.000000000","message":"Input validation should be done before replace_method is called.","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"287128a1ccfccd3c5c3ab7a24be33762ac307426","unresolved":false,"context_lines":[{"line_number":53,"context_line":"            db_entry \u003d dbmodel(object_id\u003de[\u0027object_id\u0027],"},{"line_number":54,"context_line":"                               target_tenant\u003de[\u0027target_tenant\u0027],"},{"line_number":55,"context_line":"                               action\u003de[\u0027action\u0027],"},{"line_number":56,"context_line":"                               tenant_id\u003dcontext.tenant_id)"},{"line_number":57,"context_line":"            context.session.add(db_entry)"},{"line_number":58,"context_line":"        return self._make_rbac_policy_dict(db_entry)"},{"line_number":59,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"dae33548_476679ed","line":56,"updated":"2016-02-18 16:24:11.000000000","message":"why is this change? (IRC LOG):\n\n[16:38]  \u003chdaniel\u003e ajo: yeah\n[16:38]  \u003cajo\u003e why do you change e[\u0027tenant_id\u0027] to context.tenant_id ? \n[16:39]  \u003cajo\u003e you\u0027re changing the owner of the rbac entry from the rbac you\u0027re trying to create, to the creator doing the action?\n[16:39]  \u003chdaniel\u003e ajo: yeah, I think I saw that the client might send a \n[16:40]  \u003cajo\u003e hdaniel: but if you\u0027re the admin, I think you can specify an \"specific\" tenant ID for the objects you\u0027re creating\n[16:40]  \u003chdaniel\u003e ajo: and the owner of the rbac-policy, can\u0027t be change afaik\n[16:40]  \u003cajo\u003e hdaniel: ok, I\u0027d move that change out and discuss it with kevin if that sounds ok\n[16:40]  \u003chdaniel\u003e ajo: well, I\u0027m not sure that this code validates that\n[16:40]  \u003cajo\u003e it seems unrelated to your specific patch\n[16:40]  \u003chdaniel\u003e ajo: sure, np\n\n\nAgreement to move it to a different patch, and discuss with @kevin.","commit_id":"b6ed80c05295c90d28a470a1efdff9812e4841d1"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1097f292257ef5415579f0232ae721f0982a1e90","unresolved":false,"context_lines":[{"line_number":53,"context_line":"            db_entry \u003d dbmodel(object_id\u003de[\u0027object_id\u0027],"},{"line_number":54,"context_line":"                               target_tenant\u003de[\u0027target_tenant\u0027],"},{"line_number":55,"context_line":"                               action\u003de[\u0027action\u0027],"},{"line_number":56,"context_line":"                               tenant_id\u003dcontext.tenant_id)"},{"line_number":57,"context_line":"            context.session.add(db_entry)"},{"line_number":58,"context_line":"        return self._make_rbac_policy_dict(db_entry)"},{"line_number":59,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"dae33548_38b3940b","line":56,"in_reply_to":"dae33548_476679ed","updated":"2016-02-18 16:31:57.000000000","message":"my bad - found the problem in L282","commit_id":"b6ed80c05295c90d28a470a1efdff9812e4841d1"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"287128a1ccfccd3c5c3ab7a24be33762ac307426","unresolved":false,"context_lines":[{"line_number":229,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"},{"line_number":230,"context_line":"        if not target_tenant or target_tenant \u003d\u003d policy[\u0027tenant_id\u0027]:"},{"line_number":231,"context_line":"            return"},{"line_number":232,"context_line":"        return cls._validate_rbac_policy_delete(context\u003dcontext,"},{"line_number":233,"context_line":"                                                obj_id\u003dpolicy[\u0027object_id\u0027],"},{"line_number":234,"context_line":"                                                target_tenant\u003dtarget_tenant)"},{"line_number":235,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"dae33548_623f2bb4","line":232,"updated":"2016-02-18 16:24:11.000000000","message":"nit: return not necessary.","commit_id":"b6ed80c05295c90d28a470a1efdff9812e4841d1"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1097f292257ef5415579f0232ae721f0982a1e90","unresolved":false,"context_lines":[{"line_number":229,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"},{"line_number":230,"context_line":"        if not target_tenant or target_tenant \u003d\u003d policy[\u0027tenant_id\u0027]:"},{"line_number":231,"context_line":"            return"},{"line_number":232,"context_line":"        return cls._validate_rbac_policy_delete(context\u003dcontext,"},{"line_number":233,"context_line":"                                                obj_id\u003dpolicy[\u0027object_id\u0027],"},{"line_number":234,"context_line":"                                                target_tenant\u003dtarget_tenant)"},{"line_number":235,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"dae33548_d8a6e8bf","line":232,"in_reply_to":"dae33548_623f2bb4","updated":"2016-02-18 16:31:57.000000000","message":"Done","commit_id":"b6ed80c05295c90d28a470a1efdff9812e4841d1"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"287128a1ccfccd3c5c3ab7a24be33762ac307426","unresolved":false,"context_lines":[{"line_number":260,"context_line":"        # TODO(hdaniel): As this code was shamelesly stolen from"},{"line_number":261,"context_line":"        # NeutronDbPluginV2.validate_network_rbac_policy_change(), those pieces"},{"line_number":262,"context_line":"        # should be synced and contain the same bugs, until Network RBAC logic"},{"line_number":263,"context_line":"        # (hopefully) melded with this one."},{"line_number":264,"context_line":"        if object_type !\u003d cls.rbac_db_model.object_type:"},{"line_number":265,"context_line":"            return"},{"line_number":266,"context_line":"        db_obj \u003d cls.get_by_id(context.elevated(), policy[\u0027object_id\u0027])"}],"source_content_type":"text/x-python","patch_set":19,"id":"dae33548_226fe3fc","line":263,"updated":"2016-02-18 16:24:11.000000000","message":"fair :)","commit_id":"b6ed80c05295c90d28a470a1efdff9812e4841d1"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"287128a1ccfccd3c5c3ab7a24be33762ac307426","unresolved":false,"context_lines":[{"line_number":359,"context_line":"        - new_class.create_orig() --\u003e orig_class.create()."},{"line_number":360,"context_line":"        \"\"\""},{"line_number":361,"context_line":"        orig \u003d mcs.get_attribute(orig_method_name, bases, dct)"},{"line_number":362,"context_line":"        dct[orig_method_name + \u0027_orig\u0027] \u003d orig"},{"line_number":363,"context_line":"        dct[orig_method_name] \u003d new_method"},{"line_number":364,"context_line":""},{"line_number":365,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":19,"id":"dae33548_bd195624","line":362,"updated":"2016-02-18 16:24:11.000000000","message":"comment about pollution in PS14 not addressed, but I\u0027m ok with it. We could enhance it in the future.","commit_id":"b6ed80c05295c90d28a470a1efdff9812e4841d1"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1097f292257ef5415579f0232ae721f0982a1e90","unresolved":false,"context_lines":[{"line_number":359,"context_line":"        - new_class.create_orig() --\u003e orig_class.create()."},{"line_number":360,"context_line":"        \"\"\""},{"line_number":361,"context_line":"        orig \u003d mcs.get_attribute(orig_method_name, bases, dct)"},{"line_number":362,"context_line":"        dct[orig_method_name + \u0027_orig\u0027] \u003d orig"},{"line_number":363,"context_line":"        dct[orig_method_name] \u003d new_method"},{"line_number":364,"context_line":""},{"line_number":365,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":19,"id":"dae33548_d8e268d4","line":362,"in_reply_to":"dae33548_bd195624","updated":"2016-02-18 16:31:57.000000000","message":"I replied to that:\n\"Not sure I completely understand how it can be accomplished.\nLets say I want to replace the NeutronDbObject.create(self) method with RbacNeutronDbObject.hook_create():\nclass RbacNeutronDbObject():\n  def hook_create(self, create_orig):\n    update_orig()\n    supplemental_logic()\nBut, since the original NeutronDbObject.create() takes only self as param,  the same function prototype needs to be kept in dct[\u0027create\u0027]. What am I missing here ?\"","commit_id":"b6ed80c05295c90d28a470a1efdff9812e4841d1"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"43692432664930055c6eb0edab6b6e4219eb701f","unresolved":false,"context_lines":[{"line_number":359,"context_line":"        - new_class.create_orig() --\u003e orig_class.create()."},{"line_number":360,"context_line":"        \"\"\""},{"line_number":361,"context_line":"        orig \u003d mcs.get_attribute(orig_method_name, bases, dct)"},{"line_number":362,"context_line":"        dct[orig_method_name + \u0027_orig\u0027] \u003d orig"},{"line_number":363,"context_line":"        dct[orig_method_name] \u003d new_method"},{"line_number":364,"context_line":""},{"line_number":365,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":19,"id":"bae84128_5541e638","line":362,"in_reply_to":"dae33548_d8e268d4","updated":"2016-02-19 10:49:00.000000000","message":"You could store the _orig method in a separate dictionary inside the class, for example.\n\nSo you have the class\n\nMyClass._orig_methods[\u0027orig_name\u0027]\u003dfunction\n\nand then you call it via that dict. But this is bike shedding, I don\u0027t see any issue with adding the extra methods.","commit_id":"b6ed80c05295c90d28a470a1efdff9812e4841d1"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"a51056aa217fb67b6cf21cd7e1de19b6d7886136","unresolved":false,"context_lines":[{"line_number":255,"context_line":""},{"line_number":256,"context_line":"        This is the dispatching function for create, update and delete"},{"line_number":257,"context_line":"        callbacks. On creation and update, verify that the creator is an admin"},{"line_number":258,"context_line":"        or that he owns the resource being shared."},{"line_number":259,"context_line":"        \"\"\""},{"line_number":260,"context_line":"        # TODO(hdaniel): As this code was shamelesly stolen from"},{"line_number":261,"context_line":"        # NeutronDbPluginV2.validate_network_rbac_policy_change(), those pieces"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_06372cb1","line":258,"range":{"start_line":258,"start_character":11,"end_line":258,"end_character":18},"updated":"2016-02-19 14:29:26.000000000","message":"nit: remove \"that he\" so you are politically correct :)","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"57b0d348fb5c654912c0fe78279702c327042ec7","unresolved":false,"context_lines":[{"line_number":255,"context_line":""},{"line_number":256,"context_line":"        This is the dispatching function for create, update and delete"},{"line_number":257,"context_line":"        callbacks. On creation and update, verify that the creator is an admin"},{"line_number":258,"context_line":"        or that he owns the resource being shared."},{"line_number":259,"context_line":"        \"\"\""},{"line_number":260,"context_line":"        # TODO(hdaniel): As this code was shamelesly stolen from"},{"line_number":261,"context_line":"        # NeutronDbPluginV2.validate_network_rbac_policy_change(), those pieces"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_7cb044de","line":258,"range":{"start_line":258,"start_character":11,"end_line":258,"end_character":18},"in_reply_to":"bae84128_06372cb1","updated":"2016-02-19 16:14:34.000000000","message":"Done","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"92c39525ea637d28f5dbbc536926e3754ec0a30b","unresolved":false,"context_lines":[{"line_number":356,"context_line":"        for replace_method(org_method\u003d\u0027create\u0027,"},{"line_number":357,"context_line":"                           new_method\u003dRbacNeutronObject.create_hook),"},{"line_number":358,"context_line":"        the resulting new_class will have the following set up:"},{"line_number":359,"context_line":"        - new_class.create() --\u003e RbacNeutronObject.create_hook()"},{"line_number":360,"context_line":"        - new_class.create_orig() --\u003e orig_class.create()."},{"line_number":361,"context_line":"        \"\"\""},{"line_number":362,"context_line":"        orig \u003d mcs.get_attribute(orig_method_name, bases, dct)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_b58cb236","line":359,"range":{"start_line":359,"start_character":33,"end_line":359,"end_character":50},"updated":"2016-02-19 12:07:51.000000000","message":"nit-stupid-comment: I\u0027d invert the arrow \u003c--\n\nOnly address if you agree it\u0027s clearer and if you need to respin for any reason.","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"f3145b06d332ae18603f5e72a2fe4ac51ef96a56","unresolved":false,"context_lines":[{"line_number":356,"context_line":"        for replace_method(org_method\u003d\u0027create\u0027,"},{"line_number":357,"context_line":"                           new_method\u003dRbacNeutronObject.create_hook),"},{"line_number":358,"context_line":"        the resulting new_class will have the following set up:"},{"line_number":359,"context_line":"        - new_class.create() --\u003e RbacNeutronObject.create_hook()"},{"line_number":360,"context_line":"        - new_class.create_orig() --\u003e orig_class.create()."},{"line_number":361,"context_line":"        \"\"\""},{"line_number":362,"context_line":"        orig \u003d mcs.get_attribute(orig_method_name, bases, dct)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_b1583f58","line":359,"range":{"start_line":359,"start_character":33,"end_line":359,"end_character":50},"in_reply_to":"bae84128_b58cb236","updated":"2016-02-19 13:00:46.000000000","message":"I meant the arrow to be an address pointer (C like), what do you mean by reversing it ?","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"593b66178030b97f5f45d0daf68b36ec515cc684","unresolved":false,"context_lines":[{"line_number":370,"context_line":"            dct[\u0027synthetic_fields\u0027] \u003d synthetic_attr or []"},{"line_number":371,"context_line":"        if \u0027shared\u0027 in dct[\u0027synthetic_fields\u0027]:"},{"line_number":372,"context_line":"            raise n_exc.ObjectActionError("},{"line_number":373,"context_line":"                action\u003d\u0027shared property switching to synthetic\u0027,"},{"line_number":374,"context_line":"                reason\u003d\u0027already a synthetic attribute\u0027)"},{"line_number":375,"context_line":"        dct[\u0027synthetic_fields\u0027].append(\u0027shared\u0027)"},{"line_number":376,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_3364f720","line":373,"updated":"2016-02-21 10:28:59.000000000","message":"missing translations","commit_id":"2aab0cd1cda881dbdadeb6e923f373675f889489"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"14b8a9553977b4ba56a43f5dfb276912b8fa97c7","unresolved":false,"context_lines":[{"line_number":370,"context_line":"            dct[\u0027synthetic_fields\u0027] \u003d synthetic_attr or []"},{"line_number":371,"context_line":"        if \u0027shared\u0027 in dct[\u0027synthetic_fields\u0027]:"},{"line_number":372,"context_line":"            raise n_exc.ObjectActionError("},{"line_number":373,"context_line":"                action\u003d\u0027shared property switching to synthetic\u0027,"},{"line_number":374,"context_line":"                reason\u003d\u0027already a synthetic attribute\u0027)"},{"line_number":375,"context_line":"        dct[\u0027synthetic_fields\u0027].append(\u0027shared\u0027)"},{"line_number":376,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_cee36432","line":373,"in_reply_to":"bae84128_3364f720","updated":"2016-02-21 11:06:33.000000000","message":"Done","commit_id":"2aab0cd1cda881dbdadeb6e923f373675f889489"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"593b66178030b97f5f45d0daf68b36ec515cc684","unresolved":false,"context_lines":[{"line_number":371,"context_line":"        if \u0027shared\u0027 in dct[\u0027synthetic_fields\u0027]:"},{"line_number":372,"context_line":"            raise n_exc.ObjectActionError("},{"line_number":373,"context_line":"                action\u003d\u0027shared property switching to synthetic\u0027,"},{"line_number":374,"context_line":"                reason\u003d\u0027already a synthetic attribute\u0027)"},{"line_number":375,"context_line":"        dct[\u0027synthetic_fields\u0027].append(\u0027shared\u0027)"},{"line_number":376,"context_line":""},{"line_number":377,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_13673326","line":374,"updated":"2016-02-21 10:28:59.000000000","message":"ditto","commit_id":"2aab0cd1cda881dbdadeb6e923f373675f889489"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"14b8a9553977b4ba56a43f5dfb276912b8fa97c7","unresolved":false,"context_lines":[{"line_number":371,"context_line":"        if \u0027shared\u0027 in dct[\u0027synthetic_fields\u0027]:"},{"line_number":372,"context_line":"            raise n_exc.ObjectActionError("},{"line_number":373,"context_line":"                action\u003d\u0027shared property switching to synthetic\u0027,"},{"line_number":374,"context_line":"                reason\u003d\u0027already a synthetic attribute\u0027)"},{"line_number":375,"context_line":"        dct[\u0027synthetic_fields\u0027].append(\u0027shared\u0027)"},{"line_number":376,"context_line":""},{"line_number":377,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_2ed13058","line":374,"in_reply_to":"bae84128_13673326","updated":"2016-02-21 11:06:33.000000000","message":"Done","commit_id":"2aab0cd1cda881dbdadeb6e923f373675f889489"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"593b66178030b97f5f45d0daf68b36ec515cc684","unresolved":false,"context_lines":[{"line_number":392,"context_line":"    @classmethod"},{"line_number":393,"context_line":"    def validate_existing_attrs(mcs, cls_name, dct):"},{"line_number":394,"context_line":"        if \u0027shared\u0027 not in dct[\u0027fields\u0027]:"},{"line_number":395,"context_line":"            raise KeyError(\u0027No shared key in fields for {}\u0027.format(cls_name))"},{"line_number":396,"context_line":"        if \u0027rbac_db_model\u0027 not in dct:"},{"line_number":397,"context_line":"            raise AttributeError("},{"line_number":398,"context_line":"                \u0027rbac_db_model not found in {}\u0027.format(cls_name))"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_5371bbdf","line":395,"updated":"2016-02-21 10:28:59.000000000","message":"missing translations","commit_id":"2aab0cd1cda881dbdadeb6e923f373675f889489"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"14b8a9553977b4ba56a43f5dfb276912b8fa97c7","unresolved":false,"context_lines":[{"line_number":392,"context_line":"    @classmethod"},{"line_number":393,"context_line":"    def validate_existing_attrs(mcs, cls_name, dct):"},{"line_number":394,"context_line":"        if \u0027shared\u0027 not in dct[\u0027fields\u0027]:"},{"line_number":395,"context_line":"            raise KeyError(\u0027No shared key in fields for {}\u0027.format(cls_name))"},{"line_number":396,"context_line":"        if \u0027rbac_db_model\u0027 not in dct:"},{"line_number":397,"context_line":"            raise AttributeError("},{"line_number":398,"context_line":"                \u0027rbac_db_model not found in {}\u0027.format(cls_name))"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_2eead00f","line":395,"in_reply_to":"bae84128_5371bbdf","updated":"2016-02-21 11:06:33.000000000","message":"Done","commit_id":"2aab0cd1cda881dbdadeb6e923f373675f889489"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"593b66178030b97f5f45d0daf68b36ec515cc684","unresolved":false,"context_lines":[{"line_number":395,"context_line":"            raise KeyError(\u0027No shared key in fields for {}\u0027.format(cls_name))"},{"line_number":396,"context_line":"        if \u0027rbac_db_model\u0027 not in dct:"},{"line_number":397,"context_line":"            raise AttributeError("},{"line_number":398,"context_line":"                \u0027rbac_db_model not found in {}\u0027.format(cls_name))"},{"line_number":399,"context_line":""},{"line_number":400,"context_line":"    def __new__(mcs, name, bases, dct):"},{"line_number":401,"context_line":"        mcs.validate_existing_attrs(name, dct)"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_b37807c6","line":398,"updated":"2016-02-21 10:28:59.000000000","message":"ditto","commit_id":"2aab0cd1cda881dbdadeb6e923f373675f889489"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"14b8a9553977b4ba56a43f5dfb276912b8fa97c7","unresolved":false,"context_lines":[{"line_number":395,"context_line":"            raise KeyError(\u0027No shared key in fields for {}\u0027.format(cls_name))"},{"line_number":396,"context_line":"        if \u0027rbac_db_model\u0027 not in dct:"},{"line_number":397,"context_line":"            raise AttributeError("},{"line_number":398,"context_line":"                \u0027rbac_db_model not found in {}\u0027.format(cls_name))"},{"line_number":399,"context_line":""},{"line_number":400,"context_line":"    def __new__(mcs, name, bases, dct):"},{"line_number":401,"context_line":"        mcs.validate_existing_attrs(name, dct)"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_0eed4c25","line":398,"in_reply_to":"bae84128_b37807c6","updated":"2016-02-21 11:06:33.000000000","message":"Done","commit_id":"2aab0cd1cda881dbdadeb6e923f373675f889489"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"639aea60ae3b8e94018d3c2c3cf8e53c322b7b9f","unresolved":false,"context_lines":[{"line_number":146,"context_line":""},{"line_number":147,"context_line":"    @classmethod"},{"line_number":148,"context_line":"    @abc.abstractmethod"},{"line_number":149,"context_line":"    def get_bound_tenant_ids(cls, context, obj_id):"},{"line_number":150,"context_line":"        \"\"\"Returns ids of all tenants depending on this db object."},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"        Has to be implemented by classes using RbacNeutronMetaclass."}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_84cadb6c","line":149,"updated":"2016-02-21 14:02:14.000000000","message":"this will depend on the action. (e.g. a tenant can be attached to a network with a router, but not a VM port, therefore it is bound in the \u0027external\u0027 context, but not in the \u0027shared\u0027 context.","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8372896716c3d1fa70e7be6ddc7e8f189bf9380f","unresolved":false,"context_lines":[{"line_number":146,"context_line":""},{"line_number":147,"context_line":"    @classmethod"},{"line_number":148,"context_line":"    @abc.abstractmethod"},{"line_number":149,"context_line":"    def get_bound_tenant_ids(cls, context, obj_id):"},{"line_number":150,"context_line":"        \"\"\"Returns ids of all tenants depending on this db object."},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"        Has to be implemented by classes using RbacNeutronMetaclass."}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_c0bde1d8","line":149,"in_reply_to":"bae84128_84cadb6c","updated":"2016-02-22 10:16:52.000000000","message":"will renaming that to \u0027get_bound_shared_tenant_ids\u0027 do better ?","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"639aea60ae3b8e94018d3c2c3cf8e53c322b7b9f","unresolved":false,"context_lines":[{"line_number":159,"context_line":"        pass"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"    @classmethod"},{"line_number":162,"context_line":"    def _get_rbac_policies(cls, context, rbac_db_model, obj_id):"},{"line_number":163,"context_line":"        admin_context \u003d context.elevated()"},{"line_number":164,"context_line":"        return db_api.get_objects(admin_context, rbac_db_model,"},{"line_number":165,"context_line":"                                  object_id\u003dobj_id)"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_e4c9277a","line":162,"updated":"2016-02-21 14:02:14.000000000","message":"why does rbac_db_model need to be passed in when it is bound to the class already?","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8372896716c3d1fa70e7be6ddc7e8f189bf9380f","unresolved":false,"context_lines":[{"line_number":159,"context_line":"        pass"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"    @classmethod"},{"line_number":162,"context_line":"    def _get_rbac_policies(cls, context, rbac_db_model, obj_id):"},{"line_number":163,"context_line":"        admin_context \u003d context.elevated()"},{"line_number":164,"context_line":"        return db_api.get_objects(admin_context, rbac_db_model,"},{"line_number":165,"context_line":"                                  object_id\u003dobj_id)"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_e512b7b3","line":162,"in_reply_to":"bae84128_e4c9277a","updated":"2016-02-22 10:16:52.000000000","message":"actually this function was unused, so it got the axe.","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"639aea60ae3b8e94018d3c2c3cf8e53c322b7b9f","unresolved":false,"context_lines":[{"line_number":165,"context_line":"                                  object_id\u003dobj_id)"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    @classmethod"},{"line_number":168,"context_line":"    def is_shared_with_tenant(cls, context, rbac_db_model, obj_id, tenant_id):"},{"line_number":169,"context_line":"        ctx \u003d context.elevated()"},{"line_number":170,"context_line":"        with ctx.session.begin(subtransactions\u003dTrue):"},{"line_number":171,"context_line":"            return (common_db_mixin.model_query(ctx, rbac_db_model).filter("}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_c4c4e360","line":168,"updated":"2016-02-21 14:02:14.000000000","message":"This is specific to the shared action. Shouldn\u0027t it be more generic like \"can_tenant_perform_action\" and take the action in question as a param?","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8372896716c3d1fa70e7be6ddc7e8f189bf9380f","unresolved":false,"context_lines":[{"line_number":165,"context_line":"                                  object_id\u003dobj_id)"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    @classmethod"},{"line_number":168,"context_line":"    def is_shared_with_tenant(cls, context, rbac_db_model, obj_id, tenant_id):"},{"line_number":169,"context_line":"        ctx \u003d context.elevated()"},{"line_number":170,"context_line":"        with ctx.session.begin(subtransactions\u003dTrue):"},{"line_number":171,"context_line":"            return (common_db_mixin.model_query(ctx, rbac_db_model).filter("}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_45d723bf","line":168,"in_reply_to":"bae84128_c4c4e360","updated":"2016-02-22 10:16:52.000000000","message":"As there are two actions, and rbac supporting only one of them (access_as_shared),IMHO this seems like an overkill - the code can always be extended upon need.","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"639aea60ae3b8e94018d3c2c3cf8e53c322b7b9f","unresolved":false,"context_lines":[{"line_number":175,"context_line":"                         [\u0027*\u0027, tenant_id]))).count() !\u003d 0)"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    @classmethod"},{"line_number":178,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":179,"context_line":"        return (context.is_admin or"},{"line_number":180,"context_line":"                context.tenant_id \u003d\u003d db_obj.tenant_id or"},{"line_number":181,"context_line":"                cls.is_shared_with_tenant(context, cls.rbac_db_model,"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_24a2efae","line":178,"updated":"2016-02-21 14:02:14.000000000","message":"might want to avoid binding this generic name to just \u0027shared\u0027 as well since this logic just defines how shared networks work.","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8372896716c3d1fa70e7be6ddc7e8f189bf9380f","unresolved":false,"context_lines":[{"line_number":175,"context_line":"                         [\u0027*\u0027, tenant_id]))).count() !\u003d 0)"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    @classmethod"},{"line_number":178,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":179,"context_line":"        return (context.is_admin or"},{"line_number":180,"context_line":"                context.tenant_id \u003d\u003d db_obj.tenant_id or"},{"line_number":181,"context_line":"                cls.is_shared_with_tenant(context, cls.rbac_db_model,"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_65034743","line":178,"in_reply_to":"bae84128_24a2efae","updated":"2016-02-22 10:16:52.000000000","message":"Done","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"af4187b51886f4c897d3f895867de0b0a27efed1","unresolved":false,"context_lines":[{"line_number":175,"context_line":"                         [\u0027*\u0027, tenant_id]))).count() !\u003d 0)"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    @classmethod"},{"line_number":178,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":179,"context_line":"        return (context.is_admin or"},{"line_number":180,"context_line":"                context.tenant_id \u003d\u003d db_obj.tenant_id or"},{"line_number":181,"context_line":"                cls.is_shared_with_tenant(context, cls.rbac_db_model,"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_ce2a2b2c","line":178,"in_reply_to":"bae84128_65034743","updated":"2016-02-22 10:50:49.000000000","message":"Hmm, but context.is_admin would not mean the object is shared. Just that it\u0027s accessible (because you\u0027re admin)   or you\u0027re the owner (context.tenant_id \u003d\u003d db_obj-tenant_id).\n\nIMO is_accessible seems more correct that \"shared\".\n\nIn fact \"shared\" as  a method name for this would seem misleading.","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"19e2c1ad6d82319205cc11cb9f0d4fd491c1f668","unresolved":false,"context_lines":[{"line_number":175,"context_line":"                         [\u0027*\u0027, tenant_id]))).count() !\u003d 0)"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    @classmethod"},{"line_number":178,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":179,"context_line":"        return (context.is_admin or"},{"line_number":180,"context_line":"                context.tenant_id \u003d\u003d db_obj.tenant_id or"},{"line_number":181,"context_line":"                cls.is_shared_with_tenant(context, cls.rbac_db_model,"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_8feada0d","line":178,"in_reply_to":"bae84128_ce2a2b2c","updated":"2016-02-22 15:53:49.000000000","message":"Come to think about it - I agree with @ajo.","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"639aea60ae3b8e94018d3c2c3cf8e53c322b7b9f","unresolved":false,"context_lines":[{"line_number":182,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    @staticmethod"},{"line_number":185,"context_line":"    def _get_rbac_target_tenants(context, rbac_db_model, obj_id):"},{"line_number":186,"context_line":"        return common_db_mixin.model_query(context, rbac_db_model).filter("},{"line_number":187,"context_line":"            and_(rbac_db_model.object_id \u003d\u003d obj_id,"},{"line_number":188,"context_line":"                 rbac_db_model.action \u003d\u003d models.ACCESS_SHARED))"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_04a52bb4","line":185,"updated":"2016-02-21 14:02:14.000000000","message":"_get_rbac_shared_target tenants or have it take the action as a param","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8372896716c3d1fa70e7be6ddc7e8f189bf9380f","unresolved":false,"context_lines":[{"line_number":182,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    @staticmethod"},{"line_number":185,"context_line":"    def _get_rbac_target_tenants(context, rbac_db_model, obj_id):"},{"line_number":186,"context_line":"        return common_db_mixin.model_query(context, rbac_db_model).filter("},{"line_number":187,"context_line":"            and_(rbac_db_model.object_id \u003d\u003d obj_id,"},{"line_number":188,"context_line":"                 rbac_db_model.action \u003d\u003d models.ACCESS_SHARED))"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_65b1878f","line":185,"in_reply_to":"bae84128_04a52bb4","updated":"2016-02-22 10:16:52.000000000","message":"Done - renamed","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"a7d6c99346c1095a8b4403d80a46eba852d4328f","unresolved":false,"context_lines":[{"line_number":196,"context_line":"                                                            rb_model, obj_id)"},{"line_number":197,"context_line":"        if target_tenant !\u003d \u0027*\u0027:"},{"line_number":198,"context_line":"            # if there is a wildcard rule, we can return early because it"},{"line_number":199,"context_line":"            # shares the object globally"},{"line_number":200,"context_line":"            other_target_tenants \u003d other_target_tenants.filter("},{"line_number":201,"context_line":"                rb_model.target_tenant \u003d\u003d \u0027*\u0027)"},{"line_number":202,"context_line":"            if other_target_tenants.count():"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_3f1c6ec0","line":199,"updated":"2016-02-23 09:10:15.000000000","message":"another nit, can you move that on the if of L202 ? , otherwise it seems this is a comment for the if in 197","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"32db2cfd82ae97a403afbdff59a4eecefce6514a","unresolved":false,"context_lines":[{"line_number":196,"context_line":"                                                            rb_model, obj_id)"},{"line_number":197,"context_line":"        if target_tenant !\u003d \u0027*\u0027:"},{"line_number":198,"context_line":"            # if there is a wildcard rule, we can return early because it"},{"line_number":199,"context_line":"            # shares the object globally"},{"line_number":200,"context_line":"            other_target_tenants \u003d other_target_tenants.filter("},{"line_number":201,"context_line":"                rb_model.target_tenant \u003d\u003d \u0027*\u0027)"},{"line_number":202,"context_line":"            if other_target_tenants.count():"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_bd29a639","line":199,"in_reply_to":"bae84128_3f1c6ec0","updated":"2016-02-23 09:42:33.000000000","message":"As this comments refers to L200 - it\u0027s a keeper, but combined with the L200 comment fix the readability will be improved.","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"a7d6c99346c1095a8b4403d80a46eba852d4328f","unresolved":false,"context_lines":[{"line_number":197,"context_line":"        if target_tenant !\u003d \u0027*\u0027:"},{"line_number":198,"context_line":"            # if there is a wildcard rule, we can return early because it"},{"line_number":199,"context_line":"            # shares the object globally"},{"line_number":200,"context_line":"            other_target_tenants \u003d other_target_tenants.filter("},{"line_number":201,"context_line":"                rb_model.target_tenant \u003d\u003d \u0027*\u0027)"},{"line_number":202,"context_line":"            if other_target_tenants.count():"},{"line_number":203,"context_line":"                return"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_df33c260","line":200,"updated":"2016-02-23 09:10:15.000000000","message":"super-nit: can you change here?:\n\n   wildcard_tenants \u003d other_target_tenants.filter(....)\n   if wildcard_tenants.count(): ...\n\nIt will make understanding the code easier.","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"32db2cfd82ae97a403afbdff59a4eecefce6514a","unresolved":false,"context_lines":[{"line_number":197,"context_line":"        if target_tenant !\u003d \u0027*\u0027:"},{"line_number":198,"context_line":"            # if there is a wildcard rule, we can return early because it"},{"line_number":199,"context_line":"            # shares the object globally"},{"line_number":200,"context_line":"            other_target_tenants \u003d other_target_tenants.filter("},{"line_number":201,"context_line":"                rb_model.target_tenant \u003d\u003d \u0027*\u0027)"},{"line_number":202,"context_line":"            if other_target_tenants.count():"},{"line_number":203,"context_line":"                return"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_7f1f166c","line":200,"in_reply_to":"bae84128_df33c260","updated":"2016-02-23 09:42:33.000000000","message":"Done","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"639aea60ae3b8e94018d3c2c3cf8e53c322b7b9f","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        if policy[\u0027action\u0027] !\u003d models.ACCESS_SHARED:"},{"line_number":228,"context_line":"            return"},{"line_number":229,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"},{"line_number":230,"context_line":"        if not target_tenant or target_tenant \u003d\u003d policy[\u0027tenant_id\u0027]:"},{"line_number":231,"context_line":"            return"},{"line_number":232,"context_line":"        cls._validate_rbac_policy_delete(context\u003dcontext,"},{"line_number":233,"context_line":"                                         obj_id\u003dpolicy[\u0027object_id\u0027],"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_64acf7a0","line":230,"updated":"2016-02-21 14:02:14.000000000","message":"why does the owner of the policy get special treatment in this regard? If the owner has resources that depend on the policy, I\u0027m not sure we should be allowing it to be removed.","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"32db2cfd82ae97a403afbdff59a4eecefce6514a","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        if policy[\u0027action\u0027] !\u003d models.ACCESS_SHARED:"},{"line_number":228,"context_line":"            return"},{"line_number":229,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"},{"line_number":230,"context_line":"        if not target_tenant or target_tenant \u003d\u003d policy[\u0027tenant_id\u0027]:"},{"line_number":231,"context_line":"            return"},{"line_number":232,"context_line":"        cls._validate_rbac_policy_delete(context\u003dcontext,"},{"line_number":233,"context_line":"                                         obj_id\u003dpolicy[\u0027object_id\u0027],"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_9dd2e25a","line":230,"in_reply_to":"bae84128_2ea597a1","updated":"2016-02-23 09:42:33.000000000","message":"Ok, I see the problem now - I\u0027ve treated the policy owner as the object owner - which was clearly wrong. Fixed it in PS24","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"af4187b51886f4c897d3f895867de0b0a27efed1","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        if policy[\u0027action\u0027] !\u003d models.ACCESS_SHARED:"},{"line_number":228,"context_line":"            return"},{"line_number":229,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"},{"line_number":230,"context_line":"        if not target_tenant or target_tenant \u003d\u003d policy[\u0027tenant_id\u0027]:"},{"line_number":231,"context_line":"            return"},{"line_number":232,"context_line":"        cls._validate_rbac_policy_delete(context\u003dcontext,"},{"line_number":233,"context_line":"                                         obj_id\u003dpolicy[\u0027object_id\u0027],"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_2ea597a1","line":230,"in_reply_to":"bae84128_5b21c24c","updated":"2016-02-22 10:50:49.000000000","message":"One thing is being owner of the policy, and other being owner of the objects. (admin I guess could be owner of the policy, but not of the objects),  still wouldn\u0027t the admin be able to access the objects yet?","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8372896716c3d1fa70e7be6ddc7e8f189bf9380f","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        if policy[\u0027action\u0027] !\u003d models.ACCESS_SHARED:"},{"line_number":228,"context_line":"            return"},{"line_number":229,"context_line":"        target_tenant \u003d policy.get(\u0027target_tenant\u0027, None)"},{"line_number":230,"context_line":"        if not target_tenant or target_tenant \u003d\u003d policy[\u0027tenant_id\u0027]:"},{"line_number":231,"context_line":"            return"},{"line_number":232,"context_line":"        cls._validate_rbac_policy_delete(context\u003dcontext,"},{"line_number":233,"context_line":"                                         obj_id\u003dpolicy[\u0027object_id\u0027],"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_5b21c24c","line":230,"in_reply_to":"bae84128_64acf7a0","updated":"2016-02-22 10:16:52.000000000","message":"If the owner .. well owns the resources, wouldn\u0027t they remain visible to him after the removal of the policy ? The thought here was \u0027if I own the objects, then the policy removal won\u0027t matter\u0027. Am I missing some corner case here ?","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"639aea60ae3b8e94018d3c2c3cf8e53c322b7b9f","unresolved":false,"context_lines":[{"line_number":330,"context_line":"        return dct"},{"line_number":331,"context_line":""},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"class RbacNeutronMetaclass(type):"},{"line_number":334,"context_line":"    \"\"\"Adds support for RBAC in NeutronDbObjects."},{"line_number":335,"context_line":""},{"line_number":336,"context_line":"    Injects code for CRUD operations and modifies existing ops to do so."}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_44af3394","line":333,"updated":"2016-02-21 14:02:14.000000000","message":"Can you compare between this approach to just using a few explicit decorators on the create/update/to_dict methods of the objects that want to use this?\n\nOne of the issues with metaclasses that dynamically move around functions is that this approach doesn\u0027t stack well. Imagine you have two metaclasses that move functions to func_name + \u0027_orig\u0027. Now whichever one patches second will destroy the reference to the actual original function with the reference to the first patched in one. Then when you call it you get infinite recursion: http://paste.openstack.org/show/487695/\n\nI suspect we will lose docstrings on the original functions as well since we don\u0027t have the equivalent logic of functools.wraps. This isn\u0027t as big of an issue unless you look at function docs inside of the debugger.","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"19e2c1ad6d82319205cc11cb9f0d4fd491c1f668","unresolved":false,"context_lines":[{"line_number":330,"context_line":"        return dct"},{"line_number":331,"context_line":""},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"class RbacNeutronMetaclass(type):"},{"line_number":334,"context_line":"    \"\"\"Adds support for RBAC in NeutronDbObjects."},{"line_number":335,"context_line":""},{"line_number":336,"context_line":"    Injects code for CRUD operations and modifies existing ops to do so."}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_d5cbc851","line":333,"in_reply_to":"bae84128_4369d48a","updated":"2016-02-22 15:53:49.000000000","message":"A decorator was added in PS24 to address the dict \u0027pollution\u0027 with _orig methods.","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8372896716c3d1fa70e7be6ddc7e8f189bf9380f","unresolved":false,"context_lines":[{"line_number":330,"context_line":"        return dct"},{"line_number":331,"context_line":""},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"class RbacNeutronMetaclass(type):"},{"line_number":334,"context_line":"    \"\"\"Adds support for RBAC in NeutronDbObjects."},{"line_number":335,"context_line":""},{"line_number":336,"context_line":"    Injects code for CRUD operations and modifies existing ops to do so."}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_4369d48a","line":333,"in_reply_to":"bae84128_44af3394","updated":"2016-02-22 10:16:52.000000000","message":"The decorator approach will require the addition of RBAC to be more slightly more intrusive with respect to the obj class. So instead of \nMetaclass approach:\n   a. adding rbac_db_model attribute\n   b. implementing get_bound_tenant_ids()\n\nDecorator approach:\n   a. and b. from Metaclass\n   c. move \u0027shared\u0027 into synthetic fields\n   d. decorate the CRUD methods (if they don\u0027t exist at obj.class, override just to make them decoratable)\n   d*.I\u0027m not sure \nCome to think about it - I don\u0027t mind the switch - perhaps @Ihar could chime in, as Metaclass was our joint original direction.","commit_id":"f24ffc4b13fe9e76f9ce5a543473536af8c7a839"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":141,"context_line":""},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"@add_metaclass(abc.ABCMeta)"},{"line_number":144,"context_line":"class RbacNeutronDbObject(RbacPluginMixin, NeutronDbObject):"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"    rbac_db_model \u003d None"},{"line_number":147,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_0185c405","line":144,"updated":"2016-02-23 15:32:36.000000000","message":"This class is versioned object specific, you should move it under neutron/objects/\n\nSeems like the class is just a pile of code to meld into original object class. Should we rename it into ...Mixin?","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":141,"context_line":""},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"@add_metaclass(abc.ABCMeta)"},{"line_number":144,"context_line":"class RbacNeutronDbObject(RbacPluginMixin, NeutronDbObject):"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"    rbac_db_model \u003d None"},{"line_number":147,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_f3c224e8","line":144,"in_reply_to":"bae84128_0185c405","updated":"2016-02-23 21:25:32.000000000","message":"Do you mean RbacNeutronDbObjectMixin ?\nIf so - Done.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":157,"context_line":""},{"line_number":158,"context_line":"        :returns: set -- a set of tenants\u0027 ids dependent on this object."},{"line_number":159,"context_line":"        \"\"\""},{"line_number":160,"context_line":"        pass"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"    @classmethod"},{"line_number":163,"context_line":"    def is_shared_with_tenant(cls, context, rbac_db_model, obj_id, tenant_id):"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_e1b700d6","line":160,"updated":"2016-02-23 15:32:36.000000000","message":"nit: pass is redundant when you have a docstring","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":157,"context_line":""},{"line_number":158,"context_line":"        :returns: set -- a set of tenants\u0027 ids dependent on this object."},{"line_number":159,"context_line":"        \"\"\""},{"line_number":160,"context_line":"        pass"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"    @classmethod"},{"line_number":163,"context_line":"    def is_shared_with_tenant(cls, context, rbac_db_model, obj_id, tenant_id):"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_984137ac","line":160,"in_reply_to":"bae84128_e1b700d6","updated":"2016-02-23 21:25:32.000000000","message":"Done","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":160,"context_line":"        pass"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"    @classmethod"},{"line_number":163,"context_line":"    def is_shared_with_tenant(cls, context, rbac_db_model, obj_id, tenant_id):"},{"line_number":164,"context_line":"        ctx \u003d context.elevated()"},{"line_number":165,"context_line":"        with ctx.session.begin(subtransactions\u003dTrue):"},{"line_number":166,"context_line":"            return (common_db_mixin.model_query(ctx, rbac_db_model).filter("}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_0138243c","line":163,"updated":"2016-02-23 15:32:36.000000000","message":"Do we really need to pass the rbac_db_model as an argument when it\u0027s already defined on cls?","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":160,"context_line":"        pass"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"    @classmethod"},{"line_number":163,"context_line":"    def is_shared_with_tenant(cls, context, rbac_db_model, obj_id, tenant_id):"},{"line_number":164,"context_line":"        ctx \u003d context.elevated()"},{"line_number":165,"context_line":"        with ctx.session.begin(subtransactions\u003dTrue):"},{"line_number":166,"context_line":"            return (common_db_mixin.model_query(ctx, rbac_db_model).filter("}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_786c3335","line":163,"in_reply_to":"bae84128_0138243c","updated":"2016-02-23 21:25:32.000000000","message":"no, will remove it.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":177,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":"    @staticmethod"},{"line_number":180,"context_line":"    def _get_rbac_shared_target_tenants(context, rbac_db_model, obj_id):"},{"line_number":181,"context_line":"        return common_db_mixin.model_query(context, rbac_db_model).filter("},{"line_number":182,"context_line":"            and_(rbac_db_model.object_id \u003d\u003d obj_id,"},{"line_number":183,"context_line":"                 rbac_db_model.action \u003d\u003d models.ACCESS_SHARED))"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_7353c3e2","line":180,"updated":"2016-02-23 15:32:36.000000000","message":"ditto: db_model could be extracted from the class directly. [as long as you make the method non-static].\n\nAlso, the name of the method is a bit misleading: it returns RBAC entries, not tenants.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":177,"context_line":"                                          db_obj.id, context.tenant_id))"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":"    @staticmethod"},{"line_number":180,"context_line":"    def _get_rbac_shared_target_tenants(context, rbac_db_model, obj_id):"},{"line_number":181,"context_line":"        return common_db_mixin.model_query(context, rbac_db_model).filter("},{"line_number":182,"context_line":"            and_(rbac_db_model.object_id \u003d\u003d obj_id,"},{"line_number":183,"context_line":"                 rbac_db_model.action \u003d\u003d models.ACCESS_SHARED))"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_b87cfbb5","line":180,"in_reply_to":"bae84128_7353c3e2","updated":"2016-02-23 21:25:32.000000000","message":"I like to see the functions go and become simpler to read as the code goes to lower layers - (input args provided explicitly). So whenever a function gets a fraction of its args from a local context and the remaining args are provided explicitly, it makes me raise an eyebrow.\n\nAnyway: Done - for both.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":187,"context_line":"        ctx_admin \u003d context.elevated()"},{"line_number":188,"context_line":"        rb_model \u003d cls.rbac_db_model"},{"line_number":189,"context_line":"        bound_tenant_ids \u003d cls.get_bound_tenant_ids(ctx_admin, obj_id)"},{"line_number":190,"context_line":"        other_target_tenants \u003d cls._get_rbac_shared_target_tenants(ctx_admin,"},{"line_number":191,"context_line":"                                                                   rb_model,"},{"line_number":192,"context_line":"                                                                   obj_id)"},{"line_number":193,"context_line":"        if target_tenant !\u003d \u0027*\u0027:"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_b696d9ed","line":190,"range":{"start_line":190,"start_character":8,"end_line":190,"end_character":28},"updated":"2016-02-23 15:32:36.000000000","message":"The variable name is misleading: in fact, it\u0027s not tenants but obj_id\u0027s RBAC entries with \u0027access_as_shared\u0027 type.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":187,"context_line":"        ctx_admin \u003d context.elevated()"},{"line_number":188,"context_line":"        rb_model \u003d cls.rbac_db_model"},{"line_number":189,"context_line":"        bound_tenant_ids \u003d cls.get_bound_tenant_ids(ctx_admin, obj_id)"},{"line_number":190,"context_line":"        other_target_tenants \u003d cls._get_rbac_shared_target_tenants(ctx_admin,"},{"line_number":191,"context_line":"                                                                   rb_model,"},{"line_number":192,"context_line":"                                                                   obj_id)"},{"line_number":193,"context_line":"        if target_tenant !\u003d \u0027*\u0027:"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_c8c2ce33","line":190,"range":{"start_line":190,"start_character":8,"end_line":190,"end_character":28},"in_reply_to":"bae84128_b696d9ed","updated":"2016-02-23 21:25:32.000000000","message":"Done","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":193,"context_line":"        if target_tenant !\u003d \u0027*\u0027:"},{"line_number":194,"context_line":"            # if there is a wildcard rule, we can return early because it"},{"line_number":195,"context_line":"            # shares the object globally"},{"line_number":196,"context_line":"            wildcarded_tenants \u003d other_target_tenants.filter("},{"line_number":197,"context_line":"                rb_model.target_tenant \u003d\u003d \u0027*\u0027)"},{"line_number":198,"context_line":"            if wildcarded_tenants.count():"},{"line_number":199,"context_line":"                return"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_7656112b","line":196,"range":{"start_line":196,"start_character":12,"end_line":196,"end_character":30},"updated":"2016-02-23 15:32:36.000000000","message":"ditto on the naming","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":193,"context_line":"        if target_tenant !\u003d \u0027*\u0027:"},{"line_number":194,"context_line":"            # if there is a wildcard rule, we can return early because it"},{"line_number":195,"context_line":"            # shares the object globally"},{"line_number":196,"context_line":"            wildcarded_tenants \u003d other_target_tenants.filter("},{"line_number":197,"context_line":"                rb_model.target_tenant \u003d\u003d \u0027*\u0027)"},{"line_number":198,"context_line":"            if wildcarded_tenants.count():"},{"line_number":199,"context_line":"                return"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_08df960d","line":196,"range":{"start_line":196,"start_character":12,"end_line":196,"end_character":30},"in_reply_to":"bae84128_7656112b","updated":"2016-02-23 21:25:32.000000000","message":"Done","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":206,"context_line":"                return list(itertools.chain.from_iterable(x))"},{"line_number":207,"context_line":"            # for the wildcard we need to get all of the rbac entries to"},{"line_number":208,"context_line":"            # see if any allow the object sharing"},{"line_number":209,"context_line":"            other_target_tenants \u003d flatten(other_target_tenants.filter("},{"line_number":210,"context_line":"                rb_model.target_tenant !\u003d \u0027*\u0027).all())"},{"line_number":211,"context_line":"            if not bound_tenant_ids.issubset(set(other_target_tenants)):"},{"line_number":212,"context_line":"                raise ext_rbac.RbacPolicyInUse("}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_6c18041f","line":209,"range":{"start_line":209,"start_character":12,"end_line":209,"end_character":32},"updated":"2016-02-23 15:32:36.000000000","message":"other_target_tenants currently contains all columns, not just tenant_id one. [you don\u0027t specify column to extract in line 181). Is it really the intent here?","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":206,"context_line":"                return list(itertools.chain.from_iterable(x))"},{"line_number":207,"context_line":"            # for the wildcard we need to get all of the rbac entries to"},{"line_number":208,"context_line":"            # see if any allow the object sharing"},{"line_number":209,"context_line":"            other_target_tenants \u003d flatten(other_target_tenants.filter("},{"line_number":210,"context_line":"                rb_model.target_tenant !\u003d \u0027*\u0027).all())"},{"line_number":211,"context_line":"            if not bound_tenant_ids.issubset(set(other_target_tenants)):"},{"line_number":212,"context_line":"                raise ext_rbac.RbacPolicyInUse("}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_48a7d7bc","line":209,"range":{"start_line":209,"start_character":12,"end_line":209,"end_character":32},"in_reply_to":"bae84128_6c18041f","updated":"2016-02-23 21:25:32.000000000","message":"no, and I lacked the tests for that - fixed.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":209,"context_line":"            other_target_tenants \u003d flatten(other_target_tenants.filter("},{"line_number":210,"context_line":"                rb_model.target_tenant !\u003d \u0027*\u0027).all())"},{"line_number":211,"context_line":"            if not bound_tenant_ids.issubset(set(other_target_tenants)):"},{"line_number":212,"context_line":"                raise ext_rbac.RbacPolicyInUse("},{"line_number":213,"context_line":"                    object_id\u003dobj_id,"},{"line_number":214,"context_line":"                    details\u003d\u0027tenant_id\u003d{}\u0027.format(target_tenant))"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"    @classmethod"},{"line_number":217,"context_line":"    def validate_rbac_policy_delete(cls, resource, event, trigger, context,"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_ec3ed489","line":214,"range":{"start_line":212,"start_character":16,"end_line":214,"end_character":65},"updated":"2016-02-23 15:32:36.000000000","message":"nit: lines 201-203 and 212-214 are identical. you could avoid it if you would consistently return from the function if all goes fine, and then have a catch-all raise at the very end of the method.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":220,"context_line":""},{"line_number":221,"context_line":"        :raises: RbacPolicyInUse -- in case the policy is in use."},{"line_number":222,"context_line":"        \"\"\""},{"line_number":223,"context_line":"        if policy[\u0027action\u0027] !\u003d models.ACCESS_SHARED:"},{"line_number":224,"context_line":"            return"},{"line_number":225,"context_line":"        target_tenant \u003d policy[\u0027target_tenant\u0027]"},{"line_number":226,"context_line":"        db_obj \u003d cls.get_by_id(context, policy[\u0027object_id\u0027])"},{"line_number":227,"context_line":"        if db_obj.tenant_id \u003d\u003d target_tenant:"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_7601f1ae","line":224,"range":{"start_line":223,"start_character":8,"end_line":224,"end_character":18},"updated":"2016-02-23 15:32:36.000000000","message":"(No action required) I guess that bit will require some abstraction once we get first object supporting multiple RBAC entry types. I guess objects should be able to specify which features they want to handle.\n\nBut it should be ok as-is for now.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":254,"context_line":"        callbacks. On creation and update, verify that the creator is an admin"},{"line_number":255,"context_line":"        or owns the resource being shared."},{"line_number":256,"context_line":"        \"\"\""},{"line_number":257,"context_line":"        # TODO(hdaniel): As this code was shamelesly stolen from"},{"line_number":258,"context_line":"        # NeutronDbPluginV2.validate_network_rbac_policy_change(), those pieces"},{"line_number":259,"context_line":"        # should be synced and contain the same bugs, until Network RBAC logic"},{"line_number":260,"context_line":"        # (hopefully) melded with this one."}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_cc37904b","line":257,"range":{"start_line":257,"start_character":42,"end_line":257,"end_character":52},"updated":"2016-02-23 15:32:36.000000000","message":"shamelessly","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":254,"context_line":"        callbacks. On creation and update, verify that the creator is an admin"},{"line_number":255,"context_line":"        or owns the resource being shared."},{"line_number":256,"context_line":"        \"\"\""},{"line_number":257,"context_line":"        # TODO(hdaniel): As this code was shamelesly stolen from"},{"line_number":258,"context_line":"        # NeutronDbPluginV2.validate_network_rbac_policy_change(), those pieces"},{"line_number":259,"context_line":"        # should be synced and contain the same bugs, until Network RBAC logic"},{"line_number":260,"context_line":"        # (hopefully) melded with this one."}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_58396ff1","line":257,"range":{"start_line":257,"start_character":42,"end_line":257,"end_character":52},"in_reply_to":"bae84128_cc37904b","updated":"2016-02-23 21:25:32.000000000","message":"Done","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":256,"context_line":"        \"\"\""},{"line_number":257,"context_line":"        # TODO(hdaniel): As this code was shamelesly stolen from"},{"line_number":258,"context_line":"        # NeutronDbPluginV2.validate_network_rbac_policy_change(), those pieces"},{"line_number":259,"context_line":"        # should be synced and contain the same bugs, until Network RBAC logic"},{"line_number":260,"context_line":"        # (hopefully) melded with this one."},{"line_number":261,"context_line":"        if object_type !\u003d cls.rbac_db_model.object_type:"},{"line_number":262,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_4c1b80ca","line":259,"range":{"start_line":259,"start_character":27,"end_line":259,"end_character":52},"updated":"2016-02-23 15:32:36.000000000","message":"(No action required) I appreciate the humour.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":262,"context_line":"            return"},{"line_number":263,"context_line":"        db_obj \u003d cls.get_by_id(context.elevated(), policy[\u0027object_id\u0027])"},{"line_number":264,"context_line":"        if event in (events.BEFORE_CREATE, events.BEFORE_UPDATE):"},{"line_number":265,"context_line":"            if not context.is_admin and db_obj["},{"line_number":266,"context_line":"                \u0027tenant_id\u0027] !\u003d context.tenant_id:"},{"line_number":267,"context_line":"                msg \u003d _(\"Only admins can manipulate policies on objects \""},{"line_number":268,"context_line":"                        \"they do not own\")"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_07a31101","line":265,"updated":"2016-02-23 15:32:36.000000000","message":"that\u0027s a really weird place to split the line. please consider something more easy to grasp, like after \u0027and\u0027, (if you need it at all).","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":262,"context_line":"            return"},{"line_number":263,"context_line":"        db_obj \u003d cls.get_by_id(context.elevated(), policy[\u0027object_id\u0027])"},{"line_number":264,"context_line":"        if event in (events.BEFORE_CREATE, events.BEFORE_UPDATE):"},{"line_number":265,"context_line":"            if not context.is_admin and db_obj["},{"line_number":266,"context_line":"                \u0027tenant_id\u0027] !\u003d context.tenant_id:"},{"line_number":267,"context_line":"                msg \u003d _(\"Only admins can manipulate policies on objects \""},{"line_number":268,"context_line":"                        \"they do not own\")"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_5355d0f7","line":265,"in_reply_to":"bae84128_07a31101","updated":"2016-02-23 21:25:32.000000000","message":"Done","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":280,"context_line":"                                       \u0027tenant_id\u0027: tenant_id,"},{"line_number":281,"context_line":"                                       \u0027object_type\u0027: obj_type,"},{"line_number":282,"context_line":"                                       \u0027action\u0027: models.ACCESS_SHARED}}"},{"line_number":283,"context_line":"        return self.create_rbac_policy(self._context, rbac_policy)"},{"line_number":284,"context_line":""},{"line_number":285,"context_line":"    def update_shared(self, is_shared_new, obj_id):"},{"line_number":286,"context_line":"        admin_context \u003d self._context.elevated()"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_3dfbc4c2","line":283,"range":{"start_line":283,"start_character":8,"end_line":283,"end_character":15},"updated":"2016-02-23 15:32:36.000000000","message":"(No action required) Not sure anyone cares about the entry being returned by the method.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":280,"context_line":"                                       \u0027tenant_id\u0027: tenant_id,"},{"line_number":281,"context_line":"                                       \u0027object_type\u0027: obj_type,"},{"line_number":282,"context_line":"                                       \u0027action\u0027: models.ACCESS_SHARED}}"},{"line_number":283,"context_line":"        return self.create_rbac_policy(self._context, rbac_policy)"},{"line_number":284,"context_line":""},{"line_number":285,"context_line":"    def update_shared(self, is_shared_new, obj_id):"},{"line_number":286,"context_line":"        admin_context \u003d self._context.elevated()"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_4256a75c","line":283,"range":{"start_line":283,"start_character":39,"end_line":283,"end_character":52},"updated":"2016-02-23 15:32:36.000000000","message":"Here and below, we should avoid using the internal attribute. See: https://review.openstack.org/#/c/283616/","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":280,"context_line":"                                       \u0027tenant_id\u0027: tenant_id,"},{"line_number":281,"context_line":"                                       \u0027object_type\u0027: obj_type,"},{"line_number":282,"context_line":"                                       \u0027action\u0027: models.ACCESS_SHARED}}"},{"line_number":283,"context_line":"        return self.create_rbac_policy(self._context, rbac_policy)"},{"line_number":284,"context_line":""},{"line_number":285,"context_line":"    def update_shared(self, is_shared_new, obj_id):"},{"line_number":286,"context_line":"        admin_context \u003d self._context.elevated()"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_6b92954d","line":283,"range":{"start_line":283,"start_character":39,"end_line":283,"end_character":52},"in_reply_to":"bae84128_4256a75c","updated":"2016-02-23 21:25:32.000000000","message":"per the suggested link, the oslo guys should expose an interface for getting the context. Till they actually do that - I suggest keeping this code and replacing all places altogether as a separate patch.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":291,"context_line":"        if is_shared_prev \u003d\u003d is_shared_new:"},{"line_number":292,"context_line":"            return"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"        # \u0027sharing\u0027 goes False -\u003e True"},{"line_number":295,"context_line":"        if not is_shared_prev and is_shared_new:"},{"line_number":296,"context_line":"            self.attach_rbac(obj_id, self._context.tenant_id)"},{"line_number":297,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_62a5ab45","line":294,"range":{"start_line":294,"start_character":11,"end_line":294,"end_character":18},"updated":"2016-02-23 15:32:36.000000000","message":"shared","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":291,"context_line":"        if is_shared_prev \u003d\u003d is_shared_new:"},{"line_number":292,"context_line":"            return"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"        # \u0027sharing\u0027 goes False -\u003e True"},{"line_number":295,"context_line":"        if not is_shared_prev and is_shared_new:"},{"line_number":296,"context_line":"            self.attach_rbac(obj_id, self._context.tenant_id)"},{"line_number":297,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_3e3f3088","line":294,"range":{"start_line":294,"start_character":11,"end_line":294,"end_character":18},"in_reply_to":"bae84128_62a5ab45","updated":"2016-02-23 21:25:32.000000000","message":"Done","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":296,"context_line":"            self.attach_rbac(obj_id, self._context.tenant_id)"},{"line_number":297,"context_line":"            return"},{"line_number":298,"context_line":""},{"line_number":299,"context_line":"        # \u0027sharing\u0027 goes True -\u003e False is actualy an attempt to delete"},{"line_number":300,"context_line":"        # rbac rule for sharing obj_id with target_tenant \u003d \u0027*\u0027"},{"line_number":301,"context_line":"        self._validate_rbac_policy_delete(self._context, obj_id, \u0027*\u0027)"},{"line_number":302,"context_line":"        return self._context.session.delete(shared_prev)"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_fddafc49","line":299,"range":{"start_line":299,"start_character":42,"end_line":299,"end_character":49},"updated":"2016-02-23 15:32:36.000000000","message":"actually","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":296,"context_line":"            self.attach_rbac(obj_id, self._context.tenant_id)"},{"line_number":297,"context_line":"            return"},{"line_number":298,"context_line":""},{"line_number":299,"context_line":"        # \u0027sharing\u0027 goes True -\u003e False is actualy an attempt to delete"},{"line_number":300,"context_line":"        # rbac rule for sharing obj_id with target_tenant \u003d \u0027*\u0027"},{"line_number":301,"context_line":"        self._validate_rbac_policy_delete(self._context, obj_id, \u0027*\u0027)"},{"line_number":302,"context_line":"        return self._context.session.delete(shared_prev)"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_e26ffbf9","line":299,"range":{"start_line":299,"start_character":11,"end_line":299,"end_character":18},"updated":"2016-02-23 15:32:36.000000000","message":"ditto","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":296,"context_line":"            self.attach_rbac(obj_id, self._context.tenant_id)"},{"line_number":297,"context_line":"            return"},{"line_number":298,"context_line":""},{"line_number":299,"context_line":"        # \u0027sharing\u0027 goes True -\u003e False is actualy an attempt to delete"},{"line_number":300,"context_line":"        # rbac rule for sharing obj_id with target_tenant \u003d \u0027*\u0027"},{"line_number":301,"context_line":"        self._validate_rbac_policy_delete(self._context, obj_id, \u0027*\u0027)"},{"line_number":302,"context_line":"        return self._context.session.delete(shared_prev)"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_93c63898","line":299,"range":{"start_line":299,"start_character":42,"end_line":299,"end_character":49},"in_reply_to":"bae84128_fddafc49","updated":"2016-02-23 21:25:32.000000000","message":"Done","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":304,"context_line":"    def update_post(self):"},{"line_number":305,"context_line":"        self.update_shared(self.shared, self.id)"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def update_hook(self, update_orig):"},{"line_number":308,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":309,"context_line":"            update_orig()"},{"line_number":310,"context_line":"            self.update_post()"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_3dd3c405","line":307,"updated":"2016-02-23 15:32:36.000000000","message":"You still pollute the class with _hook and _post and whatnot. Please see below how to avoid it.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":327,"context_line":"        return dct"},{"line_number":328,"context_line":""},{"line_number":329,"context_line":""},{"line_number":330,"context_line":"def rbac_proxy_method(func):"},{"line_number":331,"context_line":"    \"\"\"Decorator for interfacing rbac hooks in RbacNeutronDbObject."},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"    Currently create(), update() and to_dict() methods need decorating."}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_98c01e52","line":330,"updated":"2016-02-23 15:32:36.000000000","message":"No, we don\u0027t want that original method modification explicit. Metaclass should take care of method modification implicitly, by the virtue of applying it to the object.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"7c326d5a585a2b2ec484db3ff935bbf20c465d10","unresolved":false,"context_lines":[{"line_number":334,"context_line":"    \"\"\""},{"line_number":335,"context_line":"    @functools.wraps(func)"},{"line_number":336,"context_line":"    def decorator(self, *args, **kwargs):"},{"line_number":337,"context_line":"        rbac_hook \u003d getattr(self, func.__name__ + \u0027_hook\u0027)"},{"line_number":338,"context_line":"        return rbac_hook(functools.partial(func, self, *args, **kwargs))"},{"line_number":339,"context_line":""},{"line_number":340,"context_line":"    return decorator"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_f396b33c","line":337,"range":{"start_line":337,"start_character":34,"end_line":337,"end_character":38},"updated":"2016-02-23 13:33:49.000000000","message":"I suspect we didn\u0027t explain our \"ideal\" well :)\n\nI believe we were talking about wrapping the original function, so *_post is called from within the wrapper. No need for hook function then. Wrap becomes the hook.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":334,"context_line":"    \"\"\""},{"line_number":335,"context_line":"    @functools.wraps(func)"},{"line_number":336,"context_line":"    def decorator(self, *args, **kwargs):"},{"line_number":337,"context_line":"        rbac_hook \u003d getattr(self, func.__name__ + \u0027_hook\u0027)"},{"line_number":338,"context_line":"        return rbac_hook(functools.partial(func, self, *args, **kwargs))"},{"line_number":339,"context_line":""},{"line_number":340,"context_line":"    return decorator"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_2eaa5b19","line":337,"range":{"start_line":337,"start_character":34,"end_line":337,"end_character":38},"in_reply_to":"bae84128_9805be12","updated":"2016-02-23 21:25:32.000000000","message":"No, it doesn\u0027t - IMO the way things are right now - the hooks are separated from the metaclass. They live in separate class, their code makes sense without even looking at the Metaclass - since the entire state belongs to RbacNeutronDbObjectMixin, thus making it easier to read. \nI\u0027m really failing to understand what makes moving the hooks into the metaclass a better solution.\n\nI suggest we\u0027ll have a discussion about that.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":334,"context_line":"    \"\"\""},{"line_number":335,"context_line":"    @functools.wraps(func)"},{"line_number":336,"context_line":"    def decorator(self, *args, **kwargs):"},{"line_number":337,"context_line":"        rbac_hook \u003d getattr(self, func.__name__ + \u0027_hook\u0027)"},{"line_number":338,"context_line":"        return rbac_hook(functools.partial(func, self, *args, **kwargs))"},{"line_number":339,"context_line":""},{"line_number":340,"context_line":"    return decorator"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_9805be12","line":337,"range":{"start_line":337,"start_character":34,"end_line":337,"end_character":38},"in_reply_to":"bae84128_f396b33c","updated":"2016-02-23 15:32:36.000000000","message":"Yes. You should not need to apply any decorators to update functions inside objects. Instead, metaclass should override the original methods in the object with another callable that 1) calls the original method; 2) does rbac work.\n\nYou also don\u0027t need to pass the original function as an argument anywhere. Instead, when you define your overriding method in the metaclass, you capture the original method value thru a closure.\n\nSo, in the end, you just define some functions inside __new__ that e.g. will call getattr(cls, \u0027update\u0027) and then rbac code, and set cls.update \u003d to the new method.\n\nIn essence, it\u0027s just moving _hook functions under __new__ in the metaclass.\n\nDoes it make sense for you?","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":340,"context_line":"    return decorator"},{"line_number":341,"context_line":""},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"class RbacNeutronMetaclass(type):"},{"line_number":344,"context_line":"    \"\"\"Adds support for RBAC in NeutronDbObjects."},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"    Injects code for CRUD operations and modifies existing ops to do so."}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_b806c2cb","line":343,"updated":"2016-02-23 15:32:36.000000000","message":"I actually don\u0027t see any reason why we would want to have separate RbacDbObject type and the metaclass. I would think that all the code belongs to the metaclass.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":340,"context_line":"    return decorator"},{"line_number":341,"context_line":""},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"class RbacNeutronMetaclass(type):"},{"line_number":344,"context_line":"    \"\"\"Adds support for RBAC in NeutronDbObjects."},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"    Injects code for CRUD operations and modifies existing ops to do so."}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_4b7fd1df","line":343,"in_reply_to":"bae84128_b806c2cb","updated":"2016-02-23 21:25:32.000000000","message":"The idea was that the Metaclass should segregate the logic needs to be done on the patched class. The RbacDbObject type was meant to provide the additional functionality, which will be extended by the patched class (via the Metaclass).","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":381,"context_line":""},{"line_number":382,"context_line":"    @classmethod"},{"line_number":383,"context_line":"    def validate_existing_attrs(mcs, cls_name, dct):"},{"line_number":384,"context_line":"        if \u0027shared\u0027 not in dct[\u0027fields\u0027]:"},{"line_number":385,"context_line":"            raise KeyError(_(\u0027No shared key in %s fields\u0027) % cls_name)"},{"line_number":386,"context_line":"        if \u0027rbac_db_model\u0027 not in dct:"},{"line_number":387,"context_line":"            raise AttributeError(_(\u0027rbac_db_model not found in %s\u0027) % cls_name)"},{"line_number":388,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_38df526a","line":385,"range":{"start_line":384,"start_character":8,"end_line":385,"end_character":70},"updated":"2016-02-23 15:32:36.000000000","message":"Instead of validating the field, I would actually make the metaclass add the field for us. That would isolate some more rbac code inside the metaclass.\n\nSame for synthetic_fields management in lines 365-.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":381,"context_line":""},{"line_number":382,"context_line":"    @classmethod"},{"line_number":383,"context_line":"    def validate_existing_attrs(mcs, cls_name, dct):"},{"line_number":384,"context_line":"        if \u0027shared\u0027 not in dct[\u0027fields\u0027]:"},{"line_number":385,"context_line":"            raise KeyError(_(\u0027No shared key in %s fields\u0027) % cls_name)"},{"line_number":386,"context_line":"        if \u0027rbac_db_model\u0027 not in dct:"},{"line_number":387,"context_line":"            raise AttributeError(_(\u0027rbac_db_model not found in %s\u0027) % cls_name)"},{"line_number":388,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_b9607ad0","line":385,"range":{"start_line":384,"start_character":8,"end_line":385,"end_character":70},"in_reply_to":"bae84128_38df526a","updated":"2016-02-23 21:25:32.000000000","message":"Do you mean\nif \u0027shared\u0027 not in dct[\u0027fields\u0027]:\n    add the \u0027shared\u0027 field to fields\n    move it to synthetic \n?","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"da01173457f0d19701eab450ea992970fa6e789f","unresolved":false,"context_lines":[{"line_number":381,"context_line":""},{"line_number":382,"context_line":"    @classmethod"},{"line_number":383,"context_line":"    def validate_existing_attrs(mcs, cls_name, dct):"},{"line_number":384,"context_line":"        if \u0027shared\u0027 not in dct[\u0027fields\u0027]:"},{"line_number":385,"context_line":"            raise KeyError(_(\u0027No shared key in %s fields\u0027) % cls_name)"},{"line_number":386,"context_line":"        if \u0027rbac_db_model\u0027 not in dct:"},{"line_number":387,"context_line":"            raise AttributeError(_(\u0027rbac_db_model not found in %s\u0027) % cls_name)"},{"line_number":388,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_43e8f116","line":385,"range":{"start_line":384,"start_character":8,"end_line":385,"end_character":70},"in_reply_to":"bae84128_b9607ad0","updated":"2016-02-25 09:25:20.000000000","message":"Yes. Though probably do it unconditionally, and fail if shared is already defined in the fields explicitly. That would guarantee us that field is properly typed and all.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":389,"context_line":"    def __new__(mcs, name, bases, dct):"},{"line_number":390,"context_line":"        mcs.validate_existing_attrs(name, dct)"},{"line_number":391,"context_line":"        mcs.update_synthetic_fields(bases, dct)"},{"line_number":392,"context_line":"        cls \u003d type(name, (RbacNeutronDbObject,) + bases, dct)"},{"line_number":393,"context_line":"        mcs.subscribe_to_rbac_events(cls)"},{"line_number":394,"context_line":""},{"line_number":395,"context_line":"        return cls"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_f8e4cae0","line":392,"updated":"2016-02-23 15:32:36.000000000","message":"I would prefer we don\u0027t mess with the inheritance chain of the original method. Rewriting some original methods for CRUD operations should be enough and won\u0027t require changing parents.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":389,"context_line":"    def __new__(mcs, name, bases, dct):"},{"line_number":390,"context_line":"        mcs.validate_existing_attrs(name, dct)"},{"line_number":391,"context_line":"        mcs.update_synthetic_fields(bases, dct)"},{"line_number":392,"context_line":"        cls \u003d type(name, (RbacNeutronDbObject,) + bases, dct)"},{"line_number":393,"context_line":"        mcs.subscribe_to_rbac_events(cls)"},{"line_number":394,"context_line":""},{"line_number":395,"context_line":"        return cls"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_59c32e89","line":392,"in_reply_to":"bae84128_f8e4cae0","updated":"2016-02-23 21:25:32.000000000","message":"How would the patched class (e.g. QosPolicy) inherit the RbacNeutronDbObject if we don\u0027t do that ?","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":12,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":13,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from sqlalchemy.orm import exc"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from neutron.callbacks import events"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_23a5edb4","side":"PARENT","line":15,"updated":"2016-02-25 11:00:39.000000000","message":"now there is no need to touch the file","commit_id":"d3ca9b7d56caf364e3b7e60f4b5ae30656b4eb98"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":12,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":13,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from sqlalchemy.orm import exc"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from neutron.callbacks import events"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_8de6a2e6","side":"PARENT","line":15,"in_reply_to":"bae84128_23a5edb4","updated":"2016-02-25 17:24:55.000000000","message":"Done","commit_id":"d3ca9b7d56caf364e3b7e60f4b5ae30656b4eb98"}],"neutron/db/rbac_db_models.py":[{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"93d8c78de40dbc7303e34286728861c178a96828","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        return (ACCESS_SHARED,)"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"class QosPolicyRBAC(RBACColumns, model_base.BASEV2):"},{"line_number":91,"context_line":"    \"\"\"RBAC table for qos policies.\"\"\""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    object_id \u003d sa.Column(sa.String(36),"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a8ffd7b_28e371da","line":90,"updated":"2015-11-30 09:09:22.000000000","message":"A thought: Could it make sense to make this into neutron/db/qos/qos_db models for decoupling?","commit_id":"ebd846ad6930ef7ee98e9fa7d61d8a5081b27c09"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"d1a32f9194ad2d333ac82c9ae2c59aaee5953983","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        return (ACCESS_SHARED,)"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"class QosPolicyRBAC(RBACColumns, model_base.BASEV2):"},{"line_number":91,"context_line":"    \"\"\"RBAC table for qos policies.\"\"\""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    object_id \u003d sa.Column(sa.String(36),"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a8ffd7b_ae49a932","line":90,"in_reply_to":"9a8ffd7b_28e371da","updated":"2015-11-30 09:17:07.000000000","message":"It looked to me that this module was supposed to be shared to all RBAC subclasses. Just followed the conventions.","commit_id":"ebd846ad6930ef7ee98e9fa7d61d8a5081b27c09"},{"author":{"_account_id":14605,"name":"vikram.choudhary","email":"vikschw@gmail.com","username":"vikram.choudhary"},"change_message_id":"cbf6e1a630aa493ac8ded6790b3aa8def3f5cce2","unresolved":false,"context_lines":[{"line_number":93,"context_line":"    object_id \u003d sa.Column(sa.String(36),"},{"line_number":94,"context_line":"                          sa.ForeignKey(\u0027qos_policies.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":95,"context_line":"                          nullable\u003dFalse)"},{"line_number":96,"context_line":"    object_type \u003d \u0027policy\u0027"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def get_valid_actions(self):"},{"line_number":99,"context_line":"        return (ACCESS_SHARED,)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5a710552_12b2e994","line":96,"updated":"2015-12-16 09:26:11.000000000","message":"how about renaming to \u0027qos-policy\u0027. \u0027policy\u0027 sounds too generic.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":24,"context_line":"from neutron.db import model_base"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"ACCESS_SHARED \u003d \u0027access_as_shared\u0027"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"class InvalidActionForType(n_exc.InvalidInput):"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_7c825302","line":27,"range":{"start_line":27,"start_character":0,"end_line":27,"end_character":13},"updated":"2015-12-17 13:17:04.000000000","message":"Since you went through the trouble of adding a new constant, please redirect all current direct references of \u0027access_as_shared\u0027 to this new variable.\n\n/me wonders whether or not we want a \u0027SHARED_BY_ALL \u003d \"*\"\u0027 constant as well.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"30599cd74aa21f58b1c83a0b115dfe06302ef5c4","unresolved":false,"context_lines":[{"line_number":24,"context_line":"from neutron.db import model_base"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"ACCESS_SHARED \u003d \u0027access_as_shared\u0027"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"class InvalidActionForType(n_exc.InvalidInput):"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_daab32d5","line":27,"range":{"start_line":27,"start_character":0,"end_line":27,"end_character":13},"in_reply_to":"3a7e1126_7c825302","updated":"2015-12-17 15:59:47.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"96f163e46f88fdbd1e16bbf6bfcfa7c4e2f9e425","unresolved":false,"context_lines":[{"line_number":93,"context_line":"class QosPolicyRBAC(RBACColumns, model_base.BASEV2):"},{"line_number":94,"context_line":"    \"\"\"RBAC table for qos policies.\"\"\""},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    object_id \u003d sa.Column(sa.String(36),"},{"line_number":97,"context_line":"                          sa.ForeignKey(\u0027qos_policies.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":98,"context_line":"                          nullable\u003dFalse)"},{"line_number":99,"context_line":"    object_type \u003d \u0027qos_policy\u0027"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_12b0fff3","line":96,"range":{"start_line":96,"start_character":16,"end_line":96,"end_character":18},"updated":"2016-02-03 11:34:57.000000000","message":"not sure if that\u0027s a pattern we do in db models, but It feels like it\u0027d be good to have a helper\n\ndef object_id_column(foreign_key):\n    return sa.Column(sa.String(36),\n                     sa.ForeignKey(foreign_key, ondelete\u003d\u0027CASCADE)\u0027,\n                     nullable\u003dFalse)","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":93,"context_line":"class QosPolicyRBAC(RBACColumns, model_base.BASEV2):"},{"line_number":94,"context_line":"    \"\"\"RBAC table for qos policies.\"\"\""},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    object_id \u003d sa.Column(sa.String(36),"},{"line_number":97,"context_line":"                          sa.ForeignKey(\u0027qos_policies.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":98,"context_line":"                          nullable\u003dFalse)"},{"line_number":99,"context_line":"    object_type \u003d \u0027qos_policy\u0027"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_57d3b338","line":96,"range":{"start_line":96,"start_character":16,"end_line":96,"end_character":18},"in_reply_to":"5a5ae5dd_12b0fff3","updated":"2016-02-04 10:11:00.000000000","message":"Done","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":14605,"name":"vikram.choudhary","email":"vikschw@gmail.com","username":"vikram.choudhary"},"change_message_id":"9f2ea048f0587daa86641beadf2dedf8449775f5","unresolved":false,"context_lines":[{"line_number":93,"context_line":"class QosPolicyRBAC(RBACColumns, model_base.BASEV2):"},{"line_number":94,"context_line":"    \"\"\"RBAC table for qos policies.\"\"\""},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    object_id \u003d sa.Column(sa.String(36),"},{"line_number":97,"context_line":"                          sa.ForeignKey(\u0027qos_policies.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":98,"context_line":"                          nullable\u003dFalse)"},{"line_number":99,"context_line":"    object_type \u003d \u0027qos_policy\u0027"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_d23a59cd","line":96,"range":{"start_line":96,"start_character":16,"end_line":96,"end_character":18},"in_reply_to":"5a5ae5dd_12b0fff3","updated":"2016-02-03 16:18:45.000000000","message":"Nice suggestion.","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"92c39525ea637d28f5dbbc536926e3754ec0a30b","unresolved":false,"context_lines":[{"line_number":78,"context_line":"    return {table.object_type: table for table in RBACColumns.__subclasses__()}"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"def object_id_column(foreign_key):"},{"line_number":82,"context_line":"    return sa.Column(sa.String(36),"},{"line_number":83,"context_line":"                     sa.ForeignKey(foreign_key, ondelete\u003d\"CASCADE\"),"},{"line_number":84,"context_line":"                     nullable\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_b5f2f26d","line":81,"range":{"start_line":81,"start_character":4,"end_line":81,"end_character":20},"updated":"2016-02-19 12:07:51.000000000","message":"supernitshedding: _object_id_column :)","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"57b0d348fb5c654912c0fe78279702c327042ec7","unresolved":false,"context_lines":[{"line_number":78,"context_line":"    return {table.object_type: table for table in RBACColumns.__subclasses__()}"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"def object_id_column(foreign_key):"},{"line_number":82,"context_line":"    return sa.Column(sa.String(36),"},{"line_number":83,"context_line":"                     sa.ForeignKey(foreign_key, ondelete\u003d\"CASCADE\"),"},{"line_number":84,"context_line":"                     nullable\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_1ccc9834","line":81,"range":{"start_line":81,"start_character":4,"end_line":81,"end_character":20},"in_reply_to":"bae84128_b1067f1e","updated":"2016-02-19 16:14:34.000000000","message":"Done","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"f3145b06d332ae18603f5e72a2fe4ac51ef96a56","unresolved":false,"context_lines":[{"line_number":78,"context_line":"    return {table.object_type: table for table in RBACColumns.__subclasses__()}"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"def object_id_column(foreign_key):"},{"line_number":82,"context_line":"    return sa.Column(sa.String(36),"},{"line_number":83,"context_line":"                     sa.ForeignKey(foreign_key, ondelete\u003d\"CASCADE\"),"},{"line_number":84,"context_line":"                     nullable\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_b1067f1e","line":81,"range":{"start_line":81,"start_character":4,"end_line":81,"end_character":20},"in_reply_to":"bae84128_b5f2f26d","updated":"2016-02-19 13:00:46.000000000","message":"will do if I\u0027ll respin","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"}],"neutron/objects/base.py":[{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"fe55d9cd73219555a689b319cbd9069f80554b52","unresolved":false,"context_lines":[{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    @classmethod"},{"line_number":134,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":135,"context_line":"        pass"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def _get_changed_persistent_fields(self):"},{"line_number":138,"context_line":"        fields \u003d self.obj_get_changes()"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a5de9d1_53d179cc","line":135,"updated":"2016-01-28 10:48:26.000000000","message":"shall we return something by default instead of pass?\n\nMay be providing a default \"shared\" field checker\nor returning False by default?","commit_id":"78a8bd43e98932225962826f0c2115b501cdbf6c"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"ae40ab1f9dbe455e86689db0fd28a605152e5788","unresolved":false,"context_lines":[{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    @classmethod"},{"line_number":134,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":135,"context_line":"        pass"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def _get_changed_persistent_fields(self):"},{"line_number":138,"context_line":"        fields \u003d self.obj_get_changes()"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a5de9d1_645dc9e8","line":135,"in_reply_to":"7a5de9d1_53d179cc","updated":"2016-01-28 11:18:02.000000000","message":"I actually wanted some form of abstract method, without messing with the class - so can I suggest throwing an alternative throwing NotImplementedError ?","commit_id":"78a8bd43e98932225962826f0c2115b501cdbf6c"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"27bec8a85e9c3c6175a0026d93f55265203efc84","unresolved":false,"context_lines":[{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    @classmethod"},{"line_number":134,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":135,"context_line":"        pass"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def _get_changed_persistent_fields(self):"},{"line_number":138,"context_line":"        fields \u003d self.obj_get_changes()"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a5de9d1_75356fd8","line":135,"in_reply_to":"7a5de9d1_645dc9e8","updated":"2016-01-28 13:48:47.000000000","message":"That sounds right too, in fact, better.","commit_id":"78a8bd43e98932225962826f0c2115b501cdbf6c"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"89dc6c8a83f2209990487100aaaa8ffea9924539","unresolved":false,"context_lines":[{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    @classmethod"},{"line_number":134,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":135,"context_line":"        raise NotImplementedError"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def _get_changed_persistent_fields(self):"},{"line_number":138,"context_line":"        fields \u003d self.obj_get_changes()"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_f50bcd7b","line":135,"range":{"start_line":135,"start_character":14,"end_line":135,"end_character":33},"updated":"2016-02-03 13:44:40.000000000","message":"Conventions tell you to always raise an instance, ie. \u0027raise NotImplementedError()\u0027","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    @classmethod"},{"line_number":134,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":135,"context_line":"        raise NotImplementedError"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def _get_changed_persistent_fields(self):"},{"line_number":138,"context_line":"        fields \u003d self.obj_get_changes()"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_f7e41f0e","line":135,"range":{"start_line":135,"start_character":14,"end_line":135,"end_character":33},"in_reply_to":"5a5ae5dd_f50bcd7b","updated":"2016-02-04 10:11:00.000000000","message":"Done","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    # should be overridden for all persistent objects"},{"line_number":100,"context_line":"    db_model \u003d None"},{"line_number":101,"context_line":"    binding_models \u003d None"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    primary_key \u003d \u0027id\u0027"},{"line_number":104,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_feea0ada","line":101,"updated":"2016-02-08 12:40:03.000000000","message":"I don\u0027t think this attribute belongs to all db objects. It\u0027s actually QoS Policy specific.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    # should be overridden for all persistent objects"},{"line_number":100,"context_line":"    db_model \u003d None"},{"line_number":101,"context_line":"    binding_models \u003d None"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    primary_key \u003d \u0027id\u0027"},{"line_number":104,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"3a57f1b5_1d6bc7f2","line":101,"in_reply_to":"5a5ae5dd_feea0ada","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        return objs"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    @classmethod"},{"line_number":134,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":135,"context_line":"        raise NotImplementedError()"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def _get_changed_persistent_fields(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_9ea756bc","line":134,"updated":"2016-02-08 12:40:03.000000000","message":"Should we provide some general implementation here, like checking that the context belongs either to an admin or to the owner of the db_obj?","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        return objs"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    @classmethod"},{"line_number":134,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":135,"context_line":"        raise NotImplementedError()"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def _get_changed_persistent_fields(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"3a57f1b5_837bd88b","line":134,"in_reply_to":"5a5ae5dd_9ea756bc","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"d08687721f3ac76091cf0b8bd9b35571aa2eac22","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        return objs"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    @classmethod"},{"line_number":134,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":135,"context_line":"        raise NotImplementedError()"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def _get_changed_persistent_fields(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_e3426567","line":134,"in_reply_to":"5a5ae5dd_9ea756bc","updated":"2016-02-08 16:01:54.000000000","message":"Similar to what I suggested on PS11, what Ihar says makes sense.\n\nhttps://review.openstack.org/#/c/250081/11..14/neutron/objects/base.py","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"}],"neutron/objects/qos/policy.py":[{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"e997782aaf49c1c408e5e40394e068c40b6076c2","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    port_binding_model \u003d qos_db_model.QosPortPolicyBinding"},{"line_number":34,"context_line":"    network_binding_model \u003d qos_db_model.QosNetworkPolicyBinding"},{"line_number":35,"context_line":"    rbac_binding_model \u003d rbac_db_models.QosPolicyRBAC"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    fields \u003d {"},{"line_number":38,"context_line":"        \u0027id\u0027: obj_fields.UUIDField(),"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_8820d0f8","line":35,"updated":"2015-12-02 11:02:38.000000000","message":"I don\u0027t like how we meld rbac implementation for versioned objects into policy object. It should be independent of the policy object, and just USED in it.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"7648de4f3f7b67eb7ce97d6634320c0d247fe36d","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    port_binding_model \u003d qos_db_model.QosPortPolicyBinding"},{"line_number":34,"context_line":"    network_binding_model \u003d qos_db_model.QosNetworkPolicyBinding"},{"line_number":35,"context_line":"    rbac_binding_model \u003d rbac_db_models.QosPolicyRBAC"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    fields \u003d {"},{"line_number":38,"context_line":"        \u0027id\u0027: obj_fields.UUIDField(),"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_025d9c46","line":35,"in_reply_to":"9a8ffd7b_7f375fff","updated":"2015-12-02 11:53:02.000000000","message":"No, I only mean that implementation for rbac attachments should be independent from policy, and reusable once we start to move more resources to objects (f.e. networks that already use the rbac models).","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"6ac3dce0b6e6c31f95c62f5a0495dc40c35d3ed6","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    port_binding_model \u003d qos_db_model.QosPortPolicyBinding"},{"line_number":34,"context_line":"    network_binding_model \u003d qos_db_model.QosNetworkPolicyBinding"},{"line_number":35,"context_line":"    rbac_binding_model \u003d rbac_db_models.QosPolicyRBAC"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    fields \u003d {"},{"line_number":38,"context_line":"        \u0027id\u0027: obj_fields.UUIDField(),"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_7f375fff","line":35,"in_reply_to":"9a8ffd7b_8820d0f8","updated":"2015-12-02 11:33:45.000000000","message":"@ihar, could you clarify?, do you mean creating an API for rbac binding models and using it from here?.\n\nI\u0027d guess RBAC doesn\u0027t need a neutron object by itself, as we don\u0027t expect to propagate that, but may be it\u0027s beneficial:\n\nThoughts?","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"e997782aaf49c1c408e5e40394e068c40b6076c2","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    fields_no_update \u003d [\u0027id\u0027, \u0027tenant_id\u0027]"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    synthetic_fields \u003d [\u0027rules\u0027, \u0027shared\u0027]"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def to_dict(self):"},{"line_number":51,"context_line":"        dict_ \u003d super(QosPolicy, self).to_dict()"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_48bc286c","line":48,"updated":"2015-12-02 11:02:38.000000000","message":"So where is the implementation of the synthetic field? (that would go in obj_load_attr).","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"e997782aaf49c1c408e5e40394e068c40b6076c2","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        dict_ \u003d super(QosPolicy, self).to_dict()"},{"line_number":52,"context_line":"        if \u0027rules\u0027 in dict_:"},{"line_number":53,"context_line":"            dict_[\u0027rules\u0027] \u003d [rule.to_dict() for rule in dict_[\u0027rules\u0027]]"},{"line_number":54,"context_line":"        dict_[\u0027shared\u0027] \u003d self._is_policy_shared_with_calling_tenant("},{"line_number":55,"context_line":"            self._context, self.id)"},{"line_number":56,"context_line":"        return dict_"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_4863c81a","line":54,"updated":"2015-12-02 11:02:38.000000000","message":"I believe that would belong to obj_load_attr that is used to initialize values for synthetic fields.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"756036fff71797af367e36a24fd3ccaad7c89455","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        dict_ \u003d super(QosPolicy, self).to_dict()"},{"line_number":52,"context_line":"        if \u0027rules\u0027 in dict_:"},{"line_number":53,"context_line":"            dict_[\u0027rules\u0027] \u003d [rule.to_dict() for rule in dict_[\u0027rules\u0027]]"},{"line_number":54,"context_line":"        dict_[\u0027shared\u0027] \u003d self._is_policy_shared_with_calling_tenant("},{"line_number":55,"context_line":"            self._context, self.id)"},{"line_number":56,"context_line":"        return dict_"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_e897178e","line":54,"in_reply_to":"9a8ffd7b_4863c81a","updated":"2015-12-02 12:22:59.000000000","message":"Done","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"74c7ccb25ccfc4fab0ce0f926081c285cc26aca7","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        return False"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"    @classmethod"},{"line_number":92,"context_line":"    def _is_policy_shared_globally(cls, context, policy_id):"},{"line_number":93,"context_line":"        return cls._is_policy_shared_with(context, policy_id, \u0027*\u0027)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_4dc75a12","line":92,"updated":"2015-12-02 10:47:24.000000000","message":"This one is not used, I guess you don\u0027t need it anymore since you have the *shared list ?","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"756036fff71797af367e36a24fd3ccaad7c89455","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        return False"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"    @classmethod"},{"line_number":92,"context_line":"    def _is_policy_shared_globally(cls, context, policy_id):"},{"line_number":93,"context_line":"        return cls._is_policy_shared_with(context, policy_id, \u0027*\u0027)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_e3cc1f63","line":92,"in_reply_to":"9a8ffd7b_4dc75a12","updated":"2015-12-02 12:22:59.000000000","message":"Done","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"74c7ccb25ccfc4fab0ce0f926081c285cc26aca7","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    def _is_policy_shared_globally(cls, context, policy_id):"},{"line_number":93,"context_line":"        return cls._is_policy_shared_with(context, policy_id, \u0027*\u0027)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    @classmethod"},{"line_number":96,"context_line":"    def _is_policy_shared_with_calling_tenant(cls, context, policy_id):"},{"line_number":97,"context_line":"        return cls._is_policy_shared_with(context, policy_id, \u0027*\u0027,"},{"line_number":98,"context_line":"                                          context.tenant_id)"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_4d951ae2","line":95,"updated":"2015-12-02 10:47:24.000000000","message":"(No action required): I\u0027d avoid this extra level of indirection and do it straight away in L103, since it\u0027s just one call, I believe it\u0027s clear.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"756036fff71797af367e36a24fd3ccaad7c89455","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    def _is_policy_shared_globally(cls, context, policy_id):"},{"line_number":93,"context_line":"        return cls._is_policy_shared_with(context, policy_id, \u0027*\u0027)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    @classmethod"},{"line_number":96,"context_line":"    def _is_policy_shared_with_calling_tenant(cls, context, policy_id):"},{"line_number":97,"context_line":"        return cls._is_policy_shared_with(context, policy_id, \u0027*\u0027,"},{"line_number":98,"context_line":"                                          context.tenant_id)"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_1f06531c","line":95,"in_reply_to":"9a8ffd7b_4d951ae2","updated":"2015-12-02 12:22:59.000000000","message":"Done","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"e997782aaf49c1c408e5e40394e068c40b6076c2","unresolved":false,"context_lines":[{"line_number":150,"context_line":"                                      port_id\u003dport_id)"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"    @classmethod"},{"line_number":153,"context_line":"    def get_bound_rbac_policies(cls, context, qos_policy_id):"},{"line_number":154,"context_line":"        return db_api.get_objects(context, cls.rbac_binding_model,"},{"line_number":155,"context_line":"                                  object_id\u003dqos_policy_id)"},{"line_number":156,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_085aa083","line":153,"updated":"2015-12-02 11:02:38.000000000","message":"that would probably go into some RBACNeutronObject or smth like that. It may be even some mixin that we meld into the object implementation.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"756036fff71797af367e36a24fd3ccaad7c89455","unresolved":false,"context_lines":[{"line_number":150,"context_line":"                                      port_id\u003dport_id)"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"    @classmethod"},{"line_number":153,"context_line":"    def get_bound_rbac_policies(cls, context, qos_policy_id):"},{"line_number":154,"context_line":"        return db_api.get_objects(context, cls.rbac_binding_model,"},{"line_number":155,"context_line":"                                  object_id\u003dqos_policy_id)"},{"line_number":156,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_68832757","line":153,"in_reply_to":"9a8ffd7b_085aa083","updated":"2015-12-02 12:22:59.000000000","message":"Done","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":14605,"name":"vikram.choudhary","email":"vikschw@gmail.com","username":"vikram.choudhary"},"change_message_id":"cbf6e1a630aa493ac8ded6790b3aa8def3f5cce2","unresolved":false,"context_lines":[{"line_number":229,"context_line":"                            object_type\u003dobject_type,"},{"line_number":230,"context_line":"                            object_id\u003ddb_obj[\u0027%s_id\u0027 % object_type])"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"    def _update_shared(self):"},{"line_number":233,"context_line":"        \"\"\"The shared attribute reflects whether the policy is shared to the"},{"line_number":234,"context_line":"        calling tenant via RBAC entry."},{"line_number":235,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"5a710552_55105b01","line":232,"updated":"2015-12-16 09:26:11.000000000","message":"How about registering callbacks for getting notification about \"RBAC_POLICY\" resource?","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"46700008826cc88fbbfef7ce857bbc8c84e8948d","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        dict_ \u003d super(QosPolicy, self).to_dict()"},{"line_number":61,"context_line":"        if \u0027rules\u0027 in dict_:"},{"line_number":62,"context_line":"            dict_[\u0027rules\u0027] \u003d [rule.to_dict() for rule in dict_[\u0027rules\u0027]]"},{"line_number":63,"context_line":"        dict_[\u0027shared\u0027] \u003d \\"},{"line_number":64,"context_line":"            rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":65,"context_line":"                    self._context, rbac_db_models.QosPolicyRBAC, self.id,"},{"line_number":66,"context_line":"                    self._context.tenant_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_d42257b9","line":63,"updated":"2015-12-17 07:24:02.000000000","message":"can you write this without the\\?","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"60e6eff57a2b48be492c1057418254c5c0d01f13","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        dict_ \u003d super(QosPolicy, self).to_dict()"},{"line_number":61,"context_line":"        if \u0027rules\u0027 in dict_:"},{"line_number":62,"context_line":"            dict_[\u0027rules\u0027] \u003d [rule.to_dict() for rule in dict_[\u0027rules\u0027]]"},{"line_number":63,"context_line":"        dict_[\u0027shared\u0027] \u003d \\"},{"line_number":64,"context_line":"            rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":65,"context_line":"                    self._context, rbac_db_models.QosPolicyRBAC, self.id,"},{"line_number":66,"context_line":"                    self._context.tenant_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_8fe27c9e","line":63,"in_reply_to":"3a7e1126_d42257b9","updated":"2015-12-17 07:49:32.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"723ed1eb65071db1eb4da66115e504c7bc50d14d","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        if \u0027rules\u0027 in dict_:"},{"line_number":62,"context_line":"            dict_[\u0027rules\u0027] \u003d [rule.to_dict() for rule in dict_[\u0027rules\u0027]]"},{"line_number":63,"context_line":"        dict_[\u0027shared\u0027] \u003d \\"},{"line_number":64,"context_line":"            rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":65,"context_line":"                    self._context, rbac_db_models.QosPolicyRBAC, self.id,"},{"line_number":66,"context_line":"                    self._context.tenant_id)"},{"line_number":67,"context_line":"        return dict_"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_e879a594","line":64,"updated":"2015-12-17 11:09:46.000000000","message":"That\u0027s not what I meant. My expectation was that there will be an easy way to meld something in an object (ideally with one line in inheritance list) that would take care of RBAC. So that next time we need RBAC for an object, we don\u0027t spread the RBAC code into its implenentation. The assumption is that there will be no RBAC code in policy.py, but it will be just enabled in some loose way from external module.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"e1d2161e90d458481a5828eaad6a58acc9e7c67a","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        if \u0027rules\u0027 in dict_:"},{"line_number":62,"context_line":"            dict_[\u0027rules\u0027] \u003d [rule.to_dict() for rule in dict_[\u0027rules\u0027]]"},{"line_number":63,"context_line":"        dict_[\u0027shared\u0027] \u003d \\"},{"line_number":64,"context_line":"            rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":65,"context_line":"                    self._context, rbac_db_models.QosPolicyRBAC, self.id,"},{"line_number":66,"context_line":"                    self._context.tenant_id)"},{"line_number":67,"context_line":"        return dict_"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_22034144","line":64,"in_reply_to":"3a7e1126_1fd21e01","updated":"2015-12-17 13:03:34.000000000","message":"In line 148, you can find a TODO that we left in initial dev phase to tackle something similar. The idea would be that each object can declare additional steps to take on each base CRUD operation. Those operations could be defined as class attributes, that are collected and executed by base class.\n\nIn that way, you could have RBAC mixin that defines an additional action for each operation you mentioned. The policy object itself would also define reload_rules() as such. Then base class would make sure both are called.\n\nAs for self.shared property, I suspect its definition could also be moved into that RBAC mixin class.\n\nIf you (reasonably) don\u0027t like mixins, I am fine if you instead implement it as a metaclass that will set the action and tinker the fields list for you if called on a class.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"9012ba4b0bb8cef13367c72a0ae8b7b093afdcae","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        if \u0027rules\u0027 in dict_:"},{"line_number":62,"context_line":"            dict_[\u0027rules\u0027] \u003d [rule.to_dict() for rule in dict_[\u0027rules\u0027]]"},{"line_number":63,"context_line":"        dict_[\u0027shared\u0027] \u003d \\"},{"line_number":64,"context_line":"            rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":65,"context_line":"                    self._context, rbac_db_models.QosPolicyRBAC, self.id,"},{"line_number":66,"context_line":"                    self._context.tenant_id)"},{"line_number":67,"context_line":"        return dict_"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_6eb932e9","line":64,"in_reply_to":"3a7e1126_22034144","updated":"2015-12-17 13:36:14.000000000","message":"Unrelated to the disuccsion: lines 64-66 are code duplications, you might as well call _is_policy_accessible().","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"30599cd74aa21f58b1c83a0b115dfe06302ef5c4","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        if \u0027rules\u0027 in dict_:"},{"line_number":62,"context_line":"            dict_[\u0027rules\u0027] \u003d [rule.to_dict() for rule in dict_[\u0027rules\u0027]]"},{"line_number":63,"context_line":"        dict_[\u0027shared\u0027] \u003d \\"},{"line_number":64,"context_line":"            rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":65,"context_line":"                    self._context, rbac_db_models.QosPolicyRBAC, self.id,"},{"line_number":66,"context_line":"                    self._context.tenant_id)"},{"line_number":67,"context_line":"        return dict_"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_3fb7c8d9","line":64,"in_reply_to":"3a7e1126_6eb932e9","updated":"2015-12-17 15:59:47.000000000","message":"is_policy_accessible() will return \u0027True\u0027 for admin, regardless whether the policy is shared or not - and that breaks the existing logic which we want to preserve.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"89fa518eaa4f082f475a339923a3672dee0407ba","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        if \u0027rules\u0027 in dict_:"},{"line_number":62,"context_line":"            dict_[\u0027rules\u0027] \u003d [rule.to_dict() for rule in dict_[\u0027rules\u0027]]"},{"line_number":63,"context_line":"        dict_[\u0027shared\u0027] \u003d \\"},{"line_number":64,"context_line":"            rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":65,"context_line":"                    self._context, rbac_db_models.QosPolicyRBAC, self.id,"},{"line_number":66,"context_line":"                    self._context.tenant_id)"},{"line_number":67,"context_line":"        return dict_"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_1fd21e01","line":64,"in_reply_to":"3a7e1126_ac372aaf","updated":"2015-12-17 12:53:58.000000000","message":"I understand you point. But please consider the flow of QosPolicy create() in case the RBAC is a inherited mixin. In order for RBAC logic to kick in, QosPolicy.create() still needs to call the RBACMixin logic, and pass it the shared flag.\n\nSame goes to get_by_id() and update(). I\u0027d really appreciate  some guidance here on the code organization from your perspective.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"b592ec5baf041bfe5f23701dc8d2d73546ff6116","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        if \u0027rules\u0027 in dict_:"},{"line_number":62,"context_line":"            dict_[\u0027rules\u0027] \u003d [rule.to_dict() for rule in dict_[\u0027rules\u0027]]"},{"line_number":63,"context_line":"        dict_[\u0027shared\u0027] \u003d \\"},{"line_number":64,"context_line":"            rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":65,"context_line":"                    self._context, rbac_db_models.QosPolicyRBAC, self.id,"},{"line_number":66,"context_line":"                    self._context.tenant_id)"},{"line_number":67,"context_line":"        return dict_"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_f7817c90","line":64,"in_reply_to":"3a7e1126_e879a594","updated":"2015-12-17 12:14:11.000000000","message":"After completely rewriting this (twice) once as RBACNeutronObjectMixin and once as RBACNeutronObject- I realized:\n1.that mixins \u0026\u0026 multiple inheritance are evil\n2.that RBAC policy is something that the QosPolicy (or Network for that matter) have, not something that they are. In that sense the RBAC logic feels more like a utils library than an abstract class.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"2132b10c9e463a92cf63d3ec1bee6161ce26d736","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        if \u0027rules\u0027 in dict_:"},{"line_number":62,"context_line":"            dict_[\u0027rules\u0027] \u003d [rule.to_dict() for rule in dict_[\u0027rules\u0027]]"},{"line_number":63,"context_line":"        dict_[\u0027shared\u0027] \u003d \\"},{"line_number":64,"context_line":"            rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":65,"context_line":"                    self._context, rbac_db_models.QosPolicyRBAC, self.id,"},{"line_number":66,"context_line":"                    self._context.tenant_id)"},{"line_number":67,"context_line":"        return dict_"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_ac372aaf","line":64,"in_reply_to":"3a7e1126_f7817c90","updated":"2015-12-17 12:34:14.000000000","message":"I can\u0027t agree with the need to produce a bunch of new duplicate code every time we need a new object with rbac.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":92,"context_line":"                                         rule_id\u003drule_id)"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    @classmethod"},{"line_number":95,"context_line":"    def _is_policy_accessible(cls, context, db_obj_id):"},{"line_number":96,"context_line":"        return context.is_admin or \\"},{"line_number":97,"context_line":"               rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":98,"context_line":"                       context, rbac_db_models.QosPolicyRBAC, db_obj_id,"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_5c52f768","line":95,"range":{"start_line":95,"start_character":8,"end_line":95,"end_character":29},"updated":"2015-12-17 13:17:04.000000000","message":"+1 on removing this TODO. I remember adding this back when we worked on this :)","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"46700008826cc88fbbfef7ce857bbc8c84e8948d","unresolved":false,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    @classmethod"},{"line_number":95,"context_line":"    def _is_policy_accessible(cls, context, db_obj_id):"},{"line_number":96,"context_line":"        return context.is_admin or \\"},{"line_number":97,"context_line":"               rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":98,"context_line":"                       context, rbac_db_models.QosPolicyRBAC, db_obj_id,"},{"line_number":99,"context_line":"                       context.tenant_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_0f252caa","line":96,"updated":"2015-12-17 07:24:02.000000000","message":"return (context.is_admin or\n            rbac...)","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"60e6eff57a2b48be492c1057418254c5c0d01f13","unresolved":false,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    @classmethod"},{"line_number":95,"context_line":"    def _is_policy_accessible(cls, context, db_obj_id):"},{"line_number":96,"context_line":"        return context.is_admin or \\"},{"line_number":97,"context_line":"               rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":98,"context_line":"                       context, rbac_db_models.QosPolicyRBAC, db_obj_id,"},{"line_number":99,"context_line":"                       context.tenant_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_efb5407e","line":96,"in_reply_to":"3a7e1126_0f252caa","updated":"2015-12-17 07:49:32.000000000","message":"AFAIK return is not a function, so why are the redundant parenthesis required ?","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"30599cd74aa21f58b1c83a0b115dfe06302ef5c4","unresolved":false,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    @classmethod"},{"line_number":95,"context_line":"    def _is_policy_accessible(cls, context, db_obj_id):"},{"line_number":96,"context_line":"        return context.is_admin or \\"},{"line_number":97,"context_line":"               rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":98,"context_line":"                       context, rbac_db_models.QosPolicyRBAC, db_obj_id,"},{"line_number":99,"context_line":"                       context.tenant_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_dfc6c448","line":96,"in_reply_to":"3a7e1126_7c8333cd","updated":"2015-12-17 15:59:47.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    @classmethod"},{"line_number":95,"context_line":"    def _is_policy_accessible(cls, context, db_obj_id):"},{"line_number":96,"context_line":"        return context.is_admin or \\"},{"line_number":97,"context_line":"               rbac_db_mixin.RBACNeutronObject.is_shared_with_tenant("},{"line_number":98,"context_line":"                       context, rbac_db_models.QosPolicyRBAC, db_obj_id,"},{"line_number":99,"context_line":"                       context.tenant_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_7c8333cd","line":96,"in_reply_to":"3a7e1126_efb5407e","updated":"2015-12-17 13:17:04.000000000","message":"So that you can avoid the \\ at the end of the line. +1 to Gary\u0027s suggestion.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"2132b10c9e463a92cf63d3ec1bee6161ce26d736","unresolved":false,"context_lines":[{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    def delete(self):"},{"line_number":157,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":158,"context_line":"            for object_type, model in six.iteritems(self.binding_models):"},{"line_number":159,"context_line":"                binding_db_obj \u003d db_api.get_object(self._context, model,"},{"line_number":160,"context_line":"                                                   policy_id\u003dself.id)"},{"line_number":161,"context_line":"                if binding_db_obj:"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_ac05eac2","line":158,"updated":"2015-12-17 12:34:14.000000000","message":"don\u0027t use six.iteritems pretty much ever, unless we really have some performance concerns.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"e1d2161e90d458481a5828eaad6a58acc9e7c67a","unresolved":false,"context_lines":[{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    def delete(self):"},{"line_number":157,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":158,"context_line":"            for object_type, model in six.iteritems(self.binding_models):"},{"line_number":159,"context_line":"                binding_db_obj \u003d db_api.get_object(self._context, model,"},{"line_number":160,"context_line":"                                                   policy_id\u003dself.id)"},{"line_number":161,"context_line":"                if binding_db_obj:"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_821475f5","line":158,"in_reply_to":"3a7e1126_3f66faed","updated":"2015-12-17 13:03:34.000000000","message":"Just .items() is pretty much always ok.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"30599cd74aa21f58b1c83a0b115dfe06302ef5c4","unresolved":false,"context_lines":[{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    def delete(self):"},{"line_number":157,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":158,"context_line":"            for object_type, model in six.iteritems(self.binding_models):"},{"line_number":159,"context_line":"                binding_db_obj \u003d db_api.get_object(self._context, model,"},{"line_number":160,"context_line":"                                                   policy_id\u003dself.id)"},{"line_number":161,"context_line":"                if binding_db_obj:"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_ffe700e2","line":158,"in_reply_to":"3a7e1126_821475f5","updated":"2015-12-17 15:59:47.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"89fa518eaa4f082f475a339923a3672dee0407ba","unresolved":false,"context_lines":[{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    def delete(self):"},{"line_number":157,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":158,"context_line":"            for object_type, model in six.iteritems(self.binding_models):"},{"line_number":159,"context_line":"                binding_db_obj \u003d db_api.get_object(self._context, model,"},{"line_number":160,"context_line":"                                                   policy_id\u003dself.id)"},{"line_number":161,"context_line":"                if binding_db_obj:"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_3f66faed","line":158,"in_reply_to":"3a7e1126_ac05eac2","updated":"2015-12-17 12:53:58.000000000","message":"the orig code here was self.binding_models.iteritems() . tox -e py27 kindly rejected that, and suggested using six. I trust tox. I trust you. What should I do now ?","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"63021e22375a0e116aab4274c5f9302a834fa46a","unresolved":false,"context_lines":[{"line_number":187,"context_line":"                                              port_id\u003dport_id)"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"    def get_bound_objects(self):"},{"line_number":190,"context_line":"        return [db_api.get_objects(self._context, model,"},{"line_number":191,"context_line":"                                   policy_id\u003dself.id) for model in"},{"line_number":192,"context_line":"                self.binding_models.values()]"},{"line_number":193,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_423f6db4","line":190,"range":{"start_line":190,"start_character":9,"end_line":190,"end_character":14},"updated":"2015-12-17 13:17:04.000000000","message":"Possible bug: this returns a nested list, ie. [ [\u003cnetwork-bound objects\u003e], [\u003cport-bound objects\u003e] ], but RBACNeutronObject does not treat this list as a nested list. You probably want to flatten() the returned value.","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"30599cd74aa21f58b1c83a0b115dfe06302ef5c4","unresolved":false,"context_lines":[{"line_number":187,"context_line":"                                              port_id\u003dport_id)"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"    def get_bound_objects(self):"},{"line_number":190,"context_line":"        return [db_api.get_objects(self._context, model,"},{"line_number":191,"context_line":"                                   policy_id\u003dself.id) for model in"},{"line_number":192,"context_line":"                self.binding_models.values()]"},{"line_number":193,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_ffb62089","line":190,"range":{"start_line":190,"start_character":9,"end_line":190,"end_character":14},"in_reply_to":"3a7e1126_423f6db4","updated":"2015-12-17 15:59:47.000000000","message":"Done","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"89dc6c8a83f2209990487100aaaa8ffea9924539","unresolved":false,"context_lines":[{"line_number":12,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":13,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":"import itertools"},{"line_number":16,"context_line":"from oslo_versionedobjects import base as obj_base"},{"line_number":17,"context_line":"from oslo_versionedobjects import fields as obj_fields"},{"line_number":18,"context_line":"from six import add_metaclass"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_d0ac9fef","line":15,"range":{"start_line":15,"start_character":0,"end_line":15,"end_character":16},"updated":"2016-02-03 13:44:40.000000000","message":"Please enter a whitespace line between the first import and the license documentation (so push line 15 down one line to 16).","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":12,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":13,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":"import itertools"},{"line_number":16,"context_line":"from oslo_versionedobjects import base as obj_base"},{"line_number":17,"context_line":"from oslo_versionedobjects import fields as obj_fields"},{"line_number":18,"context_line":"from six import add_metaclass"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_f7cbbf70","line":15,"range":{"start_line":15,"start_character":0,"end_line":15,"end_character":16},"in_reply_to":"5a5ae5dd_d0ac9fef","updated":"2016-02-04 10:11:00.000000000","message":"Done","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"89dc6c8a83f2209990487100aaaa8ffea9924539","unresolved":false,"context_lines":[{"line_number":182,"context_line":"        qosnet \u003d qos_db_model.QosNetworkPolicyBinding"},{"line_number":183,"context_line":"        port \u003d models_v2.Port"},{"line_number":184,"context_line":"        qosport \u003d qos_db_model.QosPortPolicyBinding"},{"line_number":185,"context_line":"        flatten \u003d itertools.chain.from_iterable"},{"line_number":186,"context_line":"        with db_api.autonested_transaction(context.session):"},{"line_number":187,"context_line":"            ret \u003d list(flatten(context.session.query(net.tenant_id).join("},{"line_number":188,"context_line":"                qosnet, net.id \u003d\u003d qosnet.network_id).filter("}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_8904bd15","line":185,"range":{"start_line":185,"start_character":8,"end_line":185,"end_character":47},"updated":"2016-02-03 13:44:40.000000000","message":"The way it is now, both this function and RbacNeutronObject define \u0027flatten\u0027. Preferably define a single function \u0027flatten\u0027 someplace shared (like neutron/db/rbac_db_mixin.py or neutron/common/) and use that one for both calls.","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":182,"context_line":"        qosnet \u003d qos_db_model.QosNetworkPolicyBinding"},{"line_number":183,"context_line":"        port \u003d models_v2.Port"},{"line_number":184,"context_line":"        qosport \u003d qos_db_model.QosPortPolicyBinding"},{"line_number":185,"context_line":"        flatten \u003d itertools.chain.from_iterable"},{"line_number":186,"context_line":"        with db_api.autonested_transaction(context.session):"},{"line_number":187,"context_line":"            ret \u003d list(flatten(context.session.query(net.tenant_id).join("},{"line_number":188,"context_line":"                qosnet, net.id \u003d\u003d qosnet.network_id).filter("}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_ef665f28","line":185,"range":{"start_line":185,"start_character":8,"end_line":185,"end_character":47},"in_reply_to":"5a5ae5dd_8904bd15","updated":"2016-02-04 10:11:00.000000000","message":"I\u0027ve reduced the L187+L191 to single function call, which will return the list(itertools.chain.from_iterable(result)),\nso no need in defining that function externally","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"89dc6c8a83f2209990487100aaaa8ffea9924539","unresolved":false,"context_lines":[{"line_number":188,"context_line":"                qosnet, net.id \u003d\u003d qosnet.network_id).filter("},{"line_number":189,"context_line":"                qosnet.policy_id \u003d\u003d obj_id).all()))"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"            ret.extend(list(flatten(context.session.query(port.tenant_id).join("},{"line_number":192,"context_line":"                qosport, port.id \u003d\u003d qosport.port_id).filter("},{"line_number":193,"context_line":"                qosport.policy_id \u003d\u003d obj_id).all())))"},{"line_number":194,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_29e7c9e5","line":191,"range":{"start_line":191,"start_character":12,"end_line":191,"end_character":23},"updated":"2016-02-03 13:44:40.000000000","message":"This statement is a duplication with the former statement. We can probably define a function that receives the binding model and the id field and runs the result.","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":188,"context_line":"                qosnet, net.id \u003d\u003d qosnet.network_id).filter("},{"line_number":189,"context_line":"                qosnet.policy_id \u003d\u003d obj_id).all()))"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"            ret.extend(list(flatten(context.session.query(port.tenant_id).join("},{"line_number":192,"context_line":"                qosport, port.id \u003d\u003d qosport.port_id).filter("},{"line_number":193,"context_line":"                qosport.policy_id \u003d\u003d obj_id).all())))"},{"line_number":194,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"5a5ae5dd_8f6d6b06","line":191,"range":{"start_line":191,"start_character":12,"end_line":191,"end_character":23},"in_reply_to":"5a5ae5dd_29e7c9e5","updated":"2016-02-04 10:11:00.000000000","message":"Done","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":13,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import itertools"},{"line_number":17,"context_line":"from oslo_versionedobjects import base as obj_base"},{"line_number":18,"context_line":"from oslo_versionedobjects import fields as obj_fields"},{"line_number":19,"context_line":"from six import add_metaclass"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_571f895a","line":16,"updated":"2016-02-08 12:40:03.000000000","message":"nit: itertools is stdlib, should have newline after line 16.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":13,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import itertools"},{"line_number":17,"context_line":"from oslo_versionedobjects import base as obj_base"},{"line_number":18,"context_line":"from oslo_versionedobjects import fields as obj_fields"},{"line_number":19,"context_line":"from six import add_metaclass"}],"source_content_type":"text/x-python","patch_set":14,"id":"3a57f1b5_c350f0d6","line":16,"in_reply_to":"5a5ae5dd_571f895a","updated":"2016-02-15 22:48:57.000000000","message":"argh, I really should get this into pep8 env","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"07f8140c3caf9072cc1ae3a86ccbc7d3ade2155b","unresolved":false,"context_lines":[{"line_number":177,"context_line":"                                              policy_id\u003dself.id,"},{"line_number":178,"context_line":"                                              port_id\u003dport_id)"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"    @classmethod"},{"line_number":181,"context_line":"    def _get_bound_tenant_ids(cls, session, binding_db, bound_db,"},{"line_number":182,"context_line":"                              binding_db_id_column, policy_id):"},{"line_number":183,"context_line":"        return list(itertools.chain.from_iterable("}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_0337814d","line":180,"updated":"2016-02-08 16:16:13.000000000","message":"Just curious as to the decision to use classmethod vs staticmethod (or plain method)? Is there an intention of inheriting from the QosPolicy class?","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":177,"context_line":"                                              policy_id\u003dself.id,"},{"line_number":178,"context_line":"                                              port_id\u003dport_id)"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"    @classmethod"},{"line_number":181,"context_line":"    def _get_bound_tenant_ids(cls, session, binding_db, bound_db,"},{"line_number":182,"context_line":"                              binding_db_id_column, policy_id):"},{"line_number":183,"context_line":"        return list(itertools.chain.from_iterable("}],"source_content_type":"text/x-python","patch_set":14,"id":"3a57f1b5_23a9c490","line":180,"in_reply_to":"5a5ae5dd_0337814d","updated":"2016-02-15 22:48:57.000000000","message":"No, there isn\u0027t any intention at the moment, I guess it\u0027s my personal preference to keep the code logically grouped together.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":191,"context_line":"        qosnet \u003d qos_db_model.QosNetworkPolicyBinding"},{"line_number":192,"context_line":"        port \u003d models_v2.Port"},{"line_number":193,"context_line":"        qosport \u003d qos_db_model.QosPortPolicyBinding"},{"line_number":194,"context_line":"        ret \u003d []"},{"line_number":195,"context_line":"        with db_api.autonested_transaction(context.session):"},{"line_number":196,"context_line":"            ret.extend(cls._get_bound_tenant_ids("},{"line_number":197,"context_line":"                context.session, qosnet, net, qosnet.network_id, policy_id))"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_7e15ba99","line":194,"updated":"2016-02-08 12:40:03.000000000","message":"nit: rename ret to something more specific (like \u0027bound_tenants\u0027)","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"d08687721f3ac76091cf0b8bd9b35571aa2eac22","unresolved":false,"context_lines":[{"line_number":191,"context_line":"        qosnet \u003d qos_db_model.QosNetworkPolicyBinding"},{"line_number":192,"context_line":"        port \u003d models_v2.Port"},{"line_number":193,"context_line":"        qosport \u003d qos_db_model.QosPortPolicyBinding"},{"line_number":194,"context_line":"        ret \u003d []"},{"line_number":195,"context_line":"        with db_api.autonested_transaction(context.session):"},{"line_number":196,"context_line":"            ret.extend(cls._get_bound_tenant_ids("},{"line_number":197,"context_line":"                context.session, qosnet, net, qosnet.network_id, policy_id))"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_473a6e9a","line":194,"in_reply_to":"5a5ae5dd_7e15ba99","updated":"2016-02-08 16:01:54.000000000","message":"+1","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":191,"context_line":"        qosnet \u003d qos_db_model.QosNetworkPolicyBinding"},{"line_number":192,"context_line":"        port \u003d models_v2.Port"},{"line_number":193,"context_line":"        qosport \u003d qos_db_model.QosPortPolicyBinding"},{"line_number":194,"context_line":"        ret \u003d []"},{"line_number":195,"context_line":"        with db_api.autonested_transaction(context.session):"},{"line_number":196,"context_line":"            ret.extend(cls._get_bound_tenant_ids("},{"line_number":197,"context_line":"                context.session, qosnet, net, qosnet.network_id, policy_id))"}],"source_content_type":"text/x-python","patch_set":14,"id":"3a57f1b5_4385e004","line":194,"in_reply_to":"5a5ae5dd_7e15ba99","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":198,"context_line":"            ret.extend("},{"line_number":199,"context_line":"                cls._get_bound_tenant_ids(context.session, qosport, port,"},{"line_number":200,"context_line":"                                          qosport.port_id, policy_id))"},{"line_number":201,"context_line":"        return ret"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_7ef13a6a","line":201,"updated":"2016-02-08 12:40:03.000000000","message":"nit: I think the list can contain duplicates. Should we remove them (f.e. by using set instead of list)?","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"d08687721f3ac76091cf0b8bd9b35571aa2eac22","unresolved":false,"context_lines":[{"line_number":198,"context_line":"            ret.extend("},{"line_number":199,"context_line":"                cls._get_bound_tenant_ids(context.session, qosport, port,"},{"line_number":200,"context_line":"                                          qosport.port_id, policy_id))"},{"line_number":201,"context_line":"        return ret"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_e7491a32","line":201,"in_reply_to":"5a5ae5dd_7ef13a6a","updated":"2016-02-08 16:01:54.000000000","message":"a set sounds good to me.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    binding_models \u003d {\u0027network\u0027: network_binding_model,"},{"line_number":61,"context_line":"                      \u0027port\u0027: port_binding_model}"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    @rbac_db_mixin.rbac_proxy_method"},{"line_number":64,"context_line":"    def to_dict(self):"},{"line_number":65,"context_line":"        dict_ \u003d super(QosPolicy, self).to_dict()"},{"line_number":66,"context_line":"        if \u0027rules\u0027 in dict_:"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_5e1e7f5f","line":63,"updated":"2016-02-23 15:32:36.000000000","message":"The code in metaclass should take care of modifying the methods, you should not need to do anything explicitly here except applying the metaclass and maybe providing some object specific method implementations like to fetch tenant-ids below.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":140,"context_line":"        return cls._get_object_policy(context, cls.port_binding_model,"},{"line_number":141,"context_line":"                                      port_id\u003dport_id)"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"    @rbac_db_mixin.rbac_proxy_method"},{"line_number":144,"context_line":"    def update(self):"},{"line_number":145,"context_line":"        return super(QosPolicy, self).update()"},{"line_number":146,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_9e3c87c9","line":143,"updated":"2016-02-23 15:32:36.000000000","message":"ditto","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        return super(QosPolicy, self).update()"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"    # TODO(QoS): Consider extending base to trigger registered methods for us"},{"line_number":148,"context_line":"    @rbac_db_mixin.rbac_proxy_method"},{"line_number":149,"context_line":"    def create(self):"},{"line_number":150,"context_line":"        with db_api.autonested_transaction(self._context.session):"},{"line_number":151,"context_line":"            super(QosPolicy, self).create()"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_1e4fd76b","line":148,"updated":"2016-02-23 15:32:36.000000000","message":"ditto","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c52d9d3e604991a0ae8ad58938ac3cb1bfc5d10c","unresolved":false,"context_lines":[{"line_number":187,"context_line":"    @classmethod"},{"line_number":188,"context_line":"    def _get_bound_tenant_ids(cls, session, binding_db, bound_db,"},{"line_number":189,"context_line":"                              binding_db_id_column, policy_id):"},{"line_number":190,"context_line":"        return list(itertools.chain.from_iterable("},{"line_number":191,"context_line":"            session.query(bound_db.tenant_id).join("},{"line_number":192,"context_line":"                binding_db, bound_db.id \u003d\u003d binding_db_id_column).filter("},{"line_number":193,"context_line":"                binding_db.policy_id \u003d\u003d policy_id).all()))"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_fe3dd38f","line":190,"updated":"2016-02-23 15:32:36.000000000","message":"My understanding is that this will still return a list of attr-value tuples, and you probably want just the value parts.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"8b0a36f87d5562beb844b699d8016e60b5580e8a","unresolved":false,"context_lines":[{"line_number":187,"context_line":"    @classmethod"},{"line_number":188,"context_line":"    def _get_bound_tenant_ids(cls, session, binding_db, bound_db,"},{"line_number":189,"context_line":"                              binding_db_id_column, policy_id):"},{"line_number":190,"context_line":"        return list(itertools.chain.from_iterable("},{"line_number":191,"context_line":"            session.query(bound_db.tenant_id).join("},{"line_number":192,"context_line":"                binding_db, bound_db.id \u003d\u003d binding_db_id_column).filter("},{"line_number":193,"context_line":"                binding_db.policy_id \u003d\u003d policy_id).all()))"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_13c98826","line":190,"in_reply_to":"bae84128_fe3dd38f","updated":"2016-02-23 21:25:32.000000000","message":"No - the _get_bound_get_tenant_ids() returns a list of tenant_ids.","commit_id":"414c0c6aedcb8465803ad928e45af2ca7cdabef9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":187,"context_line":"                binding_db.policy_id \u003d\u003d policy_id).all()))"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"    @classmethod"},{"line_number":190,"context_line":"    def get_bound_tenant_ids(cls, context, policy_id):"},{"line_number":191,"context_line":"        \"\"\"Implements RbacNeutronObject.get_bound_tenant_ids."},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"        :returns: set -- a set of tenants\u0027 ids dependant on QosPolicy."}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_c6a24f9a","line":190,"updated":"2016-02-25 11:00:39.000000000","message":"that method lacks unit tests. I would like to see it covered to make sure we indeed return a list of strings and not tuples.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":187,"context_line":"                binding_db.policy_id \u003d\u003d policy_id).all()))"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"    @classmethod"},{"line_number":190,"context_line":"    def get_bound_tenant_ids(cls, context, policy_id):"},{"line_number":191,"context_line":"        \"\"\"Implements RbacNeutronObject.get_bound_tenant_ids."},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"        :returns: set -- a set of tenants\u0027 ids dependant on QosPolicy."}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_0bf9d0c8","line":190,"in_reply_to":"bae84128_c6a24f9a","updated":"2016-02-25 17:24:55.000000000","message":"Done.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"}],"neutron/objects/rbac_db.py":[{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e18268b5cfdcbbadfd9dcc5df921fef183a3ade9","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                         [\u0027*\u0027, tenant_id]))).count() !\u003d 0)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    @classmethod"},{"line_number":64,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":65,"context_line":"        return (super("},{"line_number":66,"context_line":"            RbacNeutronDbObjectMixin, cls).is_accessible(context, db_obj) or"},{"line_number":67,"context_line":"                cls.is_shared_with_tenant(context, db_obj.id,"}],"source_content_type":"text/x-python","patch_set":32,"id":"9aed3d3a_8f6313dc","line":64,"updated":"2016-02-26 18:55:03.000000000","message":"The reason I had wanted this renamed is that both \u0027access_as_external\u0027 and \u0027access_as_shared\u0027 are different forms of access allowed to a network by a tenant. However, this is just specific to \u0027access_as_shared\u0027. However, we can revisit this when we convert networks to use this.","commit_id":"aeaf77a5295080a3010a2e9c32e24f47c8cc73cc"}],"neutron/objects/rbac_neutron_db.py":[{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"520eb2d13054f851074d231f708846ad4f9c9332","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 Red Hat, Inc."},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_5d3e2c2a","line":1,"range":{"start_line":1,"start_character":12,"end_line":1,"end_character":16},"updated":"2016-02-24 20:25:40.000000000","message":"2016","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 Red Hat, Inc."},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_a1f71c58","line":1,"range":{"start_line":1,"start_character":12,"end_line":1,"end_character":16},"in_reply_to":"bae84128_32a531b5","updated":"2016-02-25 17:24:55.000000000","message":"Done","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 Red Hat, Inc."},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_32a531b5","line":1,"range":{"start_line":1,"start_character":12,"end_line":1,"end_character":16},"in_reply_to":"bae84128_3c935551","updated":"2016-02-25 11:00:39.000000000","message":"File name is a bit redundant. I suggest neutron/objects/rbac_db.py","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"29fae5eb31879d24f269464c74aa5c33246d865b","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 Red Hat, Inc."},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_3c935551","line":1,"range":{"start_line":1,"start_character":12,"end_line":1,"end_character":16},"in_reply_to":"bae84128_5d3e2c2a","updated":"2016-02-25 09:18:55.000000000","message":"I actually wrote this module in 2015, wan\u0027t sure about the time stamp. \nWill update to 2016 - makes it feel fresh :)","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":"import abc"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"import itertools"},{"line_number":18,"context_line":"from six import add_metaclass"},{"line_number":19,"context_line":"from sqlalchemy import and_"},{"line_number":20,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_06c4373e","line":17,"updated":"2016-02-25 11:00:39.000000000","message":"nit: itertools is also stdlib, should go into the section above.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":"import abc"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"import itertools"},{"line_number":18,"context_line":"from six import add_metaclass"},{"line_number":19,"context_line":"from sqlalchemy import and_"},{"line_number":20,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_e8ee3cb3","line":17,"in_reply_to":"bae84128_06c4373e","updated":"2016-02-25 17:24:55.000000000","message":"Done","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":50,"context_line":"        \"\"\""},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    @classmethod"},{"line_number":53,"context_line":"    def is_shared_with_tenant(cls, context, obj_id, tenant_id):"},{"line_number":54,"context_line":"        ctx \u003d context.elevated()"},{"line_number":55,"context_line":"        rbac_db_model \u003d cls.rbac_db_model"},{"line_number":56,"context_line":"        with ctx.session.begin(subtransactions\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_395d1ced","line":53,"updated":"2016-02-25 11:00:39.000000000","message":"This method has no reason to be defined on the object. The only thing it needs is rbac_db_model, so it could be extracted by the is_accessible caller and passed into the function.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":50,"context_line":"        \"\"\""},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    @classmethod"},{"line_number":53,"context_line":"    def is_shared_with_tenant(cls, context, obj_id, tenant_id):"},{"line_number":54,"context_line":"        ctx \u003d context.elevated()"},{"line_number":55,"context_line":"        rbac_db_model \u003d cls.rbac_db_model"},{"line_number":56,"context_line":"        with ctx.session.begin(subtransactions\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_4ebbf10e","line":53,"in_reply_to":"bae84128_395d1ced","updated":"2016-02-25 17:24:55.000000000","message":"This is exactly how this method was defined: \nhttps://review.openstack.org/#/c/250081/24..25/neutron/db/rbac_db_mixin.py\n\nI\u0027ve removed the rbac_db_model per your review comment, and as discussed - I prefer keeping the function as part of the class for:\n1. better IMO code organization + readability\n2. this method can be potentially overridden later on, by patched class to adapt it\u0027s meaning.\n\nWe can refactor that later on.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    @classmethod"},{"line_number":64,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":65,"context_line":"        return (context.is_admin or"},{"line_number":66,"context_line":"                context.tenant_id \u003d\u003d db_obj.tenant_id or"},{"line_number":67,"context_line":"                cls.is_shared_with_tenant(context, db_obj.id,"},{"line_number":68,"context_line":"                                          context.tenant_id))"},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_5980e046","line":66,"range":{"start_line":65,"start_character":15,"end_line":66,"end_character":56},"updated":"2016-02-25 11:00:39.000000000","message":"We could call to original class method instead of duplicating those two lines","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    @classmethod"},{"line_number":64,"context_line":"    def is_accessible(cls, context, db_obj):"},{"line_number":65,"context_line":"        return (context.is_admin or"},{"line_number":66,"context_line":"                context.tenant_id \u003d\u003d db_obj.tenant_id or"},{"line_number":67,"context_line":"                cls.is_shared_with_tenant(context, db_obj.id,"},{"line_number":68,"context_line":"                                          context.tenant_id))"},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_ee08052b","line":66,"range":{"start_line":65,"start_character":15,"end_line":66,"end_character":56},"in_reply_to":"bae84128_5980e046","updated":"2016-02-25 17:24:55.000000000","message":"Done","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":68,"context_line":"                                          context.tenant_id))"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    @classmethod"},{"line_number":71,"context_line":"    def _get_db_obj_rbac_entries(cls, context, rbac_obj_id, rbac_action):"},{"line_number":72,"context_line":"        rbac_db_model \u003d cls.rbac_db_model"},{"line_number":73,"context_line":"        return common_db_mixin.model_query(context, rbac_db_model).filter("},{"line_number":74,"context_line":"            and_(rbac_db_model.object_id \u003d\u003d rbac_obj_id,"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_592aa02d","line":71,"updated":"2016-02-25 11:00:39.000000000","message":"ditto on moving the method out of the mixin.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":68,"context_line":"                                          context.tenant_id))"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    @classmethod"},{"line_number":71,"context_line":"    def _get_db_obj_rbac_entries(cls, context, rbac_obj_id, rbac_action):"},{"line_number":72,"context_line":"        rbac_db_model \u003d cls.rbac_db_model"},{"line_number":73,"context_line":"        return common_db_mixin.model_query(context, rbac_db_model).filter("},{"line_number":74,"context_line":"            and_(rbac_db_model.object_id \u003d\u003d rbac_obj_id,"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_6e5515c5","line":71,"in_reply_to":"bae84128_592aa02d","updated":"2016-02-25 17:24:55.000000000","message":"ditto on is_shared_with_tenant comment","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                 rbac_db_model.action \u003d\u003d rbac_action))"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    @classmethod"},{"line_number":78,"context_line":"    def _get_tenant_ids_with_shared_access_to_db_obj(cls, context, obj_id):"},{"line_number":79,"context_line":"        return itertools.chain.from_iterable(context.session.query("},{"line_number":80,"context_line":"            cls.rbac_db_model.target_tenant).filter("},{"line_number":81,"context_line":"            and_(cls.rbac_db_model.object_id \u003d\u003d obj_id,"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_79dcc446","line":78,"updated":"2016-02-25 11:00:39.000000000","message":"ditto","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                 rbac_db_model.action \u003d\u003d rbac_action))"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    @classmethod"},{"line_number":78,"context_line":"    def _get_tenant_ids_with_shared_access_to_db_obj(cls, context, obj_id):"},{"line_number":79,"context_line":"        return itertools.chain.from_iterable(context.session.query("},{"line_number":80,"context_line":"            cls.rbac_db_model.target_tenant).filter("},{"line_number":81,"context_line":"            and_(cls.rbac_db_model.object_id \u003d\u003d obj_id,"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_ae16f252","line":78,"in_reply_to":"bae84128_79dcc446","updated":"2016-02-25 17:24:55.000000000","message":"ditto","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                 cls.rbac_db_model.target_tenant !\u003d \u0027*\u0027)))"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"    @classmethod"},{"line_number":86,"context_line":"    def _validate_rbac_policy_delete(cls, context, obj_id, target_tenant):"},{"line_number":87,"context_line":"        ctx_admin \u003d context.elevated()"},{"line_number":88,"context_line":"        rb_model \u003d cls.rbac_db_model"},{"line_number":89,"context_line":"        bound_tenant_ids \u003d cls.get_bound_tenant_ids(ctx_admin, obj_id)"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_372a437f","line":86,"updated":"2016-02-25 11:00:39.000000000","message":"ditto. Honestly, the only things that should be melded into the original object are:\n\n- is_accessible\n- get_bound_tenant_ids\n- modified CRUD operations.\n\nAll other methods could be just functions that operate on an object and other parameters needed. There is no reason to have those methods defined on the object itself.\n\nMoving all irrelevant pieces outside the object will also help to target the code with specific unit tests. Currently, you cover only some of those functions with unit tests. Most of them are left uncovered or covered implicitly, by the virtue of being triggered by other methods. That\u0027s not ideal.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"520eb2d13054f851074d231f708846ad4f9c9332","unresolved":false,"context_lines":[{"line_number":90,"context_line":"        db_obj_sharing_entries \u003d cls._get_db_obj_rbac_entries("},{"line_number":91,"context_line":"            ctx_admin, obj_id, models.ACCESS_SHARED)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        def raise_in_policy_in_use():"},{"line_number":94,"context_line":"            raise ext_rbac.RbacPolicyInUse("},{"line_number":95,"context_line":"                object_id\u003dobj_id,"},{"line_number":96,"context_line":"                details\u003d\u0027tenant_id\u003d{}\u0027.format(target_tenant))"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_9dac348e","line":93,"updated":"2016-02-24 20:25:40.000000000","message":"nit: raise_policy_in_use?\n\nCurious as to why this is a method and not just raise on L114?","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"29fae5eb31879d24f269464c74aa5c33246d865b","unresolved":false,"context_lines":[{"line_number":90,"context_line":"        db_obj_sharing_entries \u003d cls._get_db_obj_rbac_entries("},{"line_number":91,"context_line":"            ctx_admin, obj_id, models.ACCESS_SHARED)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        def raise_in_policy_in_use():"},{"line_number":94,"context_line":"            raise ext_rbac.RbacPolicyInUse("},{"line_number":95,"context_line":"                object_id\u003dobj_id,"},{"line_number":96,"context_line":"                details\u003d\u0027tenant_id\u003d{}\u0027.format(target_tenant))"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_7c9ddd58","line":93,"in_reply_to":"bae84128_3698a56a","updated":"2016-02-25 09:18:55.000000000","message":"+1 ;)\n\ncome to think about it - renaming to raise_policy_in_use()","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"4578d85ee4e44dc0449aca76db1aa24b36b4968d","unresolved":false,"context_lines":[{"line_number":90,"context_line":"        db_obj_sharing_entries \u003d cls._get_db_obj_rbac_entries("},{"line_number":91,"context_line":"            ctx_admin, obj_id, models.ACCESS_SHARED)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        def raise_in_policy_in_use():"},{"line_number":94,"context_line":"            raise ext_rbac.RbacPolicyInUse("},{"line_number":95,"context_line":"                object_id\u003dobj_id,"},{"line_number":96,"context_line":"                details\u003d\u0027tenant_id\u003d{}\u0027.format(target_tenant))"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_3698a56a","line":93,"in_reply_to":"bae84128_9dac348e","updated":"2016-02-24 21:51:12.000000000","message":"It\u0027s also in L106.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":103,"context_line":"            if wildcard_sharing_entries.count():"},{"line_number":104,"context_line":"                return"},{"line_number":105,"context_line":"            if target_tenant in bound_tenant_ids:"},{"line_number":106,"context_line":"                raise_in_policy_in_use()"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"        # for the wildcard we need to get all of the rbac entries to"},{"line_number":109,"context_line":"        # see if any allow the object sharing"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_17f1ffcd","line":106,"updated":"2016-02-25 11:00:39.000000000","message":"Shouldn\u0027t we return here right away instead of proceeding to line 108?","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":103,"context_line":"            if wildcard_sharing_entries.count():"},{"line_number":104,"context_line":"                return"},{"line_number":105,"context_line":"            if target_tenant in bound_tenant_ids:"},{"line_number":106,"context_line":"                raise_in_policy_in_use()"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"        # for the wildcard we need to get all of the rbac entries to"},{"line_number":109,"context_line":"        # see if any allow the object sharing"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_f440d209","line":106,"in_reply_to":"bae84128_17f1ffcd","updated":"2016-02-25 17:24:55.000000000","message":"yes - added a test to validate that","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":105,"context_line":"            if target_tenant in bound_tenant_ids:"},{"line_number":106,"context_line":"                raise_in_policy_in_use()"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"        # for the wildcard we need to get all of the rbac entries to"},{"line_number":109,"context_line":"        # see if any allow the object sharing"},{"line_number":110,"context_line":"        other_target_tenants \u003d set("},{"line_number":111,"context_line":"            cls._get_tenant_ids_with_shared_access_to_db_obj("}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_97986f6c","line":108,"range":{"start_line":108,"start_character":10,"end_line":108,"end_character":26},"updated":"2016-02-25 11:00:39.000000000","message":"This comment suggests that you get here only when target_tenant \u003d\u003d \u0027*\u0027 while there are cases that allows to get here with other values.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":202,"context_line":"        return self._context.session.delete(shared_prev)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"def _update_post(self):"},{"line_number":206,"context_line":"    self.update_shared(self.shared, self.id)"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_720df936","line":205,"range":{"start_line":205,"start_character":17,"end_line":205,"end_character":21},"updated":"2016-02-25 11:00:39.000000000","message":"nit: -\u003e obj, here and below","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":234,"context_line":"class RbacNeutronMetaclass(type):"},{"line_number":235,"context_line":"    \"\"\"Adds support for RBAC in NeutronDbObjects."},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"    Injects code for CRUD operations and modifies existing ops to do so."},{"line_number":238,"context_line":"    Should be used in conjunction with rbac_proxy_method decorator, to mark the"},{"line_number":239,"context_line":"    relevant methods for patching. Currently create(), update() and to_dict()"},{"line_number":240,"context_line":"    methods need decorating."},{"line_number":241,"context_line":"    \"\"\""},{"line_number":242,"context_line":""},{"line_number":243,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_524c3576","line":240,"range":{"start_line":237,"start_character":72,"end_line":240,"end_character":28},"updated":"2016-02-25 11:00:39.000000000","message":"??","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":234,"context_line":"class RbacNeutronMetaclass(type):"},{"line_number":235,"context_line":"    \"\"\"Adds support for RBAC in NeutronDbObjects."},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"    Injects code for CRUD operations and modifies existing ops to do so."},{"line_number":238,"context_line":"    Should be used in conjunction with rbac_proxy_method decorator, to mark the"},{"line_number":239,"context_line":"    relevant methods for patching. Currently create(), update() and to_dict()"},{"line_number":240,"context_line":"    methods need decorating."},{"line_number":241,"context_line":"    \"\"\""},{"line_number":242,"context_line":""},{"line_number":243,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_61bfd4fc","line":240,"range":{"start_line":237,"start_character":72,"end_line":240,"end_character":28},"in_reply_to":"bae84128_524c3576","updated":"2016-02-25 17:24:55.000000000","message":"chopped.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"4578d85ee4e44dc0449aca76db1aa24b36b4968d","unresolved":false,"context_lines":[{"line_number":263,"context_line":"                reason\u003d_(\u0027already a synthetic attribute\u0027))"},{"line_number":264,"context_line":"        dct[\u0027synthetic_fields\u0027].append(\u0027shared\u0027)"},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"    @classmethod"},{"line_number":267,"context_line":"    def subscribe_to_rbac_events(mcs, class_instance):"},{"line_number":268,"context_line":"        for e in (events.BEFORE_CREATE, events.BEFORE_UPDATE,"},{"line_number":269,"context_line":"                  events.BEFORE_DELETE):"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_d17ce3ed","line":266,"updated":"2016-02-24 21:51:12.000000000","message":"nit: this is not a class method now, you don\u0027t use mcs. just @staticmethod would do.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"29fae5eb31879d24f269464c74aa5c33246d865b","unresolved":false,"context_lines":[{"line_number":263,"context_line":"                reason\u003d_(\u0027already a synthetic attribute\u0027))"},{"line_number":264,"context_line":"        dct[\u0027synthetic_fields\u0027].append(\u0027shared\u0027)"},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"    @classmethod"},{"line_number":267,"context_line":"    def subscribe_to_rbac_events(mcs, class_instance):"},{"line_number":268,"context_line":"        for e in (events.BEFORE_CREATE, events.BEFORE_UPDATE,"},{"line_number":269,"context_line":"                  events.BEFORE_DELETE):"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_1cf2d19a","line":266,"in_reply_to":"bae84128_d17ce3ed","updated":"2016-02-25 09:18:55.000000000","message":"Done","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"4578d85ee4e44dc0449aca76db1aa24b36b4968d","unresolved":false,"context_lines":[{"line_number":270,"context_line":"            registry.subscribe(class_instance.validate_rbac_policy_change,"},{"line_number":271,"context_line":"                               rbac_db_mixin.RBAC_POLICY, e)"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"    @classmethod"},{"line_number":274,"context_line":"    def validate_existing_attrs(mcs, cls_name, dct):"},{"line_number":275,"context_line":"        if \u0027shared\u0027 not in dct[\u0027fields\u0027]:"},{"line_number":276,"context_line":"            raise KeyError(_(\u0027No shared key in %s fields\u0027) % cls_name)"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_31e70fae","line":273,"updated":"2016-02-24 21:51:12.000000000","message":"Ditto.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"29fae5eb31879d24f269464c74aa5c33246d865b","unresolved":false,"context_lines":[{"line_number":270,"context_line":"            registry.subscribe(class_instance.validate_rbac_policy_change,"},{"line_number":271,"context_line":"                               rbac_db_mixin.RBAC_POLICY, e)"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"    @classmethod"},{"line_number":274,"context_line":"    def validate_existing_attrs(mcs, cls_name, dct):"},{"line_number":275,"context_line":"        if \u0027shared\u0027 not in dct[\u0027fields\u0027]:"},{"line_number":276,"context_line":"            raise KeyError(_(\u0027No shared key in %s fields\u0027) % cls_name)"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_fcee0db3","line":273,"in_reply_to":"bae84128_31e70fae","updated":"2016-02-25 09:18:55.000000000","message":"Done","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":272,"context_line":""},{"line_number":273,"context_line":"    @classmethod"},{"line_number":274,"context_line":"    def validate_existing_attrs(mcs, cls_name, dct):"},{"line_number":275,"context_line":"        if \u0027shared\u0027 not in dct[\u0027fields\u0027]:"},{"line_number":276,"context_line":"            raise KeyError(_(\u0027No shared key in %s fields\u0027) % cls_name)"},{"line_number":277,"context_line":"        if \u0027rbac_db_model\u0027 not in dct:"},{"line_number":278,"context_line":"            raise AttributeError(_(\u0027rbac_db_model not found in %s\u0027) % cls_name)"},{"line_number":279,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_5281d54c","line":276,"range":{"start_line":275,"start_character":8,"end_line":276,"end_character":70},"updated":"2016-02-25 11:00:39.000000000","message":"(No action required) I would prefer if shared field is defined and appended by the metaclass, making sure it\u0027s of proper type and all.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":275,"context_line":"        if \u0027shared\u0027 not in dct[\u0027fields\u0027]:"},{"line_number":276,"context_line":"            raise KeyError(_(\u0027No shared key in %s fields\u0027) % cls_name)"},{"line_number":277,"context_line":"        if \u0027rbac_db_model\u0027 not in dct:"},{"line_number":278,"context_line":"            raise AttributeError(_(\u0027rbac_db_model not found in %s\u0027) % cls_name)"},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"    @classmethod"},{"line_number":281,"context_line":"    def get_replaced_method(mcs, orig_method, new_method):"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_12e74d41","line":278,"range":{"start_line":278,"start_character":33,"end_line":278,"end_character":67},"updated":"2016-02-25 11:00:39.000000000","message":"Seems like programmer error. Probably does not need translation.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":275,"context_line":"        if \u0027shared\u0027 not in dct[\u0027fields\u0027]:"},{"line_number":276,"context_line":"            raise KeyError(_(\u0027No shared key in %s fields\u0027) % cls_name)"},{"line_number":277,"context_line":"        if \u0027rbac_db_model\u0027 not in dct:"},{"line_number":278,"context_line":"            raise AttributeError(_(\u0027rbac_db_model not found in %s\u0027) % cls_name)"},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"    @classmethod"},{"line_number":281,"context_line":"    def get_replaced_method(mcs, orig_method, new_method):"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_8172d87a","line":278,"range":{"start_line":278,"start_character":33,"end_line":278,"end_character":67},"in_reply_to":"bae84128_12e74d41","updated":"2016-02-25 17:24:55.000000000","message":"got a -1 from @garyk for this. I\u0027m keeping it - just as a precaution.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"4578d85ee4e44dc0449aca76db1aa24b36b4968d","unresolved":false,"context_lines":[{"line_number":277,"context_line":"        if \u0027rbac_db_model\u0027 not in dct:"},{"line_number":278,"context_line":"            raise AttributeError(_(\u0027rbac_db_model not found in %s\u0027) % cls_name)"},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"    @classmethod"},{"line_number":281,"context_line":"    def get_replaced_method(mcs, orig_method, new_method):"},{"line_number":282,"context_line":"        def func(self):"},{"line_number":283,"context_line":"            return new_method(self, orig_method)"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_11480b87","line":280,"updated":"2016-02-24 21:51:12.000000000","message":"ditto :)","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"29fae5eb31879d24f269464c74aa5c33246d865b","unresolved":false,"context_lines":[{"line_number":277,"context_line":"        if \u0027rbac_db_model\u0027 not in dct:"},{"line_number":278,"context_line":"            raise AttributeError(_(\u0027rbac_db_model not found in %s\u0027) % cls_name)"},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"    @classmethod"},{"line_number":281,"context_line":"    def get_replaced_method(mcs, orig_method, new_method):"},{"line_number":282,"context_line":"        def func(self):"},{"line_number":283,"context_line":"            return new_method(self, orig_method)"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_3c2fd5f7","line":280,"in_reply_to":"bae84128_11480b87","updated":"2016-02-25 09:18:55.000000000","message":"Done","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"4578d85ee4e44dc0449aca76db1aa24b36b4968d","unresolved":false,"context_lines":[{"line_number":279,"context_line":""},{"line_number":280,"context_line":"    @classmethod"},{"line_number":281,"context_line":"    def get_replaced_method(mcs, orig_method, new_method):"},{"line_number":282,"context_line":"        def func(self):"},{"line_number":283,"context_line":"            return new_method(self, orig_method)"},{"line_number":284,"context_line":"        return func"},{"line_number":285,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_4cab1cd7","line":282,"updated":"2016-02-24 21:51:12.000000000","message":"oh yeah :)","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"29fae5eb31879d24f269464c74aa5c33246d865b","unresolved":false,"context_lines":[{"line_number":279,"context_line":""},{"line_number":280,"context_line":"    @classmethod"},{"line_number":281,"context_line":"    def get_replaced_method(mcs, orig_method, new_method):"},{"line_number":282,"context_line":"        def func(self):"},{"line_number":283,"context_line":"            return new_method(self, orig_method)"},{"line_number":284,"context_line":"        return func"},{"line_number":285,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_9c34214b","line":282,"in_reply_to":"bae84128_4cab1cd7","updated":"2016-02-25 09:18:55.000000000","message":"lol","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":290,"context_line":"                                   \u0027to_dict\u0027: _to_dict_hook}"},{"line_number":291,"context_line":"        for orig_method_name, new_method in methods_replacement_map.items():"},{"line_number":292,"context_line":"            orig_method \u003d mcs.get_attribute(orig_method_name, bases, dct)"},{"line_number":293,"context_line":"            hook_method \u003d mcs.get_replaced_method(orig_method,"},{"line_number":294,"context_line":"                                                  new_method)"},{"line_number":295,"context_line":"            dct[orig_method_name] \u003d hook_method"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"    def __new__(mcs, name, bases, dct):"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_f78f3bca","line":294,"range":{"start_line":293,"start_character":12,"end_line":294,"end_character":61},"updated":"2016-02-25 11:00:39.000000000","message":"hook_method \u003d lambda self: new_method(self, orig_method)","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":290,"context_line":"                                   \u0027to_dict\u0027: _to_dict_hook}"},{"line_number":291,"context_line":"        for orig_method_name, new_method in methods_replacement_map.items():"},{"line_number":292,"context_line":"            orig_method \u003d mcs.get_attribute(orig_method_name, bases, dct)"},{"line_number":293,"context_line":"            hook_method \u003d mcs.get_replaced_method(orig_method,"},{"line_number":294,"context_line":"                                                  new_method)"},{"line_number":295,"context_line":"            dct[orig_method_name] \u003d hook_method"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"    def __new__(mcs, name, bases, dct):"}],"source_content_type":"text/x-python","patch_set":28,"id":"9aed3d3a_85c86676","line":294,"range":{"start_line":293,"start_character":12,"end_line":294,"end_character":61},"in_reply_to":"bae84128_f78f3bca","updated":"2016-02-25 17:24:55.000000000","message":"nice, but it seems to fail for some reason. we can refactor that later.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"}],"neutron/tests/api/admin/test_rbac_qos_policy_extension.py":[{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"46700008826cc88fbbfef7ce857bbc8c84e8948d","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 Hewlett-Packard Development Company, L.P.dsvsv"},{"line_number":2,"context_line":"# Copyright 2015 OpenStack Foundation"},{"line_number":3,"context_line":"# All Rights Reserved."},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_6f4b905a","line":1,"updated":"2015-12-17 07:24:02.000000000","message":"Why HP?","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"60e6eff57a2b48be492c1057418254c5c0d01f13","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 Hewlett-Packard Development Company, L.P.dsvsv"},{"line_number":2,"context_line":"# Copyright 2015 OpenStack Foundation"},{"line_number":3,"context_line":"# All Rights Reserved."},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_4f301457","line":1,"in_reply_to":"3a7e1126_6f4b905a","updated":"2015-12-17 07:49:32.000000000","message":"evil copy paste. \nremoved","commit_id":"00e1b2dd953c178d08449471e75678034a0a0816"}],"neutron/tests/api/test_qos.py":[{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":536,"context_line":"        self.admin_client.delete_rbac_policy(res[\u0027rbac_policy\u0027][\u0027id\u0027])"},{"line_number":537,"context_line":""},{"line_number":538,"context_line":"        # now that wildcard is the only remaining, it should be subjected to"},{"line_number":539,"context_line":"        # to the same restriction"},{"line_number":540,"context_line":"        with testtools.ExpectedException(exceptions.Conflict):"},{"line_number":541,"context_line":"            self.admin_client.delete_rbac_policy(wild[\u0027id\u0027])"},{"line_number":542,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_5e46be7b","line":539,"updated":"2016-02-08 12:40:03.000000000","message":"nit: duplicate \u0027to\u0027","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":536,"context_line":"        self.admin_client.delete_rbac_policy(res[\u0027rbac_policy\u0027][\u0027id\u0027])"},{"line_number":537,"context_line":""},{"line_number":538,"context_line":"        # now that wildcard is the only remaining, it should be subjected to"},{"line_number":539,"context_line":"        # to the same restriction"},{"line_number":540,"context_line":"        with testtools.ExpectedException(exceptions.Conflict):"},{"line_number":541,"context_line":"            self.admin_client.delete_rbac_policy(wild[\u0027id\u0027])"},{"line_number":542,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"3a57f1b5_e30e4c3a","line":539,"in_reply_to":"5a5ae5dd_5e46be7b","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":614,"context_line":"    def test_regular_client_blocked_from_sharing_anothers_policy(self):"},{"line_number":615,"context_line":"        policy \u003d self._make_admin_policy_shared_to_tenant_id("},{"line_number":616,"context_line":"            self.client.tenant_id)[\u0027policy\u0027]"},{"line_number":617,"context_line":"        with testtools.ExpectedException(exceptions.ServerFault):"},{"line_number":618,"context_line":"            self.client.create_rbac_policy("},{"line_number":619,"context_line":"                object_type\u003d\u0027qos_policy\u0027, object_id\u003dpolicy[\u0027id\u0027],"},{"line_number":620,"context_line":"                action\u003d\u0027access_as_shared\u0027, target_tenant\u003dself.client.tenant_id)"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_7950740b","line":617,"updated":"2016-02-08 12:40:03.000000000","message":"The exception does not seem right. It usually indicates there is a non-graceful traceback generated on server side. Can we get it returning something more meaningful, like \u0027Forbidden\u0027?","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":614,"context_line":"    def test_regular_client_blocked_from_sharing_anothers_policy(self):"},{"line_number":615,"context_line":"        policy \u003d self._make_admin_policy_shared_to_tenant_id("},{"line_number":616,"context_line":"            self.client.tenant_id)[\u0027policy\u0027]"},{"line_number":617,"context_line":"        with testtools.ExpectedException(exceptions.ServerFault):"},{"line_number":618,"context_line":"            self.client.create_rbac_policy("},{"line_number":619,"context_line":"                object_type\u003d\u0027qos_policy\u0027, object_id\u003dpolicy[\u0027id\u0027],"},{"line_number":620,"context_line":"                action\u003d\u0027access_as_shared\u0027, target_tenant\u003dself.client.tenant_id)"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_357428ce","line":617,"in_reply_to":"5a5ae5dd_7950740b","updated":"2016-02-15 22:48:57.000000000","message":"I actually found a bug thanks to your comment - there was no validation of permissions on rbac policy update/create. Thanks!\n\nRegarding the exception - existing RBAC callback infra raises an InvalidInput in case validation goes wrong. Sounds fair ?","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"d189f50f2bcdc4781af0924a23e7efa48d305d68","unresolved":false,"context_lines":[{"line_number":619,"context_line":"                object_type\u003d\u0027qos_policy\u0027, object_id\u003dpolicy[\u0027id\u0027],"},{"line_number":620,"context_line":"                action\u003d\u0027access_as_shared\u0027, target_tenant\u003dself.client.tenant_id)"},{"line_number":621,"context_line":""},{"line_number":622,"context_line":"    @test.idempotent_id(\u0027d4372454-a350-11e5-8dbf-54ee756c66df\u0027)"},{"line_number":623,"context_line":"    def test_regular_client_blocked_from_sharing_with_wildcard(self):"},{"line_number":624,"context_line":"        policy \u003d self._create_qos_policy()"},{"line_number":625,"context_line":"        with testtools.ExpectedException(exceptions.Forbidden):"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_fcb9e42f","line":622,"updated":"2016-02-15 14:35:43.000000000","message":"You may want to test a case where you first share with a specific tenant, then enable global sharing.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":619,"context_line":"                object_type\u003d\u0027qos_policy\u0027, object_id\u003dpolicy[\u0027id\u0027],"},{"line_number":620,"context_line":"                action\u003d\u0027access_as_shared\u0027, target_tenant\u003dself.client.tenant_id)"},{"line_number":621,"context_line":""},{"line_number":622,"context_line":"    @test.idempotent_id(\u0027d4372454-a350-11e5-8dbf-54ee756c66df\u0027)"},{"line_number":623,"context_line":"    def test_regular_client_blocked_from_sharing_with_wildcard(self):"},{"line_number":624,"context_line":"        policy \u003d self._create_qos_policy()"},{"line_number":625,"context_line":"        with testtools.ExpectedException(exceptions.Forbidden):"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_977985ff","line":622,"in_reply_to":"dae33548_fcb9e42f","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":467,"context_line":"            raise cls.skipException(msg)"},{"line_number":468,"context_line":"        cls.client2 \u003d cls.alt_manager.network_client"},{"line_number":469,"context_line":""},{"line_number":470,"context_line":"    def _create_qos_policy(self, tenant_id\u003dNone):"},{"line_number":471,"context_line":"        return super(RbacSharedQosPoliciesTest, self).create_qos_policy("},{"line_number":472,"context_line":"            name\u003ddata_utils.rand_name(\u0027test-policy\u0027),"},{"line_number":473,"context_line":"            description\u003d\u0027test policy\u0027,"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_c74a25ac","line":470,"range":{"start_line":470,"start_character":8,"end_line":470,"end_character":26},"updated":"2016-02-16 10:19:33.000000000","message":"_create_qos_policy and _create_network should not be here, but in neutron/tests/api/base.py:BaseNetworkTest. Using that will reveal that create_qos_policy and create_network (along with their respective cleanups) already exist, which will leave you needing to only create_rbac_policy() there.","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":468,"context_line":"        cls.client2 \u003d cls.alt_manager.network_client"},{"line_number":469,"context_line":""},{"line_number":470,"context_line":"    def _create_qos_policy(self, tenant_id\u003dNone):"},{"line_number":471,"context_line":"        return super(RbacSharedQosPoliciesTest, self).create_qos_policy("},{"line_number":472,"context_line":"            name\u003ddata_utils.rand_name(\u0027test-policy\u0027),"},{"line_number":473,"context_line":"            description\u003d\u0027test policy\u0027,"},{"line_number":474,"context_line":"            shared\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_c71ce5c3","line":471,"range":{"start_line":471,"start_character":15,"end_line":471,"end_character":53},"updated":"2016-02-16 10:19:33.000000000","message":"Calling super() here is not needed.","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":474,"context_line":"            shared\u003dFalse,"},{"line_number":475,"context_line":"            tenant_id\u003dtenant_id)"},{"line_number":476,"context_line":""},{"line_number":477,"context_line":"    def _make_admin_policy_shared_to_tenant_id(self, tenant_id):"},{"line_number":478,"context_line":"        policy \u003d self._create_qos_policy()"},{"line_number":479,"context_line":"        rbac_policy \u003d self.admin_client.create_rbac_policy("},{"line_number":480,"context_line":"            object_type\u003d\u0027qos_policy\u0027,"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_07d24cd2","line":477,"range":{"start_line":477,"start_character":8,"end_line":477,"end_character":46},"updated":"2016-02-16 10:19:33.000000000","message":"Large chunks of this code can be made very generic once rbac for networks is added. This means that whomever comes along next will need to duplicate big parts of this test suite and only change this function to create a network instead of a qos policy.\n\nWhile it\u0027s unreasonable to think ahead this much and do all the work yourself, I would appreciate a #NOTE here that mentions the fact that this class can be made a subclass for multiple rbac tests (one for qos, one for network) with shared codebase later down the line.","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":476,"context_line":""},{"line_number":477,"context_line":"    def _make_admin_policy_shared_to_tenant_id(self, tenant_id):"},{"line_number":478,"context_line":"        policy \u003d self._create_qos_policy()"},{"line_number":479,"context_line":"        rbac_policy \u003d self.admin_client.create_rbac_policy("},{"line_number":480,"context_line":"            object_type\u003d\u0027qos_policy\u0027,"},{"line_number":481,"context_line":"            object_id\u003dpolicy[\u0027id\u0027],"},{"line_number":482,"context_line":"            action\u003d\u0027access_as_shared\u0027,"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_0736cc51","line":479,"range":{"start_line":479,"start_character":40,"end_line":479,"end_character":58},"updated":"2016-02-16 10:19:33.000000000","message":"This is never cleaned up in the current code.","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":503,"context_line":""},{"line_number":504,"context_line":"        # test update shared False -\u003e True"},{"line_number":505,"context_line":"        self.admin_client.update_qos_policy(qos_pol[\u0027id\u0027], shared\u003dTrue)"},{"line_number":506,"context_line":"        qos_pol[\u0027shared\u0027] \u003d True"},{"line_number":507,"context_line":"        self.client2.show_qos_policy(qos_pol[\u0027id\u0027])"},{"line_number":508,"context_line":"        rbac_pol \u003d {\u0027target_tenant\u0027: \u0027*\u0027,"},{"line_number":509,"context_line":"                    \u0027tenant_id\u0027: self.admin_client.tenant_id,"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_47ba956f","line":506,"range":{"start_line":506,"start_character":8,"end_line":506,"end_character":16},"updated":"2016-02-16 10:19:33.000000000","message":"Please move this to just before line 528 or 527, so that the context of this change is made clear.","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":511,"context_line":"                    \u0027object_id\u0027: qos_pol[\u0027id\u0027],"},{"line_number":512,"context_line":"                    \u0027action\u0027: \u0027access_as_shared\u0027}"},{"line_number":513,"context_line":""},{"line_number":514,"context_line":"        rbac_policies \u003d [r for r in self.admin_client.list_rbac_policies()["},{"line_number":515,"context_line":"                             \u0027rbac_policies\u0027] if r.pop(\u0027id\u0027)]"},{"line_number":516,"context_line":"        self.assertIn(rbac_pol, rbac_policies)"},{"line_number":517,"context_line":""},{"line_number":518,"context_line":"        # update shared True -\u003e False should fail because the policy is bound"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_67135967","line":515,"range":{"start_line":514,"start_character":36,"end_line":515,"end_character":45},"updated":"2016-02-16 10:19:33.000000000","message":"Suggestion: code is a bit hard to read.. how about the following?\n\nrbac_policies \u003d self.admin_client.list_rbac_policies()[\u0027rbac_policies\u0027]\nrbac_policies \u003d [r for r in rbac_policies if r.pop(\u0027id\u0027)]","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":518,"context_line":"        # update shared True -\u003e False should fail because the policy is bound"},{"line_number":519,"context_line":"        # to a network"},{"line_number":520,"context_line":"        net \u003d self._create_network(qos_pol[\u0027id\u0027], self.admin_client, False)"},{"line_number":521,"context_line":"        with testtools.ExpectedException(exceptions.Conflict):"},{"line_number":522,"context_line":"            self.admin_client.update_qos_policy(qos_pol[\u0027id\u0027], shared\u003dFalse)"},{"line_number":523,"context_line":""},{"line_number":524,"context_line":"        # delete the network, and update shared True -\u003e False should pass now"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_c726a4b9","line":521,"range":{"start_line":521,"start_character":8,"end_line":521,"end_character":62},"updated":"2016-02-16 10:19:33.000000000","message":"You can use self.assertRaises() for this kind of checks.","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":538,"context_line":""},{"line_number":539,"context_line":"        # make the qos-policy globally shared"},{"line_number":540,"context_line":"        self.admin_client.update_qos_policy(qos_policy[\u0027id\u0027], shared\u003dTrue)"},{"line_number":541,"context_line":"        self.client2.show_qos_policy(qos_policy[\u0027id\u0027])"},{"line_number":542,"context_line":""},{"line_number":543,"context_line":"        # globally unshare the qos-policy, the specific share should remain"},{"line_number":544,"context_line":"        self.admin_client.update_qos_policy(qos_policy[\u0027id\u0027], shared\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_07f40cf0","line":541,"range":{"start_line":541,"start_character":8,"end_line":541,"end_character":54},"updated":"2016-02-16 10:19:33.000000000","message":"Besides making sure that no exception is raised, please also verify that the result is valid (a sample testing of \"make sure the id/name of the policy is valid\" is fine).","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":542,"context_line":""},{"line_number":543,"context_line":"        # globally unshare the qos-policy, the specific share should remain"},{"line_number":544,"context_line":"        self.admin_client.update_qos_policy(qos_policy[\u0027id\u0027], shared\u003dFalse)"},{"line_number":545,"context_line":"        self.client.show_qos_policy(qos_policy[\u0027id\u0027])"},{"line_number":546,"context_line":"        with testtools.ExpectedException(exceptions.NotFound):"},{"line_number":547,"context_line":"            self.client2.show_qos_policy(qos_policy[\u0027id\u0027])"},{"line_number":548,"context_line":"        self.assertIn(rbac,"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_87bf7cfa","line":545,"range":{"start_line":545,"start_character":8,"end_line":545,"end_character":53},"updated":"2016-02-16 10:19:33.000000000","message":"Here for example, a valid check would be that the shared property has changed and is reflected as such by the API.","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":549,"context_line":"                      self.admin_client.list_rbac_policies()[\u0027rbac_policies\u0027])"},{"line_number":550,"context_line":""},{"line_number":551,"context_line":"    @test.idempotent_id(\u002794b3639c-a350-11e5-a6d6-54ee756c66df\u0027)"},{"line_number":552,"context_line":"    def test_policy_only_visible_to_policy_target(self):"},{"line_number":553,"context_line":"        policy \u003d self._make_admin_policy_shared_to_tenant_id("},{"line_number":554,"context_line":"            self.client.tenant_id)[\u0027policy\u0027]"},{"line_number":555,"context_line":"        self.client.show_qos_policy(policy[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_a761e0aa","line":552,"range":{"start_line":552,"start_character":8,"end_line":552,"end_character":49},"updated":"2016-02-16 10:19:33.000000000","message":"This entire test can be removed since it\u0027s already done as part of test_policy_sharing_with_wildcard_and_tenant_id.","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":566,"context_line":"                res[\u0027rbac_policy\u0027][\u0027id\u0027], target_tenant\u003dself.client2.tenant_id)"},{"line_number":567,"context_line":"        self.assertEqual(self.client2.tenant_id,"},{"line_number":568,"context_line":"                         update_res[\u0027rbac_policy\u0027][\u0027target_tenant\u0027])"},{"line_number":569,"context_line":"        # make sure everything else stayed the same"},{"line_number":570,"context_line":"        res[\u0027rbac_policy\u0027].pop(\u0027target_tenant\u0027)"},{"line_number":571,"context_line":"        update_res[\u0027rbac_policy\u0027].pop(\u0027target_tenant\u0027)"},{"line_number":572,"context_line":"        self.assertEqual(res[\u0027rbac_policy\u0027], update_res[\u0027rbac_policy\u0027])"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_67ed18ef","line":569,"range":{"start_line":569,"start_character":10,"end_line":569,"end_character":51},"updated":"2016-02-16 10:19:33.000000000","message":"I would rather this will be made against \u0027show_qos_policy\u0027, but I\u0027m fine with leaving this as is.","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"a47bfe9c5f56b7a97d1e98bc106d7c36ebdf3a35","unresolved":false,"context_lines":[{"line_number":631,"context_line":"            self.assertEqual(set(fields), set(res[\u0027rbac_policies\u0027][0].keys()))"},{"line_number":632,"context_line":""},{"line_number":633,"context_line":"    @test.idempotent_id(\u0027c10d993a-a350-11e5-9c7a-54ee756c66df\u0027)"},{"line_number":634,"context_line":"    def test_policy_show(self):"},{"line_number":635,"context_line":"        res \u003d self._make_admin_policy_shared_to_tenant_id("},{"line_number":636,"context_line":"            self.client.tenant_id)"},{"line_number":637,"context_line":"        p1 \u003d res[\u0027rbac_policy\u0027]"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_e7eac8ab","line":634,"range":{"start_line":634,"start_character":8,"end_line":634,"end_character":24},"updated":"2016-02-16 10:19:33.000000000","message":"Rename to \u0027test_rbac_policy_show\u0027","commit_id":"42f1c0c7e0ff58e5bb90e203be9cad4496c8b305"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"92c39525ea637d28f5dbbc536926e3754ec0a30b","unresolved":false,"context_lines":[{"line_number":485,"context_line":""},{"line_number":486,"context_line":"        return {\u0027policy\u0027: policy, \u0027rbac_policy\u0027: rbac_policy}"},{"line_number":487,"context_line":""},{"line_number":488,"context_line":"    def _create_network(self, qos_policy_id, client, should_cleanup\u003dTrue):"},{"line_number":489,"context_line":"        net \u003d client.create_network("},{"line_number":490,"context_line":"            name\u003ddata_utils.rand_name(\u0027test-network\u0027),"},{"line_number":491,"context_line":"            qos_policy_id\u003dqos_policy_id)[\u0027network\u0027]"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_473e5db9","line":488,"updated":"2016-02-19 12:07:51.000000000","message":"Is this used somewhere? :?","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"0c14d982458101eb3481308ee44fd40a1e33f498","unresolved":false,"context_lines":[{"line_number":485,"context_line":""},{"line_number":486,"context_line":"        return {\u0027policy\u0027: policy, \u0027rbac_policy\u0027: rbac_policy}"},{"line_number":487,"context_line":""},{"line_number":488,"context_line":"    def _create_network(self, qos_policy_id, client, should_cleanup\u003dTrue):"},{"line_number":489,"context_line":"        net \u003d client.create_network("},{"line_number":490,"context_line":"            name\u003ddata_utils.rand_name(\u0027test-network\u0027),"},{"line_number":491,"context_line":"            qos_policy_id\u003dqos_policy_id)[\u0027network\u0027]"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_408643ba","line":488,"in_reply_to":"bae84128_473e5db9","updated":"2016-02-19 12:11:06.000000000","message":"Ignore this, L520 as you said in IRC....  \u0027:D","commit_id":"d074670d37849d771551481b2f4e8e0839135d00"}],"neutron/tests/unit/db/test_rbac_db_mixin.py":[{"author":{"_account_id":12444,"name":"John Schwarz","email":"jschwarz@redhat.com","username":"jschwarz"},"change_message_id":"bda6c10036944ebfd08a1ab4968fd20a805b9026","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":2,"context_line":"#    not use this file except in compliance with the License. You may obtain"},{"line_number":3,"context_line":"#    a copy of the License at"},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":19,"id":"dae33548_fdd59e1b","line":1,"range":{"start_line":1,"start_character":0,"end_line":1,"end_character":1},"updated":"2016-02-18 16:17:21.000000000","message":"You forgot to add, as first line:\n# Copyright 2016 Red Hat, Inc.","commit_id":"b6ed80c05295c90d28a470a1efdff9812e4841d1"}],"neutron/tests/unit/objects/qos/test_policy.py":[{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":245,"context_line":""},{"line_number":246,"context_line":"        self.assertEqual(rule_dict, obj_dict[\u0027rules\u0027][0])"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"    def test_shared_default(self):"},{"line_number":249,"context_line":"        self.db_obj.pop(\u0027shared\u0027)"},{"line_number":250,"context_line":"        obj \u003d self._test_class(self.context, **self.db_obj)"},{"line_number":251,"context_line":"        self.assertFalse(obj.shared)"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_99a1b0fa","side":"PARENT","line":248,"updated":"2016-02-08 12:40:03.000000000","message":"We need more explicit tests for RBAC object behaviour here.","commit_id":"ba33a89a9792e099d4fe45bd43e4eca07ec08e2b"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"7b146dcb8ca1a93de928be12982b5cd3433376be","unresolved":false,"context_lines":[{"line_number":281,"context_line":"        self.assertEqual(ids.pop(), self._port[\u0027tenant_id\u0027])"},{"line_number":282,"context_line":"        self.assertEqual(len(ids), 0)"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"        obj.detach_port(self._port[\u0027id\u0027])"},{"line_number":285,"context_line":"        obj.delete()"}],"source_content_type":"text/x-python","patch_set":30,"id":"9aed3d3a_d3db2bec","line":284,"updated":"2016-02-26 09:59:13.000000000","message":"I believe cleanup is unneeded here because the test does not target the detach/delete, and SqlTestCase will handle the db cleanup for you.","commit_id":"4ba598cd1d777dce184f34e75454b082d94d5536"}],"neutron/tests/unit/objects/test_base.py":[{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"e997782aaf49c1c408e5e40394e068c40b6076c2","unresolved":false,"context_lines":[{"line_number":211,"context_line":"        with mock.patch.object(base.NeutronDbObject,"},{"line_number":212,"context_line":"                               \u0027_get_changed_persistent_fields\u0027,"},{"line_number":213,"context_line":"                               return_value\u003d{}):"},{"line_number":214,"context_line":"            obj \u003d self._test_class(self.context, id\u003d7777)"},{"line_number":215,"context_line":"            obj.update()"},{"line_number":216,"context_line":"            self.assertFalse(update_mock.called)"},{"line_number":217,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_882f70a0","line":214,"updated":"2015-12-02 11:02:38.000000000","message":"explain the need for the change.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"756036fff71797af367e36a24fd3ccaad7c89455","unresolved":false,"context_lines":[{"line_number":211,"context_line":"        with mock.patch.object(base.NeutronDbObject,"},{"line_number":212,"context_line":"                               \u0027_get_changed_persistent_fields\u0027,"},{"line_number":213,"context_line":"                               return_value\u003d{}):"},{"line_number":214,"context_line":"            obj \u003d self._test_class(self.context, id\u003d7777)"},{"line_number":215,"context_line":"            obj.update()"},{"line_number":216,"context_line":"            self.assertFalse(update_mock.called)"},{"line_number":217,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_5fd4db1e","line":214,"in_reply_to":"9a8ffd7b_882f70a0","updated":"2015-12-02 12:22:59.000000000","message":"The test flows in slight curve - update without create first. Hence causes QoSPolicy be without an id field (which is needed for \u0027shared\u0027 field update validation)","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"}],"neutron/tests/unit/objects/test_rbac_db.py":[{"author":{"_account_id":6659,"name":"Paul Michali","email":"pc@michali.net","username":"pcm"},"change_message_id":"b11696b9c81d1cc2de5462fa67c5e7259d495226","unresolved":false,"context_lines":[{"line_number":83,"context_line":"            (fake_id,) for fake_id in fake_ids]"},{"line_number":84,"context_line":"        ret_ids \u003d self._test_class._get_tenants_with_shared_access_to_db_obj("},{"line_number":85,"context_line":"            ctx, \u0027fake_db_obj_id\u0027)"},{"line_number":86,"context_line":"        self.assertTrue(ret_ids \u003d\u003d fake_ids)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def test_is_accessible_for_admin(self):"},{"line_number":89,"context_line":"        ctx \u003d mock.Mock(is_admin\u003dTrue, tenant_id\u003d\u0027we_dont_care\u0027)"}],"source_content_type":"text/x-python","patch_set":29,"id":"9aed3d3a_61770dd5","line":86,"updated":"2016-02-25 20:00:56.000000000","message":"nit: AssertEqual()","commit_id":"fb20c40e37c371329e9349578b0bbcf5be6a204d"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"ed8bfbb77f8c204a75b27b025874fb2f41ac918f","unresolved":false,"context_lines":[{"line_number":83,"context_line":"            (fake_id,) for fake_id in fake_ids]"},{"line_number":84,"context_line":"        ret_ids \u003d self._test_class._get_tenants_with_shared_access_to_db_obj("},{"line_number":85,"context_line":"            ctx, \u0027fake_db_obj_id\u0027)"},{"line_number":86,"context_line":"        self.assertTrue(ret_ids \u003d\u003d fake_ids)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def test_is_accessible_for_admin(self):"},{"line_number":89,"context_line":"        ctx \u003d mock.Mock(is_admin\u003dTrue, tenant_id\u003d\u0027we_dont_care\u0027)"}],"source_content_type":"text/x-python","patch_set":29,"id":"9aed3d3a_d2bea5d3","line":86,"in_reply_to":"9aed3d3a_57ce075b","updated":"2016-02-25 20:55:22.000000000","message":":-)","commit_id":"fb20c40e37c371329e9349578b0bbcf5be6a204d"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"898a0c5b0be2fa03874dcff9d2da389e32506d79","unresolved":false,"context_lines":[{"line_number":83,"context_line":"            (fake_id,) for fake_id in fake_ids]"},{"line_number":84,"context_line":"        ret_ids \u003d self._test_class._get_tenants_with_shared_access_to_db_obj("},{"line_number":85,"context_line":"            ctx, \u0027fake_db_obj_id\u0027)"},{"line_number":86,"context_line":"        self.assertTrue(ret_ids \u003d\u003d fake_ids)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def test_is_accessible_for_admin(self):"},{"line_number":89,"context_line":"        ctx \u003d mock.Mock(is_admin\u003dTrue, tenant_id\u003d\u0027we_dont_care\u0027)"}],"source_content_type":"text/x-python","patch_set":29,"id":"9aed3d3a_57ce075b","line":86,"in_reply_to":"9aed3d3a_61770dd5","updated":"2016-02-25 20:47:31.000000000","message":"Done","commit_id":"fb20c40e37c371329e9349578b0bbcf5be6a204d"}],"neutron/tests/unit/objects/test_rbac_neutron_db.py":[{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        pass"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"class RbacNeutronDbObjectTestCase(test_base.BaseObjectIfaceTestCase,"},{"line_number":70,"context_line":"                                  testlib_api.SqlTestCase):"},{"line_number":71,"context_line":"    _test_class \u003d FakeNeutronDbObject"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_72e179fe","line":69,"updated":"2016-02-25 11:00:39.000000000","message":"A lot of useful tests for helper methods defined in rbac_neutron_db are missing. I suggest you go thru the list of callables there and define some tests for each of them.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        pass"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"class RbacNeutronDbObjectTestCase(test_base.BaseObjectIfaceTestCase,"},{"line_number":70,"context_line":"                                  testlib_api.SqlTestCase):"},{"line_number":71,"context_line":"    _test_class \u003d FakeNeutronDbObject"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_9e1515e7","line":69,"in_reply_to":"bae84128_72e179fe","updated":"2016-02-25 17:24:55.000000000","message":"Done","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"}],"neutron/tests/unit/services/qos/test_qos_plugin.py":[{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"e997782aaf49c1c408e5e40394e068c40b6076c2","unresolved":false,"context_lines":[{"line_number":38,"context_line":"        mock.patch(\u0027neutron.db.api.get_object\u0027).start()"},{"line_number":39,"context_line":"        mock.patch("},{"line_number":40,"context_line":"            \u0027neutron.objects.qos.policy.QosPolicy.obj_load_attr\u0027).start()"},{"line_number":41,"context_line":"        mock.patch(\u0027neutron.objects.qos.policy.QosPolicy.attach_rbac\u0027).start()"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"        cfg.CONF.set_override(\"core_plugin\", DB_PLUGIN_KLASS)"},{"line_number":44,"context_line":"        cfg.CONF.set_override(\"service_plugins\", [\"qos\"])"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_e335ffda","line":41,"updated":"2015-12-02 11:02:38.000000000","message":"I don\u0027t believe the test should care about create() implementation details. Seems like we should mock qos policy object a bit earlier (in create, not create_object).","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"4683fd7f05027fa9114cee2f00a439008006296c","unresolved":false,"context_lines":[{"line_number":38,"context_line":"        mock.patch(\u0027neutron.db.api.get_object\u0027).start()"},{"line_number":39,"context_line":"        mock.patch("},{"line_number":40,"context_line":"            \u0027neutron.objects.qos.policy.QosPolicy.obj_load_attr\u0027).start()"},{"line_number":41,"context_line":"        mock.patch(\u0027neutron.objects.qos.policy.QosPolicy.attach_rbac\u0027).start()"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"        cfg.CONF.set_override(\"core_plugin\", DB_PLUGIN_KLASS)"},{"line_number":44,"context_line":"        cfg.CONF.set_override(\"service_plugins\", [\"qos\"])"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_333ef08b","line":41,"in_reply_to":"9a8ffd7b_48a7430b","updated":"2015-12-02 12:40:33.000000000","message":"So let\u0027s fix it, not add more on top of the pile. :)","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"756036fff71797af367e36a24fd3ccaad7c89455","unresolved":false,"context_lines":[{"line_number":38,"context_line":"        mock.patch(\u0027neutron.db.api.get_object\u0027).start()"},{"line_number":39,"context_line":"        mock.patch("},{"line_number":40,"context_line":"            \u0027neutron.objects.qos.policy.QosPolicy.obj_load_attr\u0027).start()"},{"line_number":41,"context_line":"        mock.patch(\u0027neutron.objects.qos.policy.QosPolicy.attach_rbac\u0027).start()"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"        cfg.CONF.set_override(\"core_plugin\", DB_PLUGIN_KLASS)"},{"line_number":44,"context_line":"        cfg.CONF.set_override(\"service_plugins\", [\"qos\"])"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_48a7430b","line":41,"in_reply_to":"9a8ffd7b_e335ffda","updated":"2015-12-02 12:22:59.000000000","message":"my thoughts exactly. before I saw L40.","commit_id":"756804b14b1329a454ab5756d89babbba16ae761"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    @mock.patch("},{"line_number":80,"context_line":"        \u0027neutron.objects.rbac_neutron_db.RbacNeutronDbObjectMixin\u0027"},{"line_number":81,"context_line":"        \u0027.create_rbac_policy\u0027)"},{"line_number":82,"context_line":"    def test_add_policy(self, *mocks):"},{"line_number":83,"context_line":"        self.qos_plugin.create_policy(self.ctxt, self.policy_data)"},{"line_number":84,"context_line":"        self._validate_notif_driver_params(\u0027create_policy\u0027)"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_b2aca136","line":81,"updated":"2016-02-25 11:00:39.000000000","message":"Alternatively, you could just remove shared\u003dTrue from the policy data used here. It\u0027s of no concern for the test class.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    @mock.patch("},{"line_number":80,"context_line":"        \u0027neutron.objects.rbac_neutron_db.RbacNeutronDbObjectMixin\u0027"},{"line_number":81,"context_line":"        \u0027.create_rbac_policy\u0027)"},{"line_number":82,"context_line":"    def test_add_policy(self, *mocks):"},{"line_number":83,"context_line":"        self.qos_plugin.create_policy(self.ctxt, self.policy_data)"},{"line_number":84,"context_line":"        self._validate_notif_driver_params(\u0027create_policy\u0027)"}],"source_content_type":"text/x-python","patch_set":28,"id":"bae84128_483648b5","line":81,"in_reply_to":"bae84128_b2aca136","updated":"2016-02-25 17:24:55.000000000","message":"I prefer keeping the policy untouched, since a major part of this patch - keeping the existing API from breaking.","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"}],"releasenotes/notes/add-rbac-qos-8b1154ee756c66df.yaml":[{"author":{"_account_id":14605,"name":"vikram.choudhary","email":"vikschw@gmail.com","username":"vikram.choudhary"},"change_message_id":"9f2ea048f0587daa86641beadf2dedf8449775f5","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"prelude: \u003e"},{"line_number":3,"context_line":"   Rbac support for QoS policy"},{"line_number":4,"context_line":"features:"},{"line_number":5,"context_line":"  - Neutron supports now sharing of qos policies between a subset of tenants."}],"source_content_type":"text/x-yaml","patch_set":12,"id":"5a5ae5dd_72792593","line":3,"updated":"2016-02-03 16:18:45.000000000","message":"%s/Rbac/RBAC/g","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"336da73974c4abab201c20a240626497900120db","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"prelude: \u003e"},{"line_number":3,"context_line":"   Rbac support for QoS policy"},{"line_number":4,"context_line":"features:"},{"line_number":5,"context_line":"  - Neutron supports now sharing of qos policies between a subset of tenants."}],"source_content_type":"text/x-yaml","patch_set":12,"id":"5a5ae5dd_6f210fb4","line":3,"in_reply_to":"5a5ae5dd_72792593","updated":"2016-02-04 10:11:00.000000000","message":"Done","commit_id":"82cb8775cf04d10272079ba41416c4807e48b7f5"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"prelude: \u003e"},{"line_number":3,"context_line":"   RBAC support for QoS policy"},{"line_number":4,"context_line":"features:"},{"line_number":5,"context_line":"  - Neutron supports now sharing of qos policies between a subset of tenants."}],"source_content_type":"text/x-yaml","patch_set":14,"id":"5a5ae5dd_d91408ea","line":3,"updated":"2016-02-08 12:40:03.000000000","message":"for QoS policies","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"prelude: \u003e"},{"line_number":3,"context_line":"   RBAC support for QoS policy"},{"line_number":4,"context_line":"features:"},{"line_number":5,"context_line":"  - Neutron supports now sharing of qos policies between a subset of tenants."}],"source_content_type":"text/x-yaml","patch_set":14,"id":"3a57f1b5_0e262f15","line":3,"in_reply_to":"5a5ae5dd_d91408ea","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"033fa3209a43d7a67893973cfa9ed18b4e18ed0f","unresolved":false,"context_lines":[{"line_number":2,"context_line":"prelude: \u003e"},{"line_number":3,"context_line":"   RBAC support for QoS policy"},{"line_number":4,"context_line":"features:"},{"line_number":5,"context_line":"  - Neutron supports now sharing of qos policies between a subset of tenants."}],"source_content_type":"text/x-yaml","patch_set":14,"id":"5a5ae5dd_59281833","line":5,"updated":"2016-02-08 12:40:03.000000000","message":"Neutron now supports sharing of QoS policies for a subset of tenants.","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"258f391690c5237d569e905d259d63ae342ca6ee","unresolved":false,"context_lines":[{"line_number":2,"context_line":"prelude: \u003e"},{"line_number":3,"context_line":"   RBAC support for QoS policy"},{"line_number":4,"context_line":"features:"},{"line_number":5,"context_line":"  - Neutron supports now sharing of qos policies between a subset of tenants."}],"source_content_type":"text/x-yaml","patch_set":14,"id":"3a57f1b5_ee2873e4","line":5,"in_reply_to":"5a5ae5dd_59281833","updated":"2016-02-15 22:48:57.000000000","message":"Done","commit_id":"95297b0caa5a5247fd4e1927c1213662378cf275"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"388d318ee26f01becdf2231c4f3c570057557960","unresolved":false,"context_lines":[{"line_number":2,"context_line":"prelude: \u003e"},{"line_number":3,"context_line":"   RBAC support for QoS policies"},{"line_number":4,"context_line":"features:"},{"line_number":5,"context_line":"  - Neutron now supports sharing of qos policies between a subset of tenants."}],"source_content_type":"text/x-yaml","patch_set":28,"id":"bae84128_f2a62952","line":5,"range":{"start_line":5,"start_character":36,"end_line":5,"end_character":39},"updated":"2016-02-25 11:00:39.000000000","message":"QoS","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"},{"author":{"_account_id":18485,"name":"Haim Daniel","email":"hdaniel@redhat.com","username":"hdaniel"},"change_message_id":"1407200d9de697fd6ebec25ac97a7f72375dc19e","unresolved":false,"context_lines":[{"line_number":2,"context_line":"prelude: \u003e"},{"line_number":3,"context_line":"   RBAC support for QoS policies"},{"line_number":4,"context_line":"features:"},{"line_number":5,"context_line":"  - Neutron now supports sharing of qos policies between a subset of tenants."}],"source_content_type":"text/x-yaml","patch_set":28,"id":"bae84128_c81ff807","line":5,"range":{"start_line":5,"start_character":36,"end_line":5,"end_character":39},"in_reply_to":"bae84128_f2a62952","updated":"2016-02-25 17:24:55.000000000","message":"Done","commit_id":"aaa7bbd42bcab4c868593e25cb7aefc7d73710ab"}]}
