)]}'
{"nova/common/policy.py":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"8bec073e98128ab253a0f7e39036d8743d12af5f","unresolved":false,"context_lines":[{"line_number":106,"context_line":"    @classmethod"},{"line_number":107,"context_line":"    def load_json(cls, data):"},{"line_number":108,"context_line":"        \"\"\"Init a brain using json instead of a rules dictionary.\"\"\""},{"line_number":109,"context_line":"        global _BRAIN"},{"line_number":110,"context_line":"        rules_dict \u003d json.loads(data)"},{"line_number":111,"context_line":"        return cls(rules\u003drules_dict)"},{"line_number":112,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2Brg%3D","line":109,"updated":"2012-01-04 13:48:10.000000000","message":"Why a global here?","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"e5ef027acd27aa4f99983db3a1810ec74bbd4068","unresolved":false,"context_lines":[{"line_number":106,"context_line":"    @classmethod"},{"line_number":107,"context_line":"    def load_json(cls, data):"},{"line_number":108,"context_line":"        \"\"\"Init a brain using json instead of a rules dictionary.\"\"\""},{"line_number":109,"context_line":"        global _BRAIN"},{"line_number":110,"context_line":"        rules_dict \u003d json.loads(data)"},{"line_number":111,"context_line":"        return cls(rules\u003drules_dict)"},{"line_number":112,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BSs%3D","line":109,"in_reply_to":"AAAADH%2F%2F%2Brg%3D","updated":"2012-01-05 00:04:25.000000000","message":"Oops, typo from old version. Removed","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"8bec073e98128ab253a0f7e39036d8743d12af5f","unresolved":false,"context_lines":[{"line_number":155,"context_line":""},{"line_number":156,"context_line":"        # NOTE(termie): no OR rules matched"},{"line_number":157,"context_line":"        return False"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    def _check_rule(self, match, target_dict, cred_dict):"},{"line_number":160,"context_line":"        \"\"\"Recursively checks credentials based on the brains rules.\"\"\""},{"line_number":161,"context_line":"        new_match_list \u003d self.rules.get(match)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BrA%3D","line":158,"updated":"2012-01-04 13:48:10.000000000","message":"This looks too much verbose. I think you can rewrite it like this:\n\ndef check(self, match_list, target_dict, cred_dict):\n    if not match_list:\n        return True\n    for and_list in match_list:\n        if isinstance(and_list, basestring):\n            and_list \u003d (and_list,)\n        for match in and_list:\n            match_kind, match_value \u003d match.split(\u0027:\u0027, 1)\n            try:\n                f \u003d getattr(self, \u0027_check_%s\u0027 % match_kind)\n            except AttributeError:\n                if not self._check_generic(match, target_dict, cred_dict):\n                    break\n            else:\n                if not f(match_value, target_dict, cred_dict):\n                    break\n        else:\n            return True\n    return False\n\nor if you prefer a more functionnal way:\n\ndef _check(self, match, target_dict, cred_dict):\n    match_kind, match_value \u003d match.split(\u0027:\u0027, 1)\n    try:\n        f \u003d getattr(self, \u0027_check_%s\u0027 % match_kind)\n    except AttributeError:\n        if not self._check_generic(match, target_dict, cred_dict):\n            return False\n    else:\n        if not f(match_value, target_dict, cred_dict):\n            return False\n    return True\n\ndef check(self, match_list, target_dict, cred_dict):\n    if not match_list:\n        return True\n    for and_list in match_list:\n        if isinstance(and_list, basestring):\n            and_list \u003d (and_list,)\n        if all(map(self._check, and_list)):\n            return True\n    return False","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"e5ef027acd27aa4f99983db3a1810ec74bbd4068","unresolved":false,"context_lines":[{"line_number":155,"context_line":""},{"line_number":156,"context_line":"        # NOTE(termie): no OR rules matched"},{"line_number":157,"context_line":"        return False"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    def _check_rule(self, match, target_dict, cred_dict):"},{"line_number":160,"context_line":"        \"\"\"Recursively checks credentials based on the brains rules.\"\"\""},{"line_number":161,"context_line":"        new_match_list \u003d self.rules.get(match)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BSo%3D","line":158,"in_reply_to":"AAAADH%2F%2F%2BrA%3D","updated":"2012-01-05 00:04:25.000000000","message":"I tried using the for/else construct before and it is so uncommon that it tends to cause a lot of confusion.  In this case I think the verbosity is clearer.  That said, I like your functional version so I will switch to that.","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"8bec073e98128ab253a0f7e39036d8743d12af5f","unresolved":false,"context_lines":[{"line_number":207,"context_line":"        f \u003d urllib2.urlopen(url, post_data)"},{"line_number":208,"context_line":"        if f.read() \u003d\u003d \"True\":"},{"line_number":209,"context_line":"            return True"},{"line_number":210,"context_line":"        return False"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2Bqg%3D","line":210,"updated":"2012-01-04 13:48:10.000000000","message":"return f.read() \u003d\u003d \"True\"","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"e5ef027acd27aa4f99983db3a1810ec74bbd4068","unresolved":false,"context_lines":[{"line_number":207,"context_line":"        f \u003d urllib2.urlopen(url, post_data)"},{"line_number":208,"context_line":"        if f.read() \u003d\u003d \"True\":"},{"line_number":209,"context_line":"            return True"},{"line_number":210,"context_line":"        return False"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BSk%3D","line":210,"in_reply_to":"AAAADH%2F%2F%2Bqg%3D","updated":"2012-01-05 00:04:25.000000000","message":"nice","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"25ac37c6836c36b34c4a650c5653605d29819611","unresolved":false,"context_lines":[{"line_number":46,"context_line":""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"def enforce(match_list, target_dict, credentials_dict):"},{"line_number":49,"context_line":"    \"\"\"Enforces authorization of some rules against credentials."},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    :param match_list: nested tuples of data to match against"},{"line_number":52,"context_line":"    The basic brain supports three types of match lists:"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAADH%2F%2F%2BIg%3D","line":49,"updated":"2012-01-05 15:20:54.000000000","message":"You may want to look at nova.scheduler.filters.json_filter.py ... we had to solve a pretty similar problem already.","commit_id":"4175fed68a6a71852b756f9af75ebd07f64678ab"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"4f9ed3899cfa53e105b807a656bc8099b80f4e82","unresolved":false,"context_lines":[{"line_number":138,"context_line":"                if not f(match_value, target_dict, cred_dict):"},{"line_number":139,"context_line":"                    return False"},{"line_number":140,"context_line":"            return True"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"        if not match_list:"},{"line_number":143,"context_line":"            return True"},{"line_number":144,"context_line":"        for and_list in match_list:"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAADH%2F%2F%2BIo%3D","line":141,"updated":"2012-01-05 14:57:33.000000000","message":"Redefining _check each time is useless and cost more than defining it once in the class. And it can be considered as a private method.","commit_id":"4175fed68a6a71852b756f9af75ebd07f64678ab"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"4f9ed3899cfa53e105b807a656bc8099b80f4e82","unresolved":false,"context_lines":[{"line_number":154,"context_line":"        if new_match_list is None:"},{"line_number":155,"context_line":"            return False"},{"line_number":156,"context_line":"        return self.check(new_match_list, target_dict, cred_dict)"},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"    def _check_role(self, match, target_dict, cred_dict):"},{"line_number":159,"context_line":"        \"\"\"Check that there is a matching role in the cred dict.\"\"\""},{"line_number":160,"context_line":"        return match in cred_dict[\u0027roles\u0027]"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAADH%2F%2F%2BIU%3D","line":157,"updated":"2012-01-05 14:57:33.000000000","message":"I find this weird: you say that if the match list is empty, then the check is False.\nBut in check() you say that the if match list is empty, then the check is True.\n\nWhy not removing:\n\nif not match_list:\n    return True\n\non line 142 and then remove this check on lines 154-155 ?","commit_id":"4175fed68a6a71852b756f9af75ebd07f64678ab"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"c4b58b0b38bca49a7652ffaba4468332291101a5","unresolved":false,"context_lines":[{"line_number":154,"context_line":"        if new_match_list is None:"},{"line_number":155,"context_line":"            return False"},{"line_number":156,"context_line":"        return self.check(new_match_list, target_dict, cred_dict)"},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"    def _check_role(self, match, target_dict, cred_dict):"},{"line_number":159,"context_line":"        \"\"\"Check that there is a matching role in the cred dict.\"\"\""},{"line_number":160,"context_line":"        return match in cred_dict[\u0027roles\u0027]"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAADX%2F%2F%2F9U%3D","line":157,"in_reply_to":"AAAADH%2F%2F%2BIU%3D","updated":"2012-01-05 18:52:07.000000000","message":"Yes this is a little confusing. The check is actually supposed to show false if the rule doesn\u0027t exist.  It would be clearer with a try except so i will change it.\n\nThe other check just says that an empty rule set is always True.\nEmpty rule is not the same as No rule.","commit_id":"4175fed68a6a71852b756f9af75ebd07f64678ab"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"1eaf7d8a5dbb64c290a2fe5d4eef1f1f20f8ee8d","unresolved":false,"context_lines":[{"line_number":54,"context_line":"            looks like: (\u0027rule:compute:get_instance\u0027,)"},{"line_number":55,"context_line":"            Retrieves the named rule from the rules dict and recursively"},{"line_number":56,"context_line":"            checks against the contents of the rule."},{"line_number":57,"context_line":"        2) roles"},{"line_number":58,"context_line":"            looks like: (\u0027role:compute:admin\u0027,)"},{"line_number":59,"context_line":"            Matches if the specified role is in credentials_dict[\u0027roles\u0027]."},{"line_number":60,"context_line":"        3) generic"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAADX%2F%2F%2F84%3D","line":57,"updated":"2012-01-05 19:04:28.000000000","message":"friggin\u0027 Gerrit p.o.c lost my comment on this.\n\nAs we discussed at the summit, Roles is the wrong abstraction here. We should be checking Rights. Otherwise the number of explicit role checks we have to do will grow insanely for any meaningful deployment (and it will be nearly impossible to manage from the admin side). \n\nRole are just a collection of Rights. You can then do basic Set operations on the Rights when Roles are nested, excluded, joined, etc.","commit_id":"bf8eceee9c09f7def6e170042fafb917966e9ced"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"5e265a335e61487d64dd05e9c350033d8e1cf291","unresolved":false,"context_lines":[{"line_number":54,"context_line":"            looks like: (\u0027rule:compute:get_instance\u0027,)"},{"line_number":55,"context_line":"            Retrieves the named rule from the rules dict and recursively"},{"line_number":56,"context_line":"            checks against the contents of the rule."},{"line_number":57,"context_line":"        2) roles"},{"line_number":58,"context_line":"            looks like: (\u0027role:compute:admin\u0027,)"},{"line_number":59,"context_line":"            Matches if the specified role is in credentials_dict[\u0027roles\u0027]."},{"line_number":60,"context_line":"        3) generic"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAADX%2F%2F%2F4w%3D","line":57,"in_reply_to":"AAAADX%2F%2F%2F6Y%3D","updated":"2012-01-05 21:39:48.000000000","message":"the role is not can_delete_instance\nthat is the name of the rule/action.\nrules \u003d {\n\u0027compute:delete_instance\u0027: [[\u0027role:sysadmin\u0027], [\u0027role:netadmin\u0027]]\n}\n\nI think the Right is the entire rule.  The above says that the right to delete an instance is allowed for sysadmins and netadmins.\n\nSo the purpose of this is to define rights by mapping roles to actions.","commit_id":"bf8eceee9c09f7def6e170042fafb917966e9ced"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"2ec2afed1cd34e970f58e353a5c81f4d7fbde006","unresolved":false,"context_lines":[{"line_number":54,"context_line":"            looks like: (\u0027rule:compute:get_instance\u0027,)"},{"line_number":55,"context_line":"            Retrieves the named rule from the rules dict and recursively"},{"line_number":56,"context_line":"            checks against the contents of the rule."},{"line_number":57,"context_line":"        2) roles"},{"line_number":58,"context_line":"            looks like: (\u0027role:compute:admin\u0027,)"},{"line_number":59,"context_line":"            Matches if the specified role is in credentials_dict[\u0027roles\u0027]."},{"line_number":60,"context_line":"        3) generic"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAADX%2F%2F%2F6Y%3D","line":57,"in_reply_to":"AAAADX%2F%2F%2F7I%3D","updated":"2012-01-05 19:59:27.000000000","message":"I\u0027m probably bike shedding a little here, only because I\u0027m used to a certain vernacular.\n\nBut, if you\u0027re hacking \"Role\" to be \"Right\" by forcing one-action-per-role ... why not just call it a Right? \n\nDoes it make sense for a role to be called: can_delete_instance?","commit_id":"bf8eceee9c09f7def6e170042fafb917966e9ced"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"717dd3f483dc504b917cbf75aff12931bc282dc6","unresolved":false,"context_lines":[{"line_number":54,"context_line":"            looks like: (\u0027rule:compute:get_instance\u0027,)"},{"line_number":55,"context_line":"            Retrieves the named rule from the rules dict and recursively"},{"line_number":56,"context_line":"            checks against the contents of the rule."},{"line_number":57,"context_line":"        2) roles"},{"line_number":58,"context_line":"            looks like: (\u0027role:compute:admin\u0027,)"},{"line_number":59,"context_line":"            Matches if the specified role is in credentials_dict[\u0027roles\u0027]."},{"line_number":60,"context_line":"        3) generic"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAADX%2F%2F%2F7I%3D","line":57,"in_reply_to":"AAAADX%2F%2F%2F84%3D","updated":"2012-01-05 19:45:40.000000000","message":"I think this implementation supports this.  We are just doing the mapping of roles to actions in the brain as opposed to in an external service.  Look at the example policy file here:\n\nhttps://review.openstack.org/#patch,sidebyside,2767,3,etc/nova/policy.json\n\nessentially your policy can define a number of different roles that can do one action or \"right\" as you call it.\n\nYou can see that the policy.json is essentially mapping actions and roles.  It also allows us to do slightly more complicated things like map action to role + other info like project_id matches the credentials.\n\nI think this is just the inversion of what we discussed and is functionally equivalent.  We\u0027re saying\naction x can be done by [roles]\n\ninstead of:\nrole y can do [actions]\n\nping me on irc if this isn\u0027t clear or I\u0027m missing something","commit_id":"bf8eceee9c09f7def6e170042fafb917966e9ced"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"b40240ca87e6d51e78b8d4e366b1bf2ef84c388a","unresolved":false,"context_lines":[{"line_number":155,"context_line":"            new_match_list \u003d self.rules[match]"},{"line_number":156,"context_line":"        except KeyError:"},{"line_number":157,"context_line":"            return False"},{"line_number":158,"context_line":"        return self.check(new_match_list, target_dict, cred_dict)"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"    def _check_role(self, match, target_dict, cred_dict):"},{"line_number":161,"context_line":"        \"\"\"Check that there is a matching role in the cred dict.\"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAADX%2F%2F%2FwA%3D","line":158,"updated":"2012-01-06 08:52:01.000000000","message":"I think you did not answer my previous question. :)\nWhy not:\n\nreturn self.check(self.rules.get(\"match\"), target_dict, cred_dict)\n\nAnd remove:\n\nif not match_list:\n    return True\n\non line 142-143 ?","commit_id":"de1969f379a54842b269c3cbcd15a4a19023f04f"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"5e7503c92a95ef4e0c41f10dd25a87b16836e6a1","unresolved":false,"context_lines":[{"line_number":155,"context_line":"            new_match_list \u003d self.rules[match]"},{"line_number":156,"context_line":"        except KeyError:"},{"line_number":157,"context_line":"            return False"},{"line_number":158,"context_line":"        return self.check(new_match_list, target_dict, cred_dict)"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"    def _check_role(self, match, target_dict, cred_dict):"},{"line_number":161,"context_line":"        \"\"\"Check that there is a matching role in the cred dict.\"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAD3%2F%2F%2F2c%3D","line":158,"in_reply_to":"AAAADX%2F%2F%2FoA%3D","updated":"2012-01-09 14:26:51.000000000","message":"Done","commit_id":"de1969f379a54842b269c3cbcd15a4a19023f04f"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"79fef96bbdadf8f6efe6043b3a462f3c228fb336","unresolved":false,"context_lines":[{"line_number":155,"context_line":"            new_match_list \u003d self.rules[match]"},{"line_number":156,"context_line":"        except KeyError:"},{"line_number":157,"context_line":"            return False"},{"line_number":158,"context_line":"        return self.check(new_match_list, target_dict, cred_dict)"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"    def _check_role(self, match, target_dict, cred_dict):"},{"line_number":161,"context_line":"        \"\"\"Check that there is a matching role in the cred dict.\"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAADX%2F%2F%2FoA%3D","line":158,"in_reply_to":"AAAADX%2F%2F%2FwA%3D","updated":"2012-01-06 18:07:44.000000000","message":"I made an inline comment explaining why that wouldn\u0027t work, but here is another one with an example.\n\nThe code you are suggesting works differently from this code in the case of an empty rule.\n\nThis version:\nrules {\n\u0027exists\u0027: [],\n\u0027example2\u0027: [[\u0027rule:exists\u0027]], # -\u003e returns True\n\u0027example3\u0027 [[\u0027rule.noexists\u0027]] # -\u003e returns False\n}\n\nYour version:\nrules {\n\u0027exists\u0027: [],\n\u0027example2\u0027: [[\u0027rule:exists\u0027]], # -\u003e returns False\n\u0027example3\u0027 [[\u0027rule.noexists\u0027]] # -\u003e returns False\n}","commit_id":"de1969f379a54842b269c3cbcd15a4a19023f04f"}],"nova/policy.py":[{"author":{"_account_id":1132,"name":"Brian Waldon","email":"brian@waldon.cc","username":"bcwaldon"},"change_message_id":"c253aec7559f73fff1457d262988a912fc6fa7e5","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from nova.common import policy"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"FLAGS \u003d flags.FLAGS"},{"line_number":26,"context_line":"flags.DEFINE_string(\u0027policy_file\u0027, \u0027policy.json\u0027,"},{"line_number":27,"context_line":"                    _(\u0027JSON file representing policy\u0027))"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"_POLICY_PATH \u003d None"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BmQ%3D","line":26,"updated":"2012-01-04 15:59:05.000000000","message":"I\u0027m not 100% sold on the default value here. For example, this will resolve to /var/run/policy.json when SmokeStack runs (since it doesn\u0027t have the updated config yet). Maybe it should default to /etc/nova/policy.json?","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":1132,"name":"Brian Waldon","email":"brian@waldon.cc","username":"bcwaldon"},"change_message_id":"1ba855e9e7653a5a277969e13de4277cbc0bad25","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from nova.common import policy"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"FLAGS \u003d flags.FLAGS"},{"line_number":26,"context_line":"flags.DEFINE_string(\u0027policy_file\u0027, \u0027policy.json\u0027,"},{"line_number":27,"context_line":"                    _(\u0027JSON file representing policy\u0027))"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"_POLICY_PATH \u003d None"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BO8%3D","line":26,"in_reply_to":"AAAADH%2F%2F%2BSg%3D","updated":"2012-01-05 04:16:34.000000000","message":"You\u0027re right. Ignore me.","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"e5ef027acd27aa4f99983db3a1810ec74bbd4068","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from nova.common import policy"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"FLAGS \u003d flags.FLAGS"},{"line_number":26,"context_line":"flags.DEFINE_string(\u0027policy_file\u0027, \u0027policy.json\u0027,"},{"line_number":27,"context_line":"                    _(\u0027JSON file representing policy\u0027))"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"_POLICY_PATH \u003d None"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BSg%3D","line":26,"in_reply_to":"AAAADH%2F%2F%2BmQ%3D","updated":"2012-01-05 00:04:25.000000000","message":"not sure the problem here. the config file loading code looks in a number of places, including /etc/nova/policy.json\n\nsee utils.find_config()","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":1132,"name":"Brian Waldon","email":"brian@waldon.cc","username":"bcwaldon"},"change_message_id":"b1d662ab0224a35684698754f103647eaae59ad1","unresolved":false,"context_lines":[{"line_number":59,"context_line":"    global _POLICY_CACHE"},{"line_number":60,"context_line":"    if not _POLICY_PATH:"},{"line_number":61,"context_line":"        _POLICY_PATH \u003d utils.find_config(FLAGS.policy_file)"},{"line_number":62,"context_line":"    old \u003d dict(_POLICY_CACHE)"},{"line_number":63,"context_line":"    data \u003d utils.read_cached_file(_POLICY_PATH, _POLICY_CACHE)"},{"line_number":64,"context_line":"    if old !\u003d _POLICY_CACHE:"},{"line_number":65,"context_line":"        policy.set_brain(policy.HttpBrain.load_json(data))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2Bms%3D","line":62,"updated":"2012-01-04 15:49:38.000000000","message":"You need to use copy.deepcopy here (assuming you\u0027re trying to create a copy of this dict and that dict can have nested dicts)","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"e5ef027acd27aa4f99983db3a1810ec74bbd4068","unresolved":false,"context_lines":[{"line_number":59,"context_line":"    global _POLICY_CACHE"},{"line_number":60,"context_line":"    if not _POLICY_PATH:"},{"line_number":61,"context_line":"        _POLICY_PATH \u003d utils.find_config(FLAGS.policy_file)"},{"line_number":62,"context_line":"    old \u003d dict(_POLICY_CACHE)"},{"line_number":63,"context_line":"    data \u003d utils.read_cached_file(_POLICY_PATH, _POLICY_CACHE)"},{"line_number":64,"context_line":"    if old !\u003d _POLICY_CACHE:"},{"line_number":65,"context_line":"        policy.set_brain(policy.HttpBrain.load_json(data))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BSc%3D","line":62,"in_reply_to":"AAAADH%2F%2F%2Bms%3D","updated":"2012-01-05 00:04:25.000000000","message":"_POLICY_CACHE is just a dict that contains two keys.  Really I think the read_cached_file should indicate whether the contents were reloaded so I don\u0027t have to do this ugly check. I will rewrite it.","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":1132,"name":"Brian Waldon","email":"brian@waldon.cc","username":"bcwaldon"},"change_message_id":"b1d662ab0224a35684698754f103647eaae59ad1","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    if old !\u003d _POLICY_CACHE:"},{"line_number":65,"context_line":"        policy.set_brain(policy.HttpBrain.load_json(data))"},{"line_number":66,"context_line":"    match_list \u003d (\u0027rule:%s\u0027 % action,)"},{"line_number":67,"context_line":"    target_dict \u003d target"},{"line_number":68,"context_line":"    credentials_dict \u003d context.to_dict()"},{"line_number":69,"context_line":"    try:"},{"line_number":70,"context_line":"        policy.enforce(match_list, target_dict, credentials_dict)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2Bmo%3D","line":67,"updated":"2012-01-04 15:49:38.000000000","message":"Is it really necessary to reassign this?","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"e5ef027acd27aa4f99983db3a1810ec74bbd4068","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    if old !\u003d _POLICY_CACHE:"},{"line_number":65,"context_line":"        policy.set_brain(policy.HttpBrain.load_json(data))"},{"line_number":66,"context_line":"    match_list \u003d (\u0027rule:%s\u0027 % action,)"},{"line_number":67,"context_line":"    target_dict \u003d target"},{"line_number":68,"context_line":"    credentials_dict \u003d context.to_dict()"},{"line_number":69,"context_line":"    try:"},{"line_number":70,"context_line":"        policy.enforce(match_list, target_dict, credentials_dict)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BSU%3D","line":67,"in_reply_to":"AAAADH%2F%2F%2Bmo%3D","updated":"2012-01-05 00:04:25.000000000","message":"no, when I initially wrote it i thought I would have to munge it.  Will remove","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"}],"nova/tests/test_policy.py":[{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"25ac37c6836c36b34c4a650c5653605d29819611","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2011 Piston Cloud Computing, Inc."},{"line_number":4,"context_line":"# All Rights Reserved."},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAADH%2F%2F%2BIY%3D","line":3,"updated":"2012-01-05 15:20:54.000000000","message":"Piston?","commit_id":"4175fed68a6a71852b756f9af75ebd07f64678ab"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"c4b58b0b38bca49a7652ffaba4468332291101a5","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2011 Piston Cloud Computing, Inc."},{"line_number":4,"context_line":"# All Rights Reserved."},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAADX%2F%2F%2F%2BE%3D","line":3,"in_reply_to":"AAAADH%2F%2F%2BIY%3D","updated":"2012-01-05 18:52:07.000000000","message":"Yeah this file was written by josh from Piston. We were collaborating and it was easier to just submit it together as one patch","commit_id":"4175fed68a6a71852b756f9af75ebd07f64678ab"},{"author":{"_account_id":688,"name":"Sandy Walsh","email":"sandy.walsh@rackspace.com","username":"sandy-walsh"},"change_message_id":"25ac37c6836c36b34c4a650c5653605d29819611","unresolved":false,"context_lines":[{"line_number":26,"context_line":"from nova import flags"},{"line_number":27,"context_line":"from nova import policy"},{"line_number":28,"context_line":"from nova import test"},{"line_number":29,"context_line":"from nova.common import policy as common_policy"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"FLAGS \u003d flags.FLAGS"},{"line_number":32,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAADH%2F%2F%2BIQ%3D","line":29,"updated":"2012-01-05 15:20:54.000000000","message":"doesn\u0027t match latest HACKING (should be before context)","commit_id":"4175fed68a6a71852b756f9af75ebd07f64678ab"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"c4b58b0b38bca49a7652ffaba4468332291101a5","unresolved":false,"context_lines":[{"line_number":26,"context_line":"from nova import flags"},{"line_number":27,"context_line":"from nova import policy"},{"line_number":28,"context_line":"from nova import test"},{"line_number":29,"context_line":"from nova.common import policy as common_policy"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"FLAGS \u003d flags.FLAGS"},{"line_number":32,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAADX%2F%2F%2F94%3D","line":29,"in_reply_to":"AAAADH%2F%2F%2BIQ%3D","updated":"2012-01-05 18:52:07.000000000","message":"interesting.  Didn\u0027t realize this changed. Fixed","commit_id":"4175fed68a6a71852b756f9af75ebd07f64678ab"},{"author":{"_account_id":475,"name":"Rick Harris","email":"rick.harris@rackspace.com","username":"rconradharris"},"change_message_id":"e71e0b3df522604e20eb87ba1e6ec585171e1dd0","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2011 Piston Cloud Computing, Inc."},{"line_number":4,"context_line":"# All Rights Reserved."},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAD3%2F%2F%2Fwo%3D","line":3,"updated":"2012-01-09 18:46:39.000000000","message":"Shouldn\u0027t this be OpenStack LLC?","commit_id":"64948204a8fd4d18b61c0ff485189afebf345a56"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"03cd04c3e71a36bdf4b8e7dacf9e241af893e673","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2011 Piston Cloud Computing, Inc."},{"line_number":4,"context_line":"# All Rights Reserved."},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAD3%2F%2F%2Fvs%3D","line":3,"in_reply_to":"AAAAD3%2F%2F%2Fwo%3D","updated":"2012-01-09 19:26:12.000000000","message":"You\u0027re the second to have mentioned this, but josh at piston wrote this code, so I think this header is fine.","commit_id":"64948204a8fd4d18b61c0ff485189afebf345a56"}],"nova/tests/test_utils.py":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"8bec073e98128ab253a0f7e39036d8743d12af5f","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        fake_file \u003d self.mox.CreateMockAnything()"},{"line_number":353,"context_line":"        fake_file.read().AndReturn(fake_contents)"},{"line_number":354,"context_line":"        fake_file.close()"},{"line_number":355,"context_line":"        __builtin__.open(mox.IgnoreArg()).AndReturn(fake_file)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"        self.mox.ReplayAll()"},{"line_number":358,"context_line":"        cache_data \u003d {\"data\": 1123, \"mtime\": 1}"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BqQ%3D","line":355,"updated":"2012-01-04 13:48:10.000000000","message":"Does this really belong to this patch?\nIf it\u0027s another bug, you should fix in another commit I think.","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"e5ef027acd27aa4f99983db3a1810ec74bbd4068","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        fake_file \u003d self.mox.CreateMockAnything()"},{"line_number":353,"context_line":"        fake_file.read().AndReturn(fake_contents)"},{"line_number":354,"context_line":"        fake_file.close()"},{"line_number":355,"context_line":"        __builtin__.open(mox.IgnoreArg()).AndReturn(fake_file)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"        self.mox.ReplayAll()"},{"line_number":358,"context_line":"        cache_data \u003d {\"data\": 1123, \"mtime\": 1}"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BSM%3D","line":355,"in_reply_to":"AAAADH%2F%2F%2BqQ%3D","updated":"2012-01-05 00:04:25.000000000","message":"probably could be in another patch.  The tests wouldn\u0027t pass due to too many open file descriptors because the file is never closed, so I fixed it.","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"}],"nova/utils.py":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"8bec073e98128ab253a0f7e39036d8743d12af5f","unresolved":false,"context_lines":[{"line_number":1174,"context_line":"    \"\"\""},{"line_number":1175,"context_line":"    mtime \u003d os.path.getmtime(filename)"},{"line_number":1176,"context_line":"    if cache_info and mtime \u003d\u003d cache_info.get(\u0027mtime\u0027):"},{"line_number":1177,"context_line":"        return cache_info[\u0027data\u0027]"},{"line_number":1178,"context_line":""},{"line_number":1179,"context_line":"    fd \u003d open(filename)"},{"line_number":1180,"context_line":"    data \u003d fd.read()"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BqI%3D","line":1177,"updated":"2012-01-04 13:48:10.000000000","message":"Does this really belong to this patch too?\nIt seems like a bug fix that deserve a different patch.","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"e5ef027acd27aa4f99983db3a1810ec74bbd4068","unresolved":false,"context_lines":[{"line_number":1174,"context_line":"    \"\"\""},{"line_number":1175,"context_line":"    mtime \u003d os.path.getmtime(filename)"},{"line_number":1176,"context_line":"    if cache_info and mtime \u003d\u003d cache_info.get(\u0027mtime\u0027):"},{"line_number":1177,"context_line":"        return cache_info[\u0027data\u0027]"},{"line_number":1178,"context_line":""},{"line_number":1179,"context_line":"    fd \u003d open(filename)"},{"line_number":1180,"context_line":"    data \u003d fd.read()"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BSE%3D","line":1177,"in_reply_to":"AAAADH%2F%2F%2BqI%3D","updated":"2012-01-05 00:04:25.000000000","message":"seems excessive to  do a whole separate patch just to get rid of the unneeded None, but I will do a separate patch to write this function to indicate whether this file was reloaded and do it there.","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"8bec073e98128ab253a0f7e39036d8743d12af5f","unresolved":false,"context_lines":[{"line_number":1179,"context_line":"    fd \u003d open(filename)"},{"line_number":1180,"context_line":"    data \u003d fd.read()"},{"line_number":1181,"context_line":"    fd.close()"},{"line_number":1182,"context_line":"    cache_info[\u0027data\u0027] \u003d data"},{"line_number":1183,"context_line":"    cache_info[\u0027mtime\u0027] \u003d mtime"},{"line_number":1184,"context_line":"    return data"},{"line_number":1185,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BqM%3D","line":1182,"updated":"2012-01-04 13:48:10.000000000","message":"I\u0027d prefer to see the with statement used:\n\n\nwith open(filename) as fd:\n    data \u003d fd.read()","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"},{"author":{"_account_id":67,"name":"Vish Ishaya","email":"vishvananda@gmail.com","username":"vishvananda"},"change_message_id":"e5ef027acd27aa4f99983db3a1810ec74bbd4068","unresolved":false,"context_lines":[{"line_number":1179,"context_line":"    fd \u003d open(filename)"},{"line_number":1180,"context_line":"    data \u003d fd.read()"},{"line_number":1181,"context_line":"    fd.close()"},{"line_number":1182,"context_line":"    cache_info[\u0027data\u0027] \u003d data"},{"line_number":1183,"context_line":"    cache_info[\u0027mtime\u0027] \u003d mtime"},{"line_number":1184,"context_line":"    return data"},{"line_number":1185,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAADH%2F%2F%2BSA%3D","line":1182,"in_reply_to":"AAAADH%2F%2F%2BqM%3D","updated":"2012-01-05 00:04:25.000000000","message":"I actually did this initially but it made the Mox test more complicated.  I will do the change with the other patch.","commit_id":"68678c394681c41f7029f28c651d26fedd364c9c"}]}
