)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"c28fb51476cdc6ea8407b9cb102ce5a9a0373261","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This commit adds a new credential provider to use credentials provided"},{"line_number":10,"context_line":"from a list of available credentials."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: I69c3105f8b413102ea567ccb92965572ce03d679"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":19,"id":"baada198_8802c30a","line":11,"updated":"2014-07-29 21:06:22.000000000","message":"The bp is set in the topic, but it would be nice to have it also in the commit message ;)","commit_id":"fd1850dbbb4ea3f1e336f715213ca48cf8927a88"}],"etc/accounts.yaml.sample":[{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"0b16c935254337f0594a5c0183182ce243b10ad7","unresolved":false,"context_lines":[{"line_number":1,"context_line":"- username: \u0027user_1\u0027"},{"line_number":2,"context_line":"  tenant: \u0027test_tenant_1\u0027"},{"line_number":3,"context_line":"  password: \u0027test_password\u0027"},{"line_number":4,"context_line":""},{"line_number":5,"context_line":"- username: \u0027user_2\u0027"}],"source_content_type":"application/octet-stream","patch_set":16,"id":"baada198_f74d6573","line":2,"updated":"2014-07-18 21:45:56.000000000","message":"I\u0027d use tenant_name like everywhere else","commit_id":"f647e51e1a8f92738946b0bb8d2c4d5548d27538"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"554134c0b93644dc8852a45ad72746746326ab2a","unresolved":false,"context_lines":[{"line_number":1,"context_line":"- username: \u0027user_1\u0027"},{"line_number":2,"context_line":"  tenant: \u0027test_tenant_1\u0027"},{"line_number":3,"context_line":"  password: \u0027test_password\u0027"},{"line_number":4,"context_line":""},{"line_number":5,"context_line":"- username: \u0027user_2\u0027"}],"source_content_type":"application/octet-stream","patch_set":16,"id":"baada198_7a3bced0","line":2,"in_reply_to":"baada198_f74d6573","updated":"2014-07-21 13:46:52.000000000","message":"Done","commit_id":"f647e51e1a8f92738946b0bb8d2c4d5548d27538"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"c28fb51476cdc6ea8407b9cb102ce5a9a0373261","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"baada198_036bf4b9","line":8,"updated":"2014-07-29 21:06:22.000000000","message":"I would include an example of v3 credentials as well, so with domain_name as well.","commit_id":"fd1850dbbb4ea3f1e336f715213ca48cf8927a88"}],"tempest/common/accounts.py":[{"author":{"_account_id":6683,"name":"Pavel Sedlák","email":"psedlak@redhat.com","username":"psedlak"},"change_message_id":"ea208a5227dffbce4d6ee0393a981498721bb999","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    def _get_free_hash(self, hashes):"},{"line_number":53,"context_line":"        if not os.path.isdir(self.accounts_dir):"},{"line_number":54,"context_line":"            os.path.mkdir(self.accounts_dir)"},{"line_number":55,"context_line":"            # Create File from first hash (since none are in use)"},{"line_number":56,"context_line":"            open(os.path.join(self.accounts_dir, hashes[0]), \u0027w\u0027).close()"},{"line_number":57,"context_line":"            return hashes[0]"},{"line_number":58,"context_line":"        for hash in hashes:"}],"source_content_type":"text/x-python","patch_set":4,"id":"baada198_c061e7a9","line":55,"updated":"2014-07-16 15:07:20.000000000","message":"I would prefer if this explicit \"use first hash\" part could be removed, and just one implementation of \u0027create hash file\u0027 used (for the price of looping into/over first element and one additional isfile check) - to do not have repeated code","commit_id":"fb6da722e460ef65fab4ddc819415bcba4b7da9d"},{"author":{"_account_id":6683,"name":"Pavel Sedlák","email":"psedlak@redhat.com","username":"psedlak"},"change_message_id":"ea208a5227dffbce4d6ee0393a981498721bb999","unresolved":false,"context_lines":[{"line_number":57,"context_line":"            return hashes[0]"},{"line_number":58,"context_line":"        for hash in hashes:"},{"line_number":59,"context_line":"            path \u003d os.path.isfile(os.path.join(self.accounts_dir, hash))"},{"line_number":60,"context_line":"            if not os.path.isfile(path):"},{"line_number":61,"context_line":"                open(path, \u0027w\u0027).close()"},{"line_number":62,"context_line":"                return hash"},{"line_number":63,"context_line":"        msg \u003d \u0027Insufficient number of users provided\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"baada198_6001fbae","line":60,"updated":"2014-07-16 15:07:20.000000000","message":"these two lines do isfile(isfile(os.path.join()))","commit_id":"fb6da722e460ef65fab4ddc819415bcba4b7da9d"},{"author":{"_account_id":6683,"name":"Pavel Sedlák","email":"psedlak@redhat.com","username":"psedlak"},"change_message_id":"ea208a5227dffbce4d6ee0393a981498721bb999","unresolved":false,"context_lines":[{"line_number":71,"context_line":"    @lockutils.lock(\u0027test_accounts_io\u0027, external\u003dTrue)"},{"line_number":72,"context_line":"    def remove_hash(self, hash):"},{"line_number":73,"context_line":"        hash_path \u003d os.path.join(self.accounts_dir, hash)"},{"line_number":74,"context_line":"        if not os.path.isfile(os.path.join(self.accounts_dir, hash)):"},{"line_number":75,"context_line":"            LOG.warning(\u0027Expected an account lock file %s to remove, but \u0027"},{"line_number":76,"context_line":"                        \u0027one did not exist\u0027)"},{"line_number":77,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":4,"id":"baada198_e0b26b05","line":74,"updated":"2014-07-16 15:07:20.000000000","message":"path.join not needed as hash_path is already prepared one line above","commit_id":"fb6da722e460ef65fab4ddc819415bcba4b7da9d"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"18e865fbd7679a890deba549866d5461b48849c7","unresolved":false,"context_lines":[{"line_number":97,"context_line":"        username, tenant \u003d self._get_creds()"},{"line_number":98,"context_line":"        primary_credential \u003d auth.get_credentials(username\u003dusername,"},{"line_number":99,"context_line":"                                                  tenant_name\u003dtenant,"},{"line_number":100,"context_line":"                                                  password\u003dCONF.password)"},{"line_number":101,"context_line":"        self.credentials[\u0027primary\u0027] \u003d primary_credential"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    def get_alt_creds(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_32c65617","line":100,"updated":"2014-07-17 08:57:47.000000000","message":"You have to return creds as well here","commit_id":"8149df7f7c930191080d4fda82e6daac566c3b31"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"18e865fbd7679a890deba549866d5461b48849c7","unresolved":false,"context_lines":[{"line_number":105,"context_line":"        alt_credential \u003d auth.get_credentials(username\u003dusername,"},{"line_number":106,"context_line":"                                              tenant_name\u003dtenant,"},{"line_number":107,"context_line":"                                              password\u003dCONF.password)"},{"line_number":108,"context_line":"        self.credentials[\u0027alt\u0027] \u003d alt_credential"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    def clear_isolated_creds(self):"},{"line_number":111,"context_line":"        for creds in self.credentials.values():"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_8c946ce9","line":108,"updated":"2014-07-17 08:57:47.000000000","message":"You have to return creds as well here","commit_id":"8149df7f7c930191080d4fda82e6daac566c3b31"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"0b16c935254337f0594a5c0183182ce243b10ad7","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        for account in accounts:"},{"line_number":49,"context_line":"            temp_hash \u003d hashlib.md5()"},{"line_number":50,"context_line":"            temp_hash.update(str(account))"},{"line_number":51,"context_line":"            hash_dict[temp_hash.hexdigest()] \u003d {"},{"line_number":52,"context_line":"                \u0027username\u0027: account[\u0027username\u0027],"},{"line_number":53,"context_line":"                \u0027tenant\u0027: account[\u0027tenant\u0027],"},{"line_number":54,"context_line":"                \u0027password\u0027: account[\u0027password\u0027]"}],"source_content_type":"text/x-python","patch_set":16,"id":"baada198_f72ba5e8","line":51,"updated":"2014-07-18 21:45:56.000000000","message":"I would prefer an approach that does not depend on the actual list of fields that make credentials if possible, as that is variable (v2/v3).","commit_id":"f647e51e1a8f92738946b0bb8d2c4d5548d27538"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"554134c0b93644dc8852a45ad72746746326ab2a","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        for account in accounts:"},{"line_number":49,"context_line":"            temp_hash \u003d hashlib.md5()"},{"line_number":50,"context_line":"            temp_hash.update(str(account))"},{"line_number":51,"context_line":"            hash_dict[temp_hash.hexdigest()] \u003d {"},{"line_number":52,"context_line":"                \u0027username\u0027: account[\u0027username\u0027],"},{"line_number":53,"context_line":"                \u0027tenant\u0027: account[\u0027tenant\u0027],"},{"line_number":54,"context_line":"                \u0027password\u0027: account[\u0027password\u0027]"}],"source_content_type":"text/x-python","patch_set":16,"id":"baada198_9a6422e6","line":51,"in_reply_to":"baada198_f72ba5e8","updated":"2014-07-21 13:46:52.000000000","message":"Done","commit_id":"f647e51e1a8f92738946b0bb8d2c4d5548d27538"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"0b16c935254337f0594a5c0183182ce243b10ad7","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def _get_creds(self):"},{"line_number":80,"context_line":"        free_hash \u003d self._get_free_hash(self.hashes.keys())"},{"line_number":81,"context_line":"        creds \u003d self.hash_dict[free_hash]"},{"line_number":82,"context_line":"        return creds[\u0027user\u0027], creds[\u0027tenant\u0027], creds[\u0027password\u0027]"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    @lockutils.synchronized(\u0027test_accounts_io\u0027, external\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":16,"id":"baada198_b7c04d2c","line":81,"updated":"2014-07-18 21:45:56.000000000","message":"If you keep the names in the YAML matching the names of fields in credentials, you can make this simpler and already working for other credentials format (e.g. v3).\n\n\nJust return the creds dict here, and L108/L109 become:\n\n\ncreds \u003d self._get_creds()\n\nprimary_credentials \u003d auth.get_credentials(**creds)\n\n\nSimilar thing for L118/L119","commit_id":"f647e51e1a8f92738946b0bb8d2c4d5548d27538"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"554134c0b93644dc8852a45ad72746746326ab2a","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def _get_creds(self):"},{"line_number":80,"context_line":"        free_hash \u003d self._get_free_hash(self.hashes.keys())"},{"line_number":81,"context_line":"        creds \u003d self.hash_dict[free_hash]"},{"line_number":82,"context_line":"        return creds[\u0027user\u0027], creds[\u0027tenant\u0027], creds[\u0027password\u0027]"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    @lockutils.synchronized(\u0027test_accounts_io\u0027, external\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":16,"id":"baada198_7a690ebd","line":81,"in_reply_to":"baada198_b7c04d2c","updated":"2014-07-21 13:46:52.000000000","message":"Done","commit_id":"f647e51e1a8f92738946b0bb8d2c4d5548d27538"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"c28fb51476cdc6ea8407b9cb102ce5a9a0373261","unresolved":false,"context_lines":[{"line_number":87,"context_line":"            if not os.listdir(self.accounts_dir):"},{"line_number":88,"context_line":"                os.rmdir(self.accounts_dir)"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def get_hash(self, username):"},{"line_number":91,"context_line":"        for hash in self.hash_dict:"},{"line_number":92,"context_line":"            if self.hash_dict[hash][\u0027username\u0027] \u003d\u003d username:"},{"line_number":93,"context_line":"                return hash"}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_69d65155","line":90,"updated":"2014-07-29 21:06:22.000000000","message":"You should not rely on username being unique. \nI\u0027d do:\n\ndef get_hash(self, creds)","commit_id":"fd1850dbbb4ea3f1e336f715213ca48cf8927a88"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"59755231469b3e3211cc28eb9f2c3a516eb5ffff","unresolved":false,"context_lines":[{"line_number":87,"context_line":"            if not os.listdir(self.accounts_dir):"},{"line_number":88,"context_line":"                os.rmdir(self.accounts_dir)"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def get_hash(self, username):"},{"line_number":91,"context_line":"        for hash in self.hash_dict:"},{"line_number":92,"context_line":"            if self.hash_dict[hash][\u0027username\u0027] \u003d\u003d username:"},{"line_number":93,"context_line":"                return hash"}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_6019fb79","line":90,"in_reply_to":"baada198_69d65155","updated":"2014-08-04 01:28:37.000000000","message":"Well it was just intended to be an easy lookup function, but I guess I can do a more complex matching to be better about it.","commit_id":"fd1850dbbb4ea3f1e336f715213ca48cf8927a88"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"c28fb51476cdc6ea8407b9cb102ce5a9a0373261","unresolved":false,"context_lines":[{"line_number":93,"context_line":"                return hash"},{"line_number":94,"context_line":"        raise AttributeError(\u0027Invalid Username %s\u0027 % username)"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    def remove_credentials(self, username):"},{"line_number":97,"context_line":"        hash \u003d self.get_hash(username)"},{"line_number":98,"context_line":"        self.remove_hash(hash, self.accounts_dir)"},{"line_number":99,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_e9d18157","line":96,"updated":"2014-07-29 21:06:22.000000000","message":"Ditto (L90)","commit_id":"fd1850dbbb4ea3f1e336f715213ca48cf8927a88"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"59755231469b3e3211cc28eb9f2c3a516eb5ffff","unresolved":false,"context_lines":[{"line_number":93,"context_line":"                return hash"},{"line_number":94,"context_line":"        raise AttributeError(\u0027Invalid Username %s\u0027 % username)"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    def remove_credentials(self, username):"},{"line_number":97,"context_line":"        hash \u003d self.get_hash(username)"},{"line_number":98,"context_line":"        self.remove_hash(hash, self.accounts_dir)"},{"line_number":99,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_d71033f6","line":96,"in_reply_to":"baada198_e9d18157","updated":"2014-08-04 01:28:37.000000000","message":"Done","commit_id":"fd1850dbbb4ea3f1e336f715213ca48cf8927a88"}],"tempest/config.py":[{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"0b16c935254337f0594a5c0183182ce243b10ad7","unresolved":false,"context_lines":[{"line_number":38,"context_line":"               default\u003dNone,"},{"line_number":39,"context_line":"               help\u003d\"Path to the yaml file that contains the list of \""},{"line_number":40,"context_line":"                    \"credentials to use for running tests\"),"},{"line_number":41,"context_line":"    cfg.StrOpt(\u0027password\u0027,"},{"line_number":42,"context_line":"               default\u003dNone,"},{"line_number":43,"context_line":"               help\u003d\"Password for all of the users listed in the list\"),"},{"line_number":44,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":16,"id":"baada198_b7168df0","line":41,"updated":"2014-07-18 21:45:56.000000000","message":"This is not used anymore. We could actually keep it, and when parsing the YAML, if password for an account is not set use this.","commit_id":"f647e51e1a8f92738946b0bb8d2c4d5548d27538"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"554134c0b93644dc8852a45ad72746746326ab2a","unresolved":false,"context_lines":[{"line_number":38,"context_line":"               default\u003dNone,"},{"line_number":39,"context_line":"               help\u003d\"Path to the yaml file that contains the list of \""},{"line_number":40,"context_line":"                    \"credentials to use for running tests\"),"},{"line_number":41,"context_line":"    cfg.StrOpt(\u0027password\u0027,"},{"line_number":42,"context_line":"               default\u003dNone,"},{"line_number":43,"context_line":"               help\u003d\"Password for all of the users listed in the list\"),"},{"line_number":44,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":16,"id":"baada198_9aab42d5","line":41,"in_reply_to":"baada198_b7168df0","updated":"2014-07-21 13:46:52.000000000","message":"I\u0027ll remove it for now, if we decide we want to add a default password field here in the future we can always add it back.","commit_id":"f647e51e1a8f92738946b0bb8d2c4d5548d27538"},{"author":{"_account_id":1192,"name":"David Kranz","email":"dkranz@redhat.com","username":"david-kranz"},"change_message_id":"ccdc273f5bdb3b9893e9c53ec0eed064f54d8413","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"AuthGroup \u003d ["},{"line_number":37,"context_line":"    cfg.StrOpt(\u0027test_accounts_file\u0027,"},{"line_number":38,"context_line":"               default\u003dNone,"},{"line_number":39,"context_line":"               help\u003d\"Path to the yaml file that contains the list of \""},{"line_number":40,"context_line":"                    \"credentials to use for running tests\"),"},{"line_number":41,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_483b4b39","line":38,"updated":"2014-07-29 20:08:53.000000000","message":"Why not default to etc/accounts.yaml?","commit_id":"fd1850dbbb4ea3f1e336f715213ca48cf8927a88"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"59755231469b3e3211cc28eb9f2c3a516eb5ffff","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"AuthGroup \u003d ["},{"line_number":37,"context_line":"    cfg.StrOpt(\u0027test_accounts_file\u0027,"},{"line_number":38,"context_line":"               default\u003dNone,"},{"line_number":39,"context_line":"               help\u003d\"Path to the yaml file that contains the list of \""},{"line_number":40,"context_line":"                    \"credentials to use for running tests\"),"},{"line_number":41,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_57dc2345","line":38,"in_reply_to":"baada198_483b4b39","updated":"2014-08-04 01:28:37.000000000","message":"Done","commit_id":"fd1850dbbb4ea3f1e336f715213ca48cf8927a88"}],"tempest/tests/common/test_accounts.py":[{"author":{"_account_id":6683,"name":"Pavel Sedlák","email":"psedlak@redhat.com","username":"psedlak"},"change_message_id":"2cdb1f8914eff8411d1abc67752332ab949686ad","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        self.useFixture(mockpatch.Patch("},{"line_number":88,"context_line":"            \u0027tempest.common.accounts.read_accounts_yaml\u0027,"},{"line_number":89,"context_line":"            return_value\u003dtest_accounts))"},{"line_number":90,"context_line":"        cfg.CONF.set_default(\u0027test_accounts_file\u0027, test_accounts, group\u003d\u0027auth\u0027)"},{"line_number":91,"context_line":"        # hash_list \u003d self._get_hash_list(test_accounts)"},{"line_number":92,"context_line":"        # test_account_class \u003d accounts.Accounts(\u0027test_name\u0027)"}],"source_content_type":"text/x-python","patch_set":17,"id":"baada198_f5d852f2","line":90,"range":{"start_line":90,"start_character":51,"end_line":90,"end_character":64},"updated":"2014-07-23 08:56:51.000000000","message":"_file path set to list value?","commit_id":"ef78c85aa3eedf05cd6c169ac2c776b2843f35bc"}]}
