)]}'
{"doc/source/getting-started/policy_mapping.rst":[{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"811f74a7cbc9553f7fec788fa3e9dbae3e41571a","unresolved":false,"context_lines":[{"line_number":205,"context_line":"identity:get_domain_config_default                         - GET /v3/domains/config/default"},{"line_number":206,"context_line":"                                                           - GET /v3/domains/config/{group}/default"},{"line_number":207,"context_line":"                                                           - GET /v3/domains/config/{group}/{option}/default"},{"line_number":208,"context_line":"identity:create_project_tag                                - PUT /v3/projects/{project_id}/tags/{tag_name}"},{"line_number":209,"context_line":"identity:delete_project_tag                                - DELETE /v3/projects/{project_id}/tags/{tag_name}"},{"line_number":210,"context_line":"identity:get_project_tag                                   - GET /v3/projects/{project_id}/tags/{tag_name}"},{"line_number":211,"context_line":"identity:list_project_tags                                 - GET /v3/projects/{project_id}/tags"},{"line_number":212,"context_line":"identity:remove_all_project_tags                           - PUT /v3/projects/{project_id}/tags"},{"line_number":213,"context_line":"identity:update_project_tags                               - PUT /v3/projects/{project_id}/tags"},{"line_number":214,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":".. _grant_resources:"}],"source_content_type":"text/x-rst","patch_set":91,"id":"ff346bd7_726082a6","line":213,"range":{"start_line":208,"start_character":0,"end_line":213,"end_character":95},"updated":"2017-07-25 13:32:38.000000000","message":"do we really want to protect these separately as opposed to just identity:update_project?","commit_id":"3031b3af1695370db5e121ab6e1ececd9d3840df"}],"etc/policy.v3cloudsample.json":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"20c942ef0cb4a98d8de22eb384377478729647b4","unresolved":false,"context_lines":[{"line_number":122,"context_line":"    \"project_admin_for_domain_role_grants\": \"rule:admin_required and project_domain_id:%(target.role.domain_id)s and project_id:%(project_id)s\","},{"line_number":123,"context_line":"    \"domain_admin_for_list_grants\": \"rule:admin_required and rule:domain_admin_grant_match\","},{"line_number":124,"context_line":"    \"project_admin_for_list_grants\": \"rule:admin_required and project_id:%(project_id)s\","},{"line_number":125,"context_line":" "},{"line_number":126,"context_line":"    \"admin_on_domain_filter\" : \"rule:admin_required and domain_id:%(scope.domain.id)s\","},{"line_number":127,"context_line":"    \"admin_on_project_filter\" : \"rule:admin_required and project_id:%(scope.project.id)s\","},{"line_number":128,"context_line":"    \"admin_on_domain_of_project_filter\" : \"rule:admin_required and domain_id:%(target.project.domain_id)s\","}],"source_content_type":"application/json","patch_set":96,"id":"ff346bd7_34ec0ef2","side":"PARENT","line":125,"range":{"start_line":125,"start_character":0,"end_line":125,"end_character":1},"updated":"2017-07-26 04:27:29.000000000","message":"This shouldn\u0027t be part of this change, not sure if this is a random whitespace?","commit_id":"dc3d0407ffbdad6fac1f0c12bc7f89d75d5eb589"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":47,"context_line":"    \"identity:get_project_tag\": \"rule:admin_required\","},{"line_number":48,"context_line":"    \"identity:list_project_tags\": \"rule:admin_required\","},{"line_number":49,"context_line":"    \"identity:remove_all_project_tags\": \"rule:admin_required\","},{"line_number":50,"context_line":"    \"identity:update_project_tags\": \"rule:admin_required\","},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    \"admin_and_matching_target_user_domain_id\": \"rule:admin_required and domain_id:%(target.user.domain_id)s\","},{"line_number":53,"context_line":"    \"admin_and_matching_user_domain_id\": \"rule:admin_required and domain_id:%(user.domain_id)s\","}],"source_content_type":"application/json","patch_set":105,"id":"ff346bd7_6fcddf64","side":"PARENT","line":50,"updated":"2017-07-27 17:03:58.000000000","message":"Why remove these?","commit_id":"6e9b790da1a86465aaef665b9504c39ac1c05efd"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"b915e834347d433809026146863e76be18275908","unresolved":false,"context_lines":[{"line_number":47,"context_line":"    \"identity:get_project_tag\": \"rule:admin_required\","},{"line_number":48,"context_line":"    \"identity:list_project_tags\": \"rule:admin_required\","},{"line_number":49,"context_line":"    \"identity:remove_all_project_tags\": \"rule:admin_required\","},{"line_number":50,"context_line":"    \"identity:update_project_tags\": \"rule:admin_required\","},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    \"admin_and_matching_target_user_domain_id\": \"rule:admin_required and domain_id:%(target.user.domain_id)s\","},{"line_number":53,"context_line":"    \"admin_and_matching_user_domain_id\": \"rule:admin_required and domain_id:%(user.domain_id)s\","}],"source_content_type":"application/json","patch_set":105,"id":"df3967d1_854bf285","side":"PARENT","line":50,"in_reply_to":"ff346bd7_6fcddf64","updated":"2017-07-28 19:52:51.000000000","message":"https://review.openstack.org/#/c/486757/12/etc/policy.v3cloudsample.json","commit_id":"6e9b790da1a86465aaef665b9504c39ac1c05efd"}],"keystone/catalog/controllers.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":566,"context_line":"                endpoint_group_ref[\u0027project_id\u0027])"},{"line_number":567,"context_line":"            if project:"},{"line_number":568,"context_line":"                project[\u0027tags\u0027] \u003d self.resource_api.list_project_tags("},{"line_number":569,"context_line":"                    endpoint_group_ref[\u0027project_id\u0027])"},{"line_number":570,"context_line":"                projects.append(project)"},{"line_number":571,"context_line":"        return resource.controllers.ProjectV3.wrap_collection("},{"line_number":572,"context_line":"            request.context_dict, projects)"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_6ffb9f78","line":569,"updated":"2017-07-27 17:03:58.000000000","message":"Doesn\u0027t look like we have a test case for this in this patch set.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2cf35b5391a660e15b098e5230e380fe2df2bf48","unresolved":false,"context_lines":[{"line_number":566,"context_line":"                endpoint_group_ref[\u0027project_id\u0027])"},{"line_number":567,"context_line":"            if project:"},{"line_number":568,"context_line":"                project[\u0027tags\u0027] \u003d self.resource_api.list_project_tags("},{"line_number":569,"context_line":"                    endpoint_group_ref[\u0027project_id\u0027])"},{"line_number":570,"context_line":"                projects.append(project)"},{"line_number":571,"context_line":"        return resource.controllers.ProjectV3.wrap_collection("},{"line_number":572,"context_line":"            request.context_dict, projects)"}],"source_content_type":"text/x-python","patch_set":108,"id":"ff346bd7_ba6f7929","line":569,"updated":"2017-07-27 21:34:45.000000000","message":"This should come back in the reference when you use properties in the resource driver.","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"}],"keystone/common/context.py":[{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"e12d042b36755116ceb1bc9beef20663a6ab6e91","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        self.domain_id \u003d kwargs.pop(\u0027domain_id \u0027, None)"},{"line_number":30,"context_line":"        self.user_domain_id \u003d kwargs.pop(\u0027user_domain_id \u0027, None)"},{"line_number":31,"context_line":"        self.project_domain_id \u003d kwargs.pop(\u0027project_domain_id \u0027, None)"},{"line_number":32,"context_line":"        self.project_tag_id \u003d kwargs.pop(\u0027project_tag_id\u0027, None)"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"        self.project_name \u003d kwargs.pop(\u0027project_name\u0027, None)"},{"line_number":35,"context_line":"        self.domain_name \u003d kwargs.pop(\u0027domain_name\u0027, None)"}],"source_content_type":"text/x-python","patch_set":102,"id":"ff346bd7_962cbeac","line":32,"range":{"start_line":32,"start_character":42,"end_line":32,"end_character":56},"updated":"2017-07-26 21:57:03.000000000","message":"project_tag_id is no more!","commit_id":"8c481485b4b99a2d9bcad9d747133d71fc48ef3d"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"02477031177d15cf1e887c91166c3ff3be5321fd","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        self.domain_id \u003d kwargs.pop(\u0027domain_id \u0027, None)"},{"line_number":30,"context_line":"        self.user_domain_id \u003d kwargs.pop(\u0027user_domain_id \u0027, None)"},{"line_number":31,"context_line":"        self.project_domain_id \u003d kwargs.pop(\u0027project_domain_id \u0027, None)"},{"line_number":32,"context_line":"        self.project_tag_id \u003d kwargs.pop(\u0027project_tag_id\u0027, None)"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"        self.project_name \u003d kwargs.pop(\u0027project_name\u0027, None)"},{"line_number":35,"context_line":"        self.domain_name \u003d kwargs.pop(\u0027domain_name\u0027, None)"}],"source_content_type":"text/x-python","patch_set":102,"id":"ff346bd7_59868968","line":32,"range":{"start_line":32,"start_character":42,"end_line":32,"end_character":56},"in_reply_to":"ff346bd7_962cbeac","updated":"2017-07-26 22:06:07.000000000","message":"the whole line could probably go","commit_id":"8c481485b4b99a2d9bcad9d747133d71fc48ef3d"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        self.domain_id \u003d kwargs.pop(\u0027domain_id \u0027, None)"},{"line_number":30,"context_line":"        self.user_domain_id \u003d kwargs.pop(\u0027user_domain_id \u0027, None)"},{"line_number":31,"context_line":"        self.project_domain_id \u003d kwargs.pop(\u0027project_domain_id \u0027, None)"},{"line_number":32,"context_line":"        self.project_tag_id \u003d kwargs.pop(\u0027project_tag_id\u0027, None)"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"        self.project_name \u003d kwargs.pop(\u0027project_name\u0027, None)"},{"line_number":35,"context_line":"        self.domain_name \u003d kwargs.pop(\u0027domain_name\u0027, None)"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_f29c16c1","line":32,"updated":"2017-07-27 17:03:58.000000000","message":"What are these bits for? This is usually specific to context stuff.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"025c22ba95505c7e691a89b4d2a30e10d664a4cf","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        self.domain_id \u003d kwargs.pop(\u0027domain_id \u0027, None)"},{"line_number":30,"context_line":"        self.user_domain_id \u003d kwargs.pop(\u0027user_domain_id \u0027, None)"},{"line_number":31,"context_line":"        self.project_domain_id \u003d kwargs.pop(\u0027project_domain_id \u0027, None)"},{"line_number":32,"context_line":"        self.project_tag_id \u003d kwargs.pop(\u0027project_tag_id\u0027, None)"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"        self.project_name \u003d kwargs.pop(\u0027project_name\u0027, None)"},{"line_number":35,"context_line":"        self.domain_name \u003d kwargs.pop(\u0027domain_name\u0027, None)"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_45b74a88","line":32,"in_reply_to":"ff346bd7_f29c16c1","updated":"2017-07-28 19:22:49.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2cf35b5391a660e15b098e5230e380fe2df2bf48","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        self.username \u003d kwargs.pop(\u0027username\u0027, None)"},{"line_number":36,"context_line":"        self.user_domain_name \u003d kwargs.pop(\u0027user_domain_name\u0027, None)"},{"line_number":37,"context_line":"        self.project_domain_name \u003d kwargs.pop(\u0027project_domain_name\u0027, None)"},{"line_number":38,"context_line":"        self.project_tag_name \u003d kwargs.pop(\u0027project_tag_name\u0027, None)"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"        self.is_delegated_auth \u003d kwargs.pop(\u0027is_delegated_auth\u0027, False)"},{"line_number":41,"context_line":""}],"source_content_type":"text/x-python","patch_set":108,"id":"ff346bd7_5a708d08","line":38,"updated":"2017-07-27 21:34:45.000000000","message":"comment here from a previous patch set still applies.","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"}],"keystone/common/json_home.py":[{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"137817a58bf6743f1b1613c9dd045cc4c136d1bd","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        \u0027https://docs.openstack.org/api/openstack-identity/3/ext/%s/%s/param/\u0027"},{"line_number":41,"context_line":"        \u0027%s\u0027 % (extension_name, extension_version, parameter_name))"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"# TODO(aselius): Change the parameters for tags_id"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class Parameters(object):"}],"source_content_type":"text/x-python","patch_set":83,"id":"ff346bd7_e3f723f5","line":43,"range":{"start_line":43,"start_character":2,"end_line":43,"end_character":6},"updated":"2017-07-24 19:53:22.000000000","message":"remove todo","commit_id":"5416f25d9b9f26b2deaf7c5ed5c81b5648ce6dd2"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"ab635b0a153640b20202d5aa1684e68a2ccaeea9","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        \u0027https://docs.openstack.org/api/openstack-identity/3/ext/%s/%s/param/\u0027"},{"line_number":41,"context_line":"        \u0027%s\u0027 % (extension_name, extension_version, parameter_name))"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"# TODO(aselius): Change the parameters for tags_id"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class Parameters(object):"}],"source_content_type":"text/x-python","patch_set":87,"id":"ff346bd7_77e40dad","line":43,"range":{"start_line":43,"start_character":0,"end_line":43,"end_character":50},"updated":"2017-07-24 22:06:56.000000000","message":"Is this done?","commit_id":"ccbc030b7597b97c731ed87762851a1fa212001b"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"92c6c43f02c15eb96b7a8f119319960fc931608e","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        \u0027https://docs.openstack.org/api/openstack-identity/3/ext/%s/%s/param/\u0027"},{"line_number":41,"context_line":"        \u0027%s\u0027 % (extension_name, extension_version, parameter_name))"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"# TODO(aselius): Change the parameters for tags_id"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class Parameters(object):"}],"source_content_type":"text/x-python","patch_set":87,"id":"ff346bd7_f2400b0a","line":43,"range":{"start_line":43,"start_character":0,"end_line":43,"end_character":50},"in_reply_to":"ff346bd7_77e40dad","updated":"2017-07-24 22:20:40.000000000","message":"Done","commit_id":"ccbc030b7597b97c731ed87762851a1fa212001b"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"e12d042b36755116ceb1bc9beef20663a6ab6e91","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    ROLE_ID \u003d build_v3_parameter_relation(\u0027role_id\u0027)"},{"line_number":54,"context_line":"    SERVICE_ID \u003d build_v3_parameter_relation(\u0027service_id\u0027)"},{"line_number":55,"context_line":"    USER_ID \u003d build_v3_parameter_relation(\u0027user_id\u0027)"},{"line_number":56,"context_line":"    PROJECT_TAG_ID \u003d build_v3_parameter_relation(\u0027project_tag_id\u0027)"},{"line_number":57,"context_line":"    TAG_VALUE \u003d build_v3_parameter_relation(\u0027tag_value\u0027)"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":""}],"source_content_type":"text/x-python","patch_set":102,"id":"ff346bd7_362192b1","line":56,"range":{"start_line":56,"start_character":50,"end_line":56,"end_character":64},"updated":"2017-07-26 21:57:03.000000000","message":"project_tag_id is no more!","commit_id":"8c481485b4b99a2d9bcad9d747133d71fc48ef3d"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"02477031177d15cf1e887c91166c3ff3be5321fd","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    ROLE_ID \u003d build_v3_parameter_relation(\u0027role_id\u0027)"},{"line_number":54,"context_line":"    SERVICE_ID \u003d build_v3_parameter_relation(\u0027service_id\u0027)"},{"line_number":55,"context_line":"    USER_ID \u003d build_v3_parameter_relation(\u0027user_id\u0027)"},{"line_number":56,"context_line":"    PROJECT_TAG_ID \u003d build_v3_parameter_relation(\u0027project_tag_id\u0027)"},{"line_number":57,"context_line":"    TAG_VALUE \u003d build_v3_parameter_relation(\u0027tag_value\u0027)"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":""}],"source_content_type":"text/x-python","patch_set":102,"id":"ff346bd7_59eb2912","line":56,"range":{"start_line":56,"start_character":50,"end_line":56,"end_character":64},"in_reply_to":"ff346bd7_362192b1","updated":"2017-07-26 22:06:07.000000000","message":"ditto whole line could prolly go","commit_id":"8c481485b4b99a2d9bcad9d747133d71fc48ef3d"}],"keystone/common/policies/base.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"8dbe62afb4f52e5da9c8d07c99788933574380c9","unresolved":false,"context_lines":[{"line_number":30,"context_line":"RULE_SERVICE_OR_ADMIN \u003d \u0027rule:service_or_admin\u0027"},{"line_number":31,"context_line":"RULE_TRUST_OWNER \u003d \u0027user_id:%(trust.trustor_user_id)s\u0027"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"# TODO(aselius): Add project tag rules here"},{"line_number":34,"context_line":"rules \u003d ["},{"line_number":35,"context_line":"    policy.RuleDefault("},{"line_number":36,"context_line":"        name\u003d\u0027admin_required\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f201791_48baa2de","line":33,"range":{"start_line":33,"start_character":0,"end_line":33,"end_character":43},"updated":"2017-06-20 20:28:20.000000000","message":"I don\u0027t think we need a separate rule for tags here (yet).","commit_id":"261144e4376e407c91d641ce1ffc965046fad54c"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"c2580f885beff92f7d06f0df27dd26578d536e42","unresolved":false,"context_lines":[{"line_number":30,"context_line":"RULE_SERVICE_OR_ADMIN \u003d \u0027rule:service_or_admin\u0027"},{"line_number":31,"context_line":"RULE_TRUST_OWNER \u003d \u0027user_id:%(trust.trustor_user_id)s\u0027"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"# TODO(aselius): Add project tag rules here"},{"line_number":34,"context_line":"rules \u003d ["},{"line_number":35,"context_line":"    policy.RuleDefault("},{"line_number":36,"context_line":"        name\u003d\u0027admin_required\u0027,"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f201791_a3bdd969","line":33,"range":{"start_line":33,"start_character":0,"end_line":33,"end_character":43},"updated":"2017-06-20 21:35:31.000000000","message":"Shouldn\u0027t need this","commit_id":"fe472f9154840af2c9fe3ab25f6dc8a1a9bbb120"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0569481e0f26a37275c25717ba33395bd543f133","unresolved":false,"context_lines":[{"line_number":30,"context_line":"RULE_SERVICE_OR_ADMIN \u003d \u0027rule:service_or_admin\u0027"},{"line_number":31,"context_line":"RULE_TRUST_OWNER \u003d \u0027user_id:%(trust.trustor_user_id)s\u0027"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"rules \u003d ["},{"line_number":35,"context_line":"    policy.RuleDefault("},{"line_number":36,"context_line":"        name\u003d\u0027admin_required\u0027,"}],"source_content_type":"text/x-python","patch_set":25,"id":"3f1d235d_700cf03a","side":"PARENT","line":33,"updated":"2017-06-30 21:16:02.000000000","message":"Remove this, we don\u0027t need to change this file","commit_id":"966fb5125cf1178d8804cf130726fc2a5c581344"}],"keystone/common/policies/project.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"8dbe62afb4f52e5da9c8d07c99788933574380c9","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        description\u003d\u0027Delete project.\u0027,"},{"line_number":52,"context_line":"        operations\u003d[{\u0027path\u0027: \u0027/v3/projects/{project_id}\u0027,"},{"line_number":53,"context_line":"                     \u0027method\u0027: \u0027DELETE\u0027}]),"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    # TODO(aselius): add PUT projects/{project_id}/tags"},{"line_number":56,"context_line":"    # add GETprojects/{project_id}/tags/{value}"},{"line_number":57,"context_line":"    # add PUT projects/{project_id}/tags/{value}"},{"line_number":58,"context_line":"    # add DELETE projects/{project_id}/tags"},{"line_number":59,"context_line":"    # add DELETE projects/{project_id}/tags/{value}"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    policy.DocumentedRuleDefault("},{"line_number":62,"context_line":"        name\u003dbase.IDENTITY % \u0027get_project_tags\u0027,"},{"line_number":63,"context_line":"        check_str\u003dbase.RULE_ADMIN_OR_OWNER,"},{"line_number":64,"context_line":"        description\u003d\"List tags a project\","},{"line_number":65,"context_line":"        operations\u003d[{\u0027path\u0027: \u0027/v3/projects/{project_id}/tags\u0027,"},{"line_number":66,"context_line":"                     \u0027method\u0027: \u0027GET\u0027}]),"},{"line_number":67,"context_line":"]"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"5f201791_a82db647","line":66,"range":{"start_line":54,"start_character":0,"end_line":66,"end_character":40},"updated":"2017-06-20 20:28:20.000000000","message":"I don\u0027t think you need this. In the spec we had decided that we will simply use the policy from /v3/projects.","commit_id":"261144e4376e407c91d641ce1ffc965046fad54c"}],"keystone/common/request.py":[{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"3dfd864f36071b01075c91e8494c24a88f8703e0","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            initiator.domain_id \u003d self.context.domain_id"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"        if self.context.project_tag_id:"},{"line_number":121,"context_line":"            initiator.project_tag_id \u003d self.context.project_tag_id"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        return initiator"},{"line_number":124,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"3f1d235d_2551a337","line":121,"range":{"start_line":121,"start_character":52,"end_line":121,"end_character":66},"updated":"2017-06-30 17:56:26.000000000","message":"did not add to context, which is making the gate check go haywire. will add.","commit_id":"89f2063bd5e86457df783ffa06478bc4d1de2e72"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"e12d042b36755116ceb1bc9beef20663a6ab6e91","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        if self.context.domain_id:"},{"line_number":118,"context_line":"            initiator.domain_id \u003d self.context.domain_id"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"        if self.context.project_tag_id:"},{"line_number":121,"context_line":"            initiator.project_tag_id \u003d self.context.project_tag_id"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        return initiator"}],"source_content_type":"text/x-python","patch_set":102,"id":"ff346bd7_d60fe634","line":120,"range":{"start_line":120,"start_character":24,"end_line":120,"end_character":38},"updated":"2017-07-26 21:57:03.000000000","message":"more project_tag_id...","commit_id":"8c481485b4b99a2d9bcad9d747133d71fc48ef3d"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"02477031177d15cf1e887c91166c3ff3be5321fd","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        if self.context.domain_id:"},{"line_number":118,"context_line":"            initiator.domain_id \u003d self.context.domain_id"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"        if self.context.project_tag_id:"},{"line_number":121,"context_line":"            initiator.project_tag_id \u003d self.context.project_tag_id"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        return initiator"},{"line_number":124,"context_line":""}],"source_content_type":"text/x-python","patch_set":102,"id":"ff346bd7_d9def96b","line":121,"range":{"start_line":120,"start_character":0,"end_line":121,"end_character":66},"updated":"2017-07-26 22:06:07.000000000","message":"the whole initiator can go i think, if this is needed for the notification.. should changed to the PKs?","commit_id":"8c481485b4b99a2d9bcad9d747133d71fc48ef3d"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            initiator.domain_id \u003d self.context.domain_id"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"        if self.context.project_tag_id:"},{"line_number":121,"context_line":"            initiator.project_tag_id \u003d self.context.project_tag_id"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        return initiator"},{"line_number":124,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_b2f0cefe","line":121,"updated":"2017-07-27 17:03:58.000000000","message":"Ah - this is what the context bits are for. We don\u0027t this for all things in keystone though. As far as notifications go, should we just send a notification saying the project tags were modified?","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"025c22ba95505c7e691a89b4d2a30e10d664a4cf","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            initiator.domain_id \u003d self.context.domain_id"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"        if self.context.project_tag_id:"},{"line_number":121,"context_line":"            initiator.project_tag_id \u003d self.context.project_tag_id"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        return initiator"},{"line_number":124,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_65c24eec","line":121,"in_reply_to":"ff346bd7_b2f0cefe","updated":"2017-07-28 19:22:49.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"}],"keystone/common/sql/contract_repo/versions/024_contract_add_project_tags_table.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"f4d2dce8b59b1467f211daf98f21db052adcc917","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":"#"},{"line_number":5,"context_line":"#         http://www.apache.org/licenses/LICENSE-2.0"},{"line_number":6,"context_line":"#"},{"line_number":7,"context_line":"#    Unless required by applicable law or agreed to in writing, software"},{"line_number":8,"context_line":"#    distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT"},{"line_number":9,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":10,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":11,"context_line":"#    under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"def upgrade(migrate_engine):"},{"line_number":15,"context_line":"    pass"}],"source_content_type":"text/x-python","patch_set":54,"id":"1f1a1f67_87deda0e","line":15,"range":{"start_line":1,"start_character":0,"end_line":15,"end_character":8},"updated":"2017-07-17 19:22:43.000000000","message":"This has been moved to a separate patch","commit_id":"5c1581fa7bb759d4a332776d558c83c47d77c726"}],"keystone/common/sql/data_migration_repo/versions/024_migrate_add_project_tags_table.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"f4d2dce8b59b1467f211daf98f21db052adcc917","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":54,"id":"1f1a1f67_67e3beda","updated":"2017-07-17 19:22:43.000000000","message":"This has been moved to a separate patch","commit_id":"5c1581fa7bb759d4a332776d558c83c47d77c726"}],"keystone/common/sql/expand_repo/versions/024_expand_add_project_tags_table.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b59764c290dc7c88d528e389a5ee2547820f9ec9","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        sql.Column(\u0027name\u0027, sql.String(60), nullable\u003dFalse),"},{"line_number":32,"context_line":"        sql.UniqueConstraint(\u0027project_id\u0027, \u0027name\u0027),"},{"line_number":33,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027,"},{"line_number":34,"context_line":"        mysql_charset\u003d\u0027utf8\u0027"},{"line_number":35,"context_line":"    )"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    project_tags_table.create(migrate_engine, checkfirst\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":52,"id":"1f1a1f67_d7cf0eae","line":34,"updated":"2017-07-14 23:26:58.000000000","message":"The migration and the resulting tests can probably get pulled out into their own change. That might help keep the overall patch set smaller and easier to review. This one is getting quite large.","commit_id":"1fc8231304c99e82d803cadac3ac7317fb66eca4"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"f4d2dce8b59b1467f211daf98f21db052adcc917","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":54,"id":"1f1a1f67_47e442e0","updated":"2017-07-17 19:22:43.000000000","message":"This has been moved to a separate patch","commit_id":"5c1581fa7bb759d4a332776d558c83c47d77c726"}],"keystone/conf/resource.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"c2580f885beff92f7d06f0df27dd26578d536e42","unresolved":false,"context_lines":[{"line_number":14,"context_line":""},{"line_number":15,"context_line":"from keystone.conf import utils"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"# NOTE(aselius): Where driver is set. Probably no need to touch conf"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"driver \u003d cfg.StrOpt("},{"line_number":20,"context_line":"    \u0027driver\u0027,"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f201791_a3627915","line":17,"range":{"start_line":17,"start_character":0,"end_line":17,"end_character":68},"updated":"2017-06-20 21:35:31.000000000","message":"Don\u0027t need to touch anything here.","commit_id":"fe472f9154840af2c9fe3ab25f6dc8a1a9bbb120"}],"keystone/exception.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0569481e0f26a37275c25717ba33395bd543f133","unresolved":false,"context_lines":[{"line_number":89,"context_line":"    title \u003d http_client.responses[http_client.BAD_REQUEST]"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"class InvalidError(Error):"},{"line_number":93,"context_line":"    message_format \u003d _(\"Invalid %(attribute)s in %(target)s.\""},{"line_number":94,"context_line":"                       \" The server could not comply with the request\""},{"line_number":95,"context_line":"                       \" since it is either malformed or otherwise\""}],"source_content_type":"text/x-python","patch_set":25,"id":"3f1d235d_b0028808","line":92,"range":{"start_line":92,"start_character":6,"end_line":92,"end_character":18},"updated":"2017-06-30 21:16:02.000000000","message":"I mentioned it in another note, but this just seems to be a copy of the \"ValidationError\" with slightly different wording. We can just tweak the \"attribute\" value to fit with \"ValidationError\"","commit_id":"89f2063bd5e86457df783ffa06478bc4d1de2e72"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"798a607ed5f3a799e88fe801518ddcda89203aa1","unresolved":false,"context_lines":[{"line_number":89,"context_line":"    title \u003d http_client.responses[http_client.BAD_REQUEST]"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"class InvalidError(Error):"},{"line_number":93,"context_line":"    message_format \u003d _(\"Invalid %(attribute)s in %(target)s.\""},{"line_number":94,"context_line":"                       \" The server could not comply with the request\""},{"line_number":95,"context_line":"                       \" since it is either malformed or otherwise\""}],"source_content_type":"text/x-python","patch_set":30,"id":"3f1d235d_e6ddbc42","line":92,"range":{"start_line":92,"start_character":6,"end_line":92,"end_character":18},"updated":"2017-07-03 23:04:32.000000000","message":"forgot to pull down from edit made on gerrit. remove this next patch","commit_id":"a20c5b2cba17c251f6a88769b7420c5c28724da5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b59764c290dc7c88d528e389a5ee2547820f9ec9","unresolved":false,"context_lines":[{"line_number":392,"context_line":""},{"line_number":393,"context_line":""},{"line_number":394,"context_line":"class ProjectTagNotFound(NotFound):"},{"line_number":395,"context_line":"    message_format \u003d _(\"Could not find project tag: %(project_tag_id)s.\")"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":""},{"line_number":398,"context_line":"class TokenNotFound(NotFound):"}],"source_content_type":"text/x-python","patch_set":52,"id":"1f1a1f67_f741ea0c","line":395,"updated":"2017-07-14 23:26:58.000000000","message":"This is another good example of something that can be pulled out into it\u0027s own change making an easy review.","commit_id":"1fc8231304c99e82d803cadac3ac7317fb66eca4"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"a65de2b9e6082282ba93b0c5509ab90dc9bfc2e4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":56,"id":"1f1a1f67_6a31435a","updated":"2017-07-17 20:05:08.000000000","message":"This was pulled out into https://review.openstack.org/#/c/484471/","commit_id":"4f94f88df2bc99bf3cdee81b57ee7b6efe653013"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f72f8c9c8b689bed68994209d08826f4c2c7065d","unresolved":false,"context_lines":[{"line_number":398,"context_line":""},{"line_number":399,"context_line":""},{"line_number":400,"context_line":"class ProjectTagNotFound(NotFound):"},{"line_number":401,"context_line":"    message_format \u003d _(\"Could not find project tag: %(project_tag_id)s.\")"},{"line_number":402,"context_line":""},{"line_number":403,"context_line":""},{"line_number":404,"context_line":"class TokenNotFound(NotFound):"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_f18a0268","line":401,"updated":"2017-07-26 15:54:11.000000000","message":"nit:\n\n  project_tag_name \n\nonly for the sake of clarify? We don\u0027t expect to ever emit the actual project_tag_id, do we?","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"ad5d4c300d3c756b69cb93be058895c049bcd5c2","unresolved":false,"context_lines":[{"line_number":398,"context_line":""},{"line_number":399,"context_line":""},{"line_number":400,"context_line":"class ProjectTagNotFound(NotFound):"},{"line_number":401,"context_line":"    message_format \u003d _(\"Could not find project tag: %(project_tag_id)s.\")"},{"line_number":402,"context_line":""},{"line_number":403,"context_line":""},{"line_number":404,"context_line":"class TokenNotFound(NotFound):"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_e96a16eb","line":401,"in_reply_to":"ff346bd7_f18a0268","updated":"2017-07-26 17:03:39.000000000","message":"this should actually be the tag_name, we swayed back and forth between having project_tag_ids as PKs and having name-project_ids as PKs, and this was neglected. Things that do raise this exception pass in the name atm however.","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":398,"context_line":""},{"line_number":399,"context_line":""},{"line_number":400,"context_line":"class ProjectTagNotFound(NotFound):"},{"line_number":401,"context_line":"    message_format \u003d _(\"Could not find project tag: %(project_tag_id)s.\")"},{"line_number":402,"context_line":""},{"line_number":403,"context_line":""},{"line_number":404,"context_line":"class TokenNotFound(NotFound):"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_922a6a29","line":401,"updated":"2017-07-27 17:03:58.000000000","message":"nit: since project tags are considered unique based on the tag name and the project id, we don\u0027t really have a project tag ID. I\u0027d be in favor of renaming this to project_tag_name to be more explicit.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"025c22ba95505c7e691a89b4d2a30e10d664a4cf","unresolved":false,"context_lines":[{"line_number":398,"context_line":""},{"line_number":399,"context_line":""},{"line_number":400,"context_line":"class ProjectTagNotFound(NotFound):"},{"line_number":401,"context_line":"    message_format \u003d _(\"Could not find project tag: %(project_tag_id)s.\")"},{"line_number":402,"context_line":""},{"line_number":403,"context_line":""},{"line_number":404,"context_line":"class TokenNotFound(NotFound):"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_a58ef6cd","line":401,"in_reply_to":"ff346bd7_922a6a29","updated":"2017-07-28 19:22:49.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"}],"keystone/federation/controllers.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"d194ecde9f5d5b5bf414d75a908dd081268e68d4","unresolved":false,"context_lines":[{"line_number":452,"context_line":"        domains \u003d domains + self.assignment_api.list_domains_for_user("},{"line_number":453,"context_line":"            request.auth_context[\u0027user_id\u0027])"},{"line_number":454,"context_line":"        # remove duplicates"},{"line_number":455,"context_line":"        domains \u003d [dict(t) for t in set([tuple(d.items()) for d in domains])]"},{"line_number":456,"context_line":"        return DomainV3.wrap_collection(request.context_dict, domains)"},{"line_number":457,"context_line":""},{"line_number":458,"context_line":""}],"source_content_type":"text/x-python","patch_set":112,"id":"bf3e73b7_60c9fe76","side":"PARENT","line":455,"range":{"start_line":455,"start_character":18,"end_line":455,"end_character":77},"updated":"2017-08-07 14:56:55.000000000","message":"These were changed because lists aren\u0027t hashable","commit_id":"71cef363810208708df0f467d05f3aeafafecd8b"}],"keystone/resource/backends/base.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"77c1b0ef717f7d7b640c04b03732692493bd2f0e","unresolved":false,"context_lines":[{"line_number":285,"context_line":"            additionalProperties: true"},{"line_number":286,"context_line":"        \"\"\""},{"line_number":287,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":288,"context_line":""},{"line_number":289,"context_line":"    @abc.abstractmethod"},{"line_number":290,"context_line":"    def delete_project_tag(self, project_id, tag_value):"},{"line_number":291,"context_line":"        \"\"\"Remove a single tag from a project."}],"source_content_type":"text/x-python","patch_set":16,"id":"5f201791_52e4fedf","line":288,"updated":"2017-06-26 16:24:30.000000000","message":"We should probably add an abstract for list_project_tags","commit_id":"560578d2c2e0dcfb6448c73dc2e0363abdd001d7"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"373da1f23bbc29a8bbac3413a09b1a8b28205b8f","unresolved":false,"context_lines":[{"line_number":285,"context_line":"            additionalProperties: true"},{"line_number":286,"context_line":"        \"\"\""},{"line_number":287,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":288,"context_line":""},{"line_number":289,"context_line":"    @abc.abstractmethod"},{"line_number":290,"context_line":"    def delete_project_tag(self, project_id, tag_value):"},{"line_number":291,"context_line":"        \"\"\"Remove a single tag from a project."}],"source_content_type":"text/x-python","patch_set":16,"id":"5f201791_d2e12e9d","line":288,"in_reply_to":"5f201791_52e4fedf","updated":"2017-06-26 16:28:08.000000000","message":"It was temporarily taken out because of a gate issue, but will add it back.","commit_id":"560578d2c2e0dcfb6448c73dc2e0363abdd001d7"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"400be4dc2c5576972019c310b5779b79c79ba672","unresolved":false,"context_lines":[{"line_number":37,"context_line":"# None. See comment in Project class of resource/backends/sql.py for more"},{"line_number":38,"context_line":"# details."},{"line_number":39,"context_line":"NULL_DOMAIN_ID \u003d \u0027\u003c\u003ckeystone.domain.root\u003e\u003e\u0027"},{"line_number":40,"context_line":"NULL_PROJECT_ID \u003d \u0027\u003c\u003ckesytone.project.root\u003e\u003e\u0027"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"@six.add_metaclass(abc.ABCMeta)"}],"source_content_type":"text/x-python","patch_set":58,"id":"1f1a1f67_e1c69668","line":40,"range":{"start_line":40,"start_character":21,"end_line":40,"end_character":29},"updated":"2017-07-17 23:12:29.000000000","message":"keystone*","commit_id":"1689ce25115f956765bd6b0628034036e27a4664"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"84199706cdba3b8cbfb9929fd1164866532bfdaf","unresolved":false,"context_lines":[{"line_number":297,"context_line":"            type: object"},{"line_number":298,"context_line":"            properties:"},{"line_number":299,"context_line":"                id:"},{"line_number":300,"context_line":"                    type: string"},{"line_number":301,"context_line":"                name:"},{"line_number":302,"context_line":"                    type: string"},{"line_number":303,"context_line":"                project_id:"}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_91445d1d","line":300,"range":{"start_line":300,"start_character":26,"end_line":300,"end_character":32},"updated":"2017-07-20 16:23:57.000000000","message":"should be Integer","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"84199706cdba3b8cbfb9929fd1164866532bfdaf","unresolved":false,"context_lines":[{"line_number":302,"context_line":"                    type: string"},{"line_number":303,"context_line":"                project_id:"},{"line_number":304,"context_line":"                    type: [string, null]"},{"line_number":305,"context_line":"                enabled:"},{"line_number":306,"context_line":"                    type: boolean"},{"line_number":307,"context_line":"            required: [id, name, project_id]"},{"line_number":308,"context_line":"            additionalProperties: true"},{"line_number":309,"context_line":""}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_315349e5","line":306,"range":{"start_line":305,"start_character":16,"end_line":306,"end_character":33},"updated":"2017-07-20 16:23:57.000000000","message":"Remove","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"28b46f86821247d3c9bdd77be6d3614925abb7ae","unresolved":false,"context_lines":[{"line_number":37,"context_line":"# None. See comment in Project class of resource/backends/sql.py for more"},{"line_number":38,"context_line":"# details."},{"line_number":39,"context_line":"NULL_DOMAIN_ID \u003d \u0027\u003c\u003ckeystone.domain.root\u003e\u003e\u0027"},{"line_number":40,"context_line":"NULL_PROJECT_ID \u003d \u0027\u003c\u003ckeystone.project.root\u003e\u003e\u0027"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"@six.add_metaclass(abc.ABCMeta)"}],"source_content_type":"text/x-python","patch_set":80,"id":"ff346bd7_bf3db9bc","line":40,"updated":"2017-07-24 15:39:36.000000000","message":"why is this needed?\n\nfor the domain case, it is needed for representing the most top level domain (which is a project already). e.g the parent domain of the default domain that exists in keystone","commit_id":"0d9df4582a608cd63a192640a48055c64fd0c7e9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"4eb38d17378cda3d3adaede82d624baedc1dc031","unresolved":false,"context_lines":[{"line_number":37,"context_line":"# None. See comment in Project class of resource/backends/sql.py for more"},{"line_number":38,"context_line":"# details."},{"line_number":39,"context_line":"NULL_DOMAIN_ID \u003d \u0027\u003c\u003ckeystone.domain.root\u003e\u003e\u0027"},{"line_number":40,"context_line":"NULL_PROJECT_ID \u003d \u0027\u003c\u003ckeystone.project.root\u003e\u003e\u0027"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"@six.add_metaclass(abc.ABCMeta)"}],"source_content_type":"text/x-python","patch_set":80,"id":"ff346bd7_022d8842","line":40,"in_reply_to":"ff346bd7_bf3db9bc","updated":"2017-07-24 16:10:44.000000000","message":"We don\u0027t need it. This is something vestigial that we were working with that we got rid of but forgot to delete. Thanks for pointing out","commit_id":"0d9df4582a608cd63a192640a48055c64fd0c7e9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"137817a58bf6743f1b1613c9dd045cc4c136d1bd","unresolved":false,"context_lines":[{"line_number":288,"context_line":"    def create_project_tag(self, project_tag):"},{"line_number":289,"context_line":"        \"\"\"Create the specified tag and adds it to the list in the project."},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        :param project_tag_id:"},{"line_number":292,"context_line":"        :param dict project_tag: The new project tag"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"        Project tags schema::"}],"source_content_type":"text/x-python","patch_set":83,"id":"ff346bd7_03f3470c","line":291,"range":{"start_line":291,"start_character":15,"end_line":291,"end_character":29},"updated":"2017-07-24 19:53:22.000000000","message":"delete","commit_id":"5416f25d9b9f26b2deaf7c5ed5c81b5648ce6dd2"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"137817a58bf6743f1b1613c9dd045cc4c136d1bd","unresolved":false,"context_lines":[{"line_number":291,"context_line":"        :param project_tag_id:"},{"line_number":292,"context_line":"        :param dict project_tag: The new project tag"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"        Project tags schema::"},{"line_number":295,"context_line":""},{"line_number":296,"context_line":"            type: object"},{"line_number":297,"context_line":"            properties:"}],"source_content_type":"text/x-python","patch_set":83,"id":"ff346bd7_a3d91b84","line":294,"range":{"start_line":294,"start_character":21,"end_line":294,"end_character":27},"updated":"2017-07-24 19:53:22.000000000","message":"this should have the id type:integer","commit_id":"5416f25d9b9f26b2deaf7c5ed5c81b5648ce6dd2"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"92c6c43f02c15eb96b7a8f119319960fc931608e","unresolved":false,"context_lines":[{"line_number":288,"context_line":"    def create_project_tag(self, project_tag):"},{"line_number":289,"context_line":"        \"\"\"Create the specified tag and adds it to the list in the project."},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        :param project_tag_id:"},{"line_number":292,"context_line":"        :param dict project_tag: The new project tag"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"        Project tags schema::"}],"source_content_type":"text/x-python","patch_set":87,"id":"ff346bd7_72541bcb","line":291,"range":{"start_line":291,"start_character":8,"end_line":291,"end_character":30},"updated":"2017-07-24 22:20:40.000000000","message":"delete","commit_id":"ccbc030b7597b97c731ed87762851a1fa212001b"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"92c6c43f02c15eb96b7a8f119319960fc931608e","unresolved":false,"context_lines":[{"line_number":295,"context_line":""},{"line_number":296,"context_line":"            type: object"},{"line_number":297,"context_line":"            properties:"},{"line_number":298,"context_line":"                name:"},{"line_number":299,"context_line":"                    type: string"},{"line_number":300,"context_line":"                project_id:"},{"line_number":301,"context_line":"                    type: [string, null]"}],"source_content_type":"text/x-python","patch_set":87,"id":"ff346bd7_3260d3a5","line":298,"range":{"start_line":298,"start_character":16,"end_line":298,"end_character":20},"updated":"2017-07-24 22:20:40.000000000","message":"add id: type:integer","commit_id":"ccbc030b7597b97c731ed87762851a1fa212001b"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"127c78adbedf388a3c3c0cb07fa6c6412b8f3a72","unresolved":false,"context_lines":[{"line_number":267,"context_line":"        \"\"\"Get project tag for project."},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"        :returns: project_tag_ref"},{"line_number":270,"context_line":"        :raises keystone.exception.ProjectTagNotFound: if project_tag_id"},{"line_number":271,"context_line":"                                                       does not exist"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":102,"id":"ff346bd7_d93dd9c4","line":270,"range":{"start_line":270,"start_character":58,"end_line":270,"end_character":72},"updated":"2017-07-26 21:59:33.000000000","message":"another","commit_id":"8c481485b4b99a2d9bcad9d747133d71fc48ef3d"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"8573c46a4f1dec0c104935cb33bef8c7b9a478a0","unresolved":false,"context_lines":[{"line_number":292,"context_line":""},{"line_number":293,"context_line":"        :raises keystone.exception.ProjectNotFound: if project_id does not"},{"line_number":294,"context_line":"                                                    exist"},{"line_number":295,"context_line":"        :raises keystone.exception.Conflict: if tag with the same id already"},{"line_number":296,"context_line":"                                             exist or same tag name under the"},{"line_number":297,"context_line":"                                             same project"},{"line_number":298,"context_line":""},{"line_number":299,"context_line":"        \"\"\""},{"line_number":300,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"}],"source_content_type":"text/x-python","patch_set":102,"id":"ff346bd7_397d057f","line":297,"range":{"start_line":295,"start_character":8,"end_line":297,"end_character":57},"updated":"2017-07-26 22:03:49.000000000","message":"No more conflicts!","commit_id":"8c481485b4b99a2d9bcad9d747133d71fc48ef3d"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"8573c46a4f1dec0c104935cb33bef8c7b9a478a0","unresolved":false,"context_lines":[{"line_number":313,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":314,"context_line":""},{"line_number":315,"context_line":"    @abc.abstractmethod"},{"line_number":316,"context_line":"    def delete_project_tag(self, project_id, tag_name):"},{"line_number":317,"context_line":"        \"\"\"Delete project tag with provided tag id.\"\"\""},{"line_number":318,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"    @abc.abstractmethod"},{"line_number":321,"context_line":"    def delete_all_project_tags(self, project_id):"},{"line_number":322,"context_line":"        \"\"\"Remove the entire tag list from the given project."},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"        :param project_id:"},{"line_number":325,"context_line":""},{"line_number":326,"context_line":"        \"\"\""},{"line_number":327,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"}],"source_content_type":"text/x-python","patch_set":102,"id":"ff346bd7_b968d5b8","line":324,"range":{"start_line":316,"start_character":3,"end_line":324,"end_character":26},"updated":"2017-07-26 22:03:49.000000000","message":"should there be a mention of the projectnotfound exception?","commit_id":"8c481485b4b99a2d9bcad9d747133d71fc48ef3d"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":262,"context_line":"        \"\"\""},{"line_number":263,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    @abc.abstractmethod"},{"line_number":266,"context_line":"    def get_project_tag(self, project_id, tag_name):"},{"line_number":267,"context_line":"        \"\"\"Get project tag for project."},{"line_number":268,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_52264217","line":265,"updated":"2017-07-27 17:03:58.000000000","message":"The interface definitions are another change that is easy to break out into a separate change (in case that helps you at all).","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":266,"context_line":"    def get_project_tag(self, project_id, tag_name):"},{"line_number":267,"context_line":"        \"\"\"Get project tag for project."},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"        :returns: project_tag_ref"},{"line_number":270,"context_line":"        :raises keystone.exception.ProjectTagNotFound: if project_tag_id"},{"line_number":271,"context_line":"                                                       does not exist"},{"line_number":272,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_32ee1eed","line":269,"updated":"2017-07-27 17:03:58.000000000","message":"We should document the parameters as well, to be consistent with the other interfaces here.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"025c22ba95505c7e691a89b4d2a30e10d664a4cf","unresolved":false,"context_lines":[{"line_number":266,"context_line":"    def get_project_tag(self, project_id, tag_name):"},{"line_number":267,"context_line":"        \"\"\"Get project tag for project."},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"        :returns: project_tag_ref"},{"line_number":270,"context_line":"        :raises keystone.exception.ProjectTagNotFound: if project_tag_id"},{"line_number":271,"context_line":"                                                       does not exist"},{"line_number":272,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_058822c4","line":269,"in_reply_to":"ff346bd7_32ee1eed","updated":"2017-07-28 19:22:49.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    @abc.abstractmethod"},{"line_number":277,"context_line":"    def create_project_tag(self, project_tag):"},{"line_number":278,"context_line":"        \"\"\"Create the specified tag and adds it to the list in the project."},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        :param dict project_tag: The new project tag"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_92adca9c","line":277,"updated":"2017-07-27 17:03:58.000000000","message":"Doesn\u0027t this also require the project in order to adhere to the FK constraint with the project table?","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"025c22ba95505c7e691a89b4d2a30e10d664a4cf","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    @abc.abstractmethod"},{"line_number":277,"context_line":"    def create_project_tag(self, project_tag):"},{"line_number":278,"context_line":"        \"\"\"Create the specified tag and adds it to the list in the project."},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        :param dict project_tag: The new project tag"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_459e2a08","line":277,"in_reply_to":"ff346bd7_92adca9c","updated":"2017-07-28 19:22:49.000000000","message":"Done: refer to comment in core","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":305,"context_line":""},{"line_number":306,"context_line":"        :param project_id:"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"        :returns: a dictionary of project tag names."},{"line_number":309,"context_line":"        :raises keystone.exception.ProjectNotFound: if project_id does not"},{"line_number":310,"context_line":"                                                    exist"},{"line_number":311,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_d290f24c","line":308,"updated":"2017-07-27 17:03:58.000000000","message":"a dictionary or a list?","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"025c22ba95505c7e691a89b4d2a30e10d664a4cf","unresolved":false,"context_lines":[{"line_number":305,"context_line":""},{"line_number":306,"context_line":"        :param project_id:"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"        :returns: a dictionary of project tag names."},{"line_number":309,"context_line":"        :raises keystone.exception.ProjectNotFound: if project_id does not"},{"line_number":310,"context_line":"                                                    exist"},{"line_number":311,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_a5f9564e","line":308,"in_reply_to":"ff346bd7_d290f24c","updated":"2017-07-28 19:22:49.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":313,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":314,"context_line":""},{"line_number":315,"context_line":"    @abc.abstractmethod"},{"line_number":316,"context_line":"    def delete_project_tag(self, project_id, tag_name):"},{"line_number":317,"context_line":"        \"\"\"Delete project tag with provided tag id.\"\"\""},{"line_number":318,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":319,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_929b8a64","line":316,"updated":"2017-07-27 17:03:58.000000000","message":"nit: missing documentation strings.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"025c22ba95505c7e691a89b4d2a30e10d664a4cf","unresolved":false,"context_lines":[{"line_number":313,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":314,"context_line":""},{"line_number":315,"context_line":"    @abc.abstractmethod"},{"line_number":316,"context_line":"    def delete_project_tag(self, project_id, tag_name):"},{"line_number":317,"context_line":"        \"\"\"Delete project tag with provided tag id.\"\"\""},{"line_number":318,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":319,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_65992e1e","line":316,"in_reply_to":"ff346bd7_929b8a64","updated":"2017-07-28 19:22:49.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2cf35b5391a660e15b098e5230e380fe2df2bf48","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    @abc.abstractmethod"},{"line_number":277,"context_line":"    def create_project_tag(self, project_tag):"},{"line_number":278,"context_line":"        \"\"\"Create the specified tag and adds it to the list in the project."},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        :param dict project_tag: The new project tag"}],"source_content_type":"text/x-python","patch_set":108,"id":"ff346bd7_da5d9d79","line":277,"updated":"2017-07-27 21:34:45.000000000","message":"I think this still requires the project id.","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"e0c8bb5fd1550a751d4f2bcc5f3268454e462ecd","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    @abc.abstractmethod"},{"line_number":277,"context_line":"    def create_project_tag(self, project_tag):"},{"line_number":278,"context_line":"        \"\"\"Create the specified tag and adds it to the list in the project."},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        :param dict project_tag: The new project tag"}],"source_content_type":"text/x-python","patch_set":108,"id":"ff346bd7_7d9a15b9","line":277,"in_reply_to":"ff346bd7_da5d9d79","updated":"2017-07-28 15:06:41.000000000","message":"++","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"9f96f5f0e3409bf78309cfe434ed14d4ab417252","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    @abc.abstractmethod"},{"line_number":277,"context_line":"    def create_project_tag(self, project_tag):"},{"line_number":278,"context_line":"        \"\"\"Create the specified tag and adds it to the list in the project."},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        :param dict project_tag: The new project tag"}],"source_content_type":"text/x-python","patch_set":109,"id":"df3967d1_5af4c95b","line":277,"updated":"2017-07-28 18:40:40.000000000","message":"project_id is still missing here.","commit_id":"826f7d56f4dc30d1e9cf59de185ca526f0a0e889"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"2dc8f05fd5b520489821e37a6055c2ebd95245ab","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    @abc.abstractmethod"},{"line_number":277,"context_line":"    def create_project_tag(self, project_tag):"},{"line_number":278,"context_line":"        \"\"\"Create the specified tag and adds it to the list in the project."},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        :param dict project_tag: The new project tag"}],"source_content_type":"text/x-python","patch_set":109,"id":"df3967d1_c5c8da75","line":277,"in_reply_to":"df3967d1_252c4646","updated":"2017-07-28 19:08:53.000000000","message":"No that\u0027s ok. You removed the project_id from the sql backend so there\u0027s no more inconsistency. I had missed that in this review.","commit_id":"826f7d56f4dc30d1e9cf59de185ca526f0a0e889"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"7ff17b76c7def671e535639f7c5a6e17b592de59","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    @abc.abstractmethod"},{"line_number":277,"context_line":"    def create_project_tag(self, project_tag):"},{"line_number":278,"context_line":"        \"\"\"Create the specified tag and adds it to the list in the project."},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        :param dict project_tag: The new project tag"}],"source_content_type":"text/x-python","patch_set":109,"id":"df3967d1_252c4646","line":277,"in_reply_to":"df3967d1_5af4c95b","updated":"2017-07-28 19:06:24.000000000","message":"project_tag is an object with the tag name and the project Id. This was done for consistency with the create project which also passes in an object. Is passing the project_id and a tag_name preferred?","commit_id":"826f7d56f4dc30d1e9cf59de185ca526f0a0e889"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"fbad58c06ce82b7e042a02f00490e0f9f4dddcc2","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    @abc.abstractmethod"},{"line_number":277,"context_line":"    def create_project_tag(self, project_tag):"},{"line_number":278,"context_line":"        \"\"\"Create the specified tag and adds it to the list in the project."},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        :param dict project_tag: The new project tag"}],"source_content_type":"text/x-python","patch_set":109,"id":"df3967d1_65500e34","line":277,"in_reply_to":"df3967d1_c5c8da75","updated":"2017-07-28 19:23:54.000000000","message":"It was a simple change and I made it before I saw your comment, I can easily change it back if passing an object is preferred.","commit_id":"826f7d56f4dc30d1e9cf59de185ca526f0a0e889"}],"keystone/resource/backends/sql.py":[{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"296844d6e687ae510b3fb7a05b942e0bbf17e924","unresolved":false,"context_lines":[{"line_number":242,"context_line":"                    if not self._is_hidden_ref(project_tag_ref)]"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"    def _get_project_tag(self, session, project_id, project_tag):"},{"line_number":245,"context_line":"        query \u003d session.query(ProjectTag)"},{"line_number":246,"context_line":"        project_tag_ref \u003d query.filter(ProjectTag.id \u003d\u003d project_tag[\u0027id\u0027])"},{"line_number":247,"context_line":"        return project_tag_ref"},{"line_number":248,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"5f201791_14dda46f","line":245,"range":{"start_line":245,"start_character":16,"end_line":245,"end_character":23},"updated":"2017-06-22 17:47:13.000000000","message":"isnt there a sql.session_for_read() as session required?","commit_id":"d635a21c51edb6ea3b91e889380d66a53067ea66"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"296844d6e687ae510b3fb7a05b942e0bbf17e924","unresolved":false,"context_lines":[{"line_number":248,"context_line":""},{"line_number":249,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":250,"context_line":"    def check_if_project_contains_tag(self, project_id, project_tag):"},{"line_number":251,"context_line":"        query \u003d session.query(ProjectTag)"},{"line_number":252,"context_line":"        project_tag_ref \u003d query.filter(ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":253,"context_line":"        return project_tag_ref \u003d\u003d project_tag"},{"line_number":254,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"5f201791_94d2d45b","line":251,"range":{"start_line":251,"start_character":16,"end_line":251,"end_character":23},"updated":"2017-06-22 17:47:13.000000000","message":"same here","commit_id":"d635a21c51edb6ea3b91e889380d66a53067ea66"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"f5468224f660c5183efa84fa52c3d9f8972c6ad6","unresolved":false,"context_lines":[{"line_number":242,"context_line":"                    if not self._is_hidden_ref(project_tag_ref)]"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"    def _get_project_tag(self, session, project_id, project_tag):"},{"line_number":245,"context_line":"        query \u003d session.query(ProjectTag)"},{"line_number":246,"context_line":"        project_tag_ref \u003d query.filter(ProjectTag.id \u003d\u003d project_tag[\u0027id\u0027])"},{"line_number":247,"context_line":"        return project_tag_ref"},{"line_number":248,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"5f201791_d49e0c62","line":245,"range":{"start_line":245,"start_character":16,"end_line":245,"end_character":23},"updated":"2017-06-22 17:54:32.000000000","message":"never mind on this since session is passed... pep8 just complains","commit_id":"a71bad187e2492cf57b485e99a8d913bec2b0453"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"c436aba56d4605a6ab71fd381a8227ea987b43d6","unresolved":false,"context_lines":[{"line_number":223,"context_line":""},{"line_number":224,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":225,"context_line":"    def create_project_tag(self, project_tag_id, project_tag):"},{"line_number":226,"context_line":"        new_project_tag \u003d self._encode_domain_id(project_tag)"},{"line_number":227,"context_line":"        with sql.session_for_write() as session:"},{"line_number":228,"context_line":"            project_tag_ref \u003d ProjectTag.from_dict(new_project_tag)"},{"line_number":229,"context_line":"            session.add(project_tag_ref)"}],"source_content_type":"text/x-python","patch_set":14,"id":"5f201791_d4596c5a","line":226,"range":{"start_line":226,"start_character":31,"end_line":226,"end_character":48},"updated":"2017-06-22 18:20:16.000000000","message":"and I think we need a new private method for this instead of using the same method used by Project, since domain_id is not going to be in the ref. Or might not even need this at all","commit_id":"f34dcf368951b44f5861a6d9268aa59067bfc095"},{"author":{"_account_id":22604,"name":"Samuel Pilla","email":"sp516w@att.com","username":"samuel.pilla"},"change_message_id":"34c1421bbf9bb92da13af1b9c8e184a6cb9430ab","unresolved":false,"context_lines":[{"line_number":223,"context_line":""},{"line_number":224,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":225,"context_line":"    def create_project_tag(self, project_tag_id, project_tag):"},{"line_number":226,"context_line":"        new_project_tag \u003d self._encode_domain_id(project_tag)"},{"line_number":227,"context_line":"        with sql.session_for_write() as session:"},{"line_number":228,"context_line":"            project_tag_ref \u003d ProjectTag.from_dict(new_project_tag)"},{"line_number":229,"context_line":"            session.add(project_tag_ref)"}],"source_content_type":"text/x-python","patch_set":14,"id":"5f201791_a0f8e648","line":226,"range":{"start_line":226,"start_character":31,"end_line":226,"end_character":48},"in_reply_to":"5f201791_d4596c5a","updated":"2017-06-22 20:30:37.000000000","message":"Done","commit_id":"f34dcf368951b44f5861a6d9268aa59067bfc095"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"c436aba56d4605a6ab71fd381a8227ea987b43d6","unresolved":false,"context_lines":[{"line_number":232,"context_line":"    @driver_hints.truncated"},{"line_number":233,"context_line":"    def list_project_tags(self, project_id, hints):"},{"line_number":234,"context_line":"        for f in hints.filters:"},{"line_number":235,"context_line":"            if (f[\u0027name\u0027] \u003d\u003d \u0027domain_id\u0027 and f[\u0027value\u0027] is None):"},{"line_number":236,"context_line":"                f[\u0027value\u0027] \u003d base.NULL_DOMAIN_ID"},{"line_number":237,"context_line":"        with sql.session_for_read() as session:"},{"line_number":238,"context_line":"            project_tag_refs \u003d sql.filter_limit_query("}],"source_content_type":"text/x-python","patch_set":14,"id":"5f201791_f408e82d","line":235,"range":{"start_line":235,"start_character":16,"end_line":235,"end_character":63},"updated":"2017-06-22 18:20:16.000000000","message":"this also.","commit_id":"f34dcf368951b44f5861a6d9268aa59067bfc095"},{"author":{"_account_id":22604,"name":"Samuel Pilla","email":"sp516w@att.com","username":"samuel.pilla"},"change_message_id":"34c1421bbf9bb92da13af1b9c8e184a6cb9430ab","unresolved":false,"context_lines":[{"line_number":232,"context_line":"    @driver_hints.truncated"},{"line_number":233,"context_line":"    def list_project_tags(self, project_id, hints):"},{"line_number":234,"context_line":"        for f in hints.filters:"},{"line_number":235,"context_line":"            if (f[\u0027name\u0027] \u003d\u003d \u0027domain_id\u0027 and f[\u0027value\u0027] is None):"},{"line_number":236,"context_line":"                f[\u0027value\u0027] \u003d base.NULL_DOMAIN_ID"},{"line_number":237,"context_line":"        with sql.session_for_read() as session:"},{"line_number":238,"context_line":"            project_tag_refs \u003d sql.filter_limit_query("}],"source_content_type":"text/x-python","patch_set":14,"id":"5f201791_8095eae6","line":235,"range":{"start_line":235,"start_character":16,"end_line":235,"end_character":63},"in_reply_to":"5f201791_f408e82d","updated":"2017-06-22 20:30:37.000000000","message":"Done","commit_id":"f34dcf368951b44f5861a6d9268aa59067bfc095"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"c436aba56d4605a6ab71fd381a8227ea987b43d6","unresolved":false,"context_lines":[{"line_number":248,"context_line":""},{"line_number":249,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":250,"context_line":"    def check_if_project_contains_tag(self, project_id, project_tag):"},{"line_number":251,"context_line":"        query \u003d session.query(ProjectTag)"},{"line_number":252,"context_line":"        project_tag_ref \u003d query.filter(ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":253,"context_line":"        return project_tag_ref \u003d\u003d project_tag"},{"line_number":254,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5f201791_bf35a9dc","line":251,"range":{"start_line":251,"start_character":8,"end_line":251,"end_character":13},"updated":"2017-06-22 18:20:16.000000000","message":"with sql.session_for_read() as session:","commit_id":"f34dcf368951b44f5861a6d9268aa59067bfc095"},{"author":{"_account_id":22604,"name":"Samuel Pilla","email":"sp516w@att.com","username":"samuel.pilla"},"change_message_id":"34c1421bbf9bb92da13af1b9c8e184a6cb9430ab","unresolved":false,"context_lines":[{"line_number":248,"context_line":""},{"line_number":249,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":250,"context_line":"    def check_if_project_contains_tag(self, project_id, project_tag):"},{"line_number":251,"context_line":"        query \u003d session.query(ProjectTag)"},{"line_number":252,"context_line":"        project_tag_ref \u003d query.filter(ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":253,"context_line":"        return project_tag_ref \u003d\u003d project_tag"},{"line_number":254,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5f201791_409fd202","line":251,"range":{"start_line":251,"start_character":8,"end_line":251,"end_character":13},"in_reply_to":"5f201791_bf35a9dc","updated":"2017-06-22 20:30:37.000000000","message":"Done","commit_id":"f34dcf368951b44f5861a6d9268aa59067bfc095"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"c436aba56d4605a6ab71fd381a8227ea987b43d6","unresolved":false,"context_lines":[{"line_number":254,"context_line":""},{"line_number":255,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":256,"context_line":"    def update_project_tag(self, project_id, project_tag):"},{"line_number":257,"context_line":"        update_project_tag \u003d self._encode_domain_id(project_tag)"},{"line_number":258,"context_line":"        with sql.session_for_write() as session:"},{"line_number":259,"context_line":"            project_tag_ref \u003d self._get_project_tag(session, project_tag)"},{"line_number":260,"context_line":"            old_project_tag_dict \u003d project_tag_ref.to_dict()"}],"source_content_type":"text/x-python","patch_set":14,"id":"5f201791_ff120158","line":257,"range":{"start_line":257,"start_character":34,"end_line":257,"end_character":51},"updated":"2017-06-22 18:20:16.000000000","message":"ditto","commit_id":"f34dcf368951b44f5861a6d9268aa59067bfc095"},{"author":{"_account_id":22604,"name":"Samuel Pilla","email":"sp516w@att.com","username":"samuel.pilla"},"change_message_id":"34c1421bbf9bb92da13af1b9c8e184a6cb9430ab","unresolved":false,"context_lines":[{"line_number":254,"context_line":""},{"line_number":255,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":256,"context_line":"    def update_project_tag(self, project_id, project_tag):"},{"line_number":257,"context_line":"        update_project_tag \u003d self._encode_domain_id(project_tag)"},{"line_number":258,"context_line":"        with sql.session_for_write() as session:"},{"line_number":259,"context_line":"            project_tag_ref \u003d self._get_project_tag(session, project_tag)"},{"line_number":260,"context_line":"            old_project_tag_dict \u003d project_tag_ref.to_dict()"}],"source_content_type":"text/x-python","patch_set":14,"id":"5f201791_20a2964c","line":257,"range":{"start_line":257,"start_character":34,"end_line":257,"end_character":51},"in_reply_to":"5f201791_ff120158","updated":"2017-06-22 20:30:37.000000000","message":"Done","commit_id":"f34dcf368951b44f5861a6d9268aa59067bfc095"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"c436aba56d4605a6ab71fd381a8227ea987b43d6","unresolved":false,"context_lines":[{"line_number":281,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":282,"context_line":"    def remove_all_project_tags(self, project_id):"},{"line_number":283,"context_line":"        with sql.session_for_write() as session:"},{"line_number":284,"context_line":"            project_tag_refs \u003d self._get_projects_tags(session, project_id)"},{"line_number":285,"context_line":"            for project_tag_ref in project_tag_refs:"},{"line_number":286,"context_line":"                session.delete(project_tag_ref)"},{"line_number":287,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5f201791_5f9e95b8","line":284,"range":{"start_line":284,"start_character":36,"end_line":284,"end_character":54},"updated":"2017-06-22 18:20:16.000000000","message":"i think this would get 3 arguments expected, got 2","commit_id":"f34dcf368951b44f5861a6d9268aa59067bfc095"},{"author":{"_account_id":22604,"name":"Samuel Pilla","email":"sp516w@att.com","username":"samuel.pilla"},"change_message_id":"34c1421bbf9bb92da13af1b9c8e184a6cb9430ab","unresolved":false,"context_lines":[{"line_number":281,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":282,"context_line":"    def remove_all_project_tags(self, project_id):"},{"line_number":283,"context_line":"        with sql.session_for_write() as session:"},{"line_number":284,"context_line":"            project_tag_refs \u003d self._get_projects_tags(session, project_id)"},{"line_number":285,"context_line":"            for project_tag_ref in project_tag_refs:"},{"line_number":286,"context_line":"                session.delete(project_tag_ref)"},{"line_number":287,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5f201791_0089dac8","line":284,"range":{"start_line":284,"start_character":36,"end_line":284,"end_character":54},"in_reply_to":"5f201791_5f9e95b8","updated":"2017-06-22 20:30:37.000000000","message":"Done","commit_id":"f34dcf368951b44f5861a6d9268aa59067bfc095"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"c436aba56d4605a6ab71fd381a8227ea987b43d6","unresolved":false,"context_lines":[{"line_number":324,"context_line":"    def to_dict(self, include_extra_dict\u003dFalse):"},{"line_number":325,"context_line":"        d \u003d super(ProjectTag, self).to_dict("},{"line_number":326,"context_line":"            include_extra_dict\u003dinclude_extra_dict)"},{"line_number":327,"context_line":"        # if d[\u0027domain_id\u0027] \u003d\u003d base.NULL_DOMAIN_ID:"},{"line_number":328,"context_line":"        #     d[\u0027domain_id\u0027] \u003d None"},{"line_number":329,"context_line":"        return d"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"    __tablename__ \u003d \u0027project_tag\u0027"}],"source_content_type":"text/x-python","patch_set":14,"id":"5f201791_d4abac1a","line":328,"range":{"start_line":327,"start_character":0,"end_line":328,"end_character":35},"updated":"2017-06-22 18:20:16.000000000","message":"should delete this at some point","commit_id":"f34dcf368951b44f5861a6d9268aa59067bfc095"},{"author":{"_account_id":22604,"name":"Samuel Pilla","email":"sp516w@att.com","username":"samuel.pilla"},"change_message_id":"34c1421bbf9bb92da13af1b9c8e184a6cb9430ab","unresolved":false,"context_lines":[{"line_number":324,"context_line":"    def to_dict(self, include_extra_dict\u003dFalse):"},{"line_number":325,"context_line":"        d \u003d super(ProjectTag, self).to_dict("},{"line_number":326,"context_line":"            include_extra_dict\u003dinclude_extra_dict)"},{"line_number":327,"context_line":"        # if d[\u0027domain_id\u0027] \u003d\u003d base.NULL_DOMAIN_ID:"},{"line_number":328,"context_line":"        #     d[\u0027domain_id\u0027] \u003d None"},{"line_number":329,"context_line":"        return d"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"    __tablename__ \u003d \u0027project_tag\u0027"}],"source_content_type":"text/x-python","patch_set":14,"id":"5f201791_e0837ea8","line":328,"range":{"start_line":327,"start_character":0,"end_line":328,"end_character":35},"in_reply_to":"5f201791_d4abac1a","updated":"2017-06-22 20:30:37.000000000","message":"Done","commit_id":"f34dcf368951b44f5861a6d9268aa59067bfc095"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"77c1b0ef717f7d7b640c04b03732692493bd2f0e","unresolved":false,"context_lines":[{"line_number":245,"context_line":""},{"line_number":246,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":247,"context_line":"    def check_if_project_contains_tag(self, project_id, project_tag):"},{"line_number":248,"context_line":"        with sql.session_for_write() as session:"},{"line_number":249,"context_line":"            query \u003d session.query(ProjectTag)"},{"line_number":250,"context_line":"            project_tag_ref \u003d query.filter(ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":251,"context_line":"            return project_tag_ref \u003d\u003d project_tag"}],"source_content_type":"text/x-python","patch_set":16,"id":"5f201791_b2bfd2a8","line":248,"range":{"start_line":248,"start_character":29,"end_line":248,"end_character":34},"updated":"2017-06-26 16:24:30.000000000","message":"Does this need to be a write?","commit_id":"560578d2c2e0dcfb6448c73dc2e0363abdd001d7"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"49bb9d77715defa0995cb9b43b98ee1e840f3730","unresolved":false,"context_lines":[{"line_number":245,"context_line":""},{"line_number":246,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":247,"context_line":"    def check_if_project_contains_tag(self, project_id, project_tag):"},{"line_number":248,"context_line":"        with sql.session_for_write() as session:"},{"line_number":249,"context_line":"            query \u003d session.query(ProjectTag)"},{"line_number":250,"context_line":"            project_tag_ref \u003d query.filter(ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":251,"context_line":"            return project_tag_ref \u003d\u003d project_tag"}],"source_content_type":"text/x-python","patch_set":16,"id":"5f201791_a0fcef3d","line":248,"range":{"start_line":248,"start_character":29,"end_line":248,"end_character":34},"in_reply_to":"5f201791_b2bfd2a8","updated":"2017-06-27 17:32:57.000000000","message":"Done","commit_id":"560578d2c2e0dcfb6448c73dc2e0363abdd001d7"},{"author":{"_account_id":20466,"name":"Tin Lam","email":"tin@lam.wtf","username":"tinlam"},"change_message_id":"7c47c092c69270eb9c81e79f28af5cba83893969","unresolved":false,"context_lines":[{"line_number":249,"context_line":"            with sql.session_for_read() as session:"},{"line_number":250,"context_line":"                query \u003d self._get_project_tag(session, project_tag_id)"},{"line_number":251,"context_line":"                query \u003d query.filter(ProjectTag.id \u003d\u003d project_tag_id)"},{"line_number":252,"context_line":"                if query:"},{"line_number":253,"context_line":"                    return True"},{"line_number":254,"context_line":"                else:"},{"line_number":255,"context_line":"                    return False"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":258,"context_line":"    def update_project_tag(self, project_id, project_tag_id, project_tags):"}],"source_content_type":"text/x-python","patch_set":18,"id":"5f201791_bbac22ed","line":255,"range":{"start_line":252,"start_character":0,"end_line":255,"end_character":32},"updated":"2017-06-27 17:46:27.000000000","message":"This is kind of strange.  This function returns a boolean here, but returns an empty array on Line 247.","commit_id":"41c7bf14798740aae46c3a9b1649aeb7777ea785"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"f0d74e8beaf22eabea82d3532de6689db01da912","unresolved":false,"context_lines":[{"line_number":249,"context_line":"            with sql.session_for_read() as session:"},{"line_number":250,"context_line":"                query \u003d self._get_project_tag(session, project_tag_id)"},{"line_number":251,"context_line":"                query \u003d query.filter(ProjectTag.id \u003d\u003d project_tag_id)"},{"line_number":252,"context_line":"                if query:"},{"line_number":253,"context_line":"                    return True"},{"line_number":254,"context_line":"                else:"},{"line_number":255,"context_line":"                    return False"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":258,"context_line":"    def update_project_tag(self, project_id, project_tag_id, project_tags):"}],"source_content_type":"text/x-python","patch_set":18,"id":"5f201791_873c5f2f","line":255,"range":{"start_line":252,"start_character":0,"end_line":255,"end_character":32},"in_reply_to":"5f201791_bbac22ed","updated":"2017-06-27 23:42:22.000000000","message":"Haven\u0027t finished fixing this but working on it.","commit_id":"41c7bf14798740aae46c3a9b1649aeb7777ea785"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"4d74e9817b9525c8c518f93e80cdbfb45553343f","unresolved":false,"context_lines":[{"line_number":357,"context_line":"    __table_args__ \u003d (sql.UniqueConstraint(\u0027domain_id\u0027, \u0027name\u0027),)"},{"line_number":358,"context_line":""},{"line_number":359,"context_line":""},{"line_number":360,"context_line":"class ProjectTag(sql.ModelBase, sql.ModelDictMixinWithExtras):"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"    def to_dict(self, include_extra_dict\u003dFalse):"},{"line_number":363,"context_line":"        d \u003d super(ProjectTag, self).to_dict("}],"source_content_type":"text/x-python","patch_set":19,"id":"5f201791_793c2d92","line":360,"range":{"start_line":360,"start_character":36,"end_line":360,"end_character":60},"updated":"2017-06-28 16:10:52.000000000","message":"replace with ModelDictMixin","commit_id":"e62c4f659bc7e3b38de326d53b0158a4a9700b3e"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"4d74e9817b9525c8c518f93e80cdbfb45553343f","unresolved":false,"context_lines":[{"line_number":373,"context_line":"        sql.String(64), sql.ForeignKey(\u0027project.id\u0027, ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":374,"context_line":"        nullable\u003dFalse)"},{"line_number":375,"context_line":"    name \u003d sql.Column(sql.String(80), nullable\u003dFalse)"},{"line_number":376,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"},{"line_number":377,"context_line":"    __table_args__ \u003d (sql.UniqueConstraint(\u0027project_id\u0027, \u0027name\u0027),)"}],"source_content_type":"text/x-python","patch_set":19,"id":"5f201791_39423510","line":376,"range":{"start_line":376,"start_character":4,"end_line":376,"end_character":9},"updated":"2017-06-28 16:10:52.000000000","message":"Delete","commit_id":"e62c4f659bc7e3b38de326d53b0158a4a9700b3e"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"3dfd864f36071b01075c91e8494c24a88f8703e0","unresolved":false,"context_lines":[{"line_number":279,"context_line":"            return [project_tag_ref.to_dict()"},{"line_number":280,"context_line":"                    for project_tag_ref in project_tag_refs]"},{"line_number":281,"context_line":""},{"line_number":282,"context_line":"    def check_if_project_contains_tag(self, project_id, project_tag_id):"},{"line_number":283,"context_line":"        if not project_id:"},{"line_number":284,"context_line":"            return []"},{"line_number":285,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":25,"id":"3f1d235d_3b63021d","line":282,"range":{"start_line":282,"start_character":8,"end_line":282,"end_character":37},"updated":"2017-06-30 17:56:26.000000000","message":"fix. this doesnt actually filter with project_id","commit_id":"89f2063bd5e86457df783ffa06478bc4d1de2e72"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"3dfd864f36071b01075c91e8494c24a88f8703e0","unresolved":false,"context_lines":[{"line_number":292,"context_line":"                    return []"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":295,"context_line":"    def update_project_tag(self, project_id, project_tag_id, project_tags):"},{"line_number":296,"context_line":"        with sql.session_for_write() as session:"},{"line_number":297,"context_line":"            new_project_tags \u003d []"},{"line_number":298,"context_line":"            for project_tag in project_tags:"}],"source_content_type":"text/x-python","patch_set":25,"id":"3f1d235d_bb76f2d7","line":295,"range":{"start_line":295,"start_character":8,"end_line":295,"end_character":26},"updated":"2017-06-30 17:56:26.000000000","message":"WIP","commit_id":"89f2063bd5e86457df783ffa06478bc4d1de2e72"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"3dfd864f36071b01075c91e8494c24a88f8703e0","unresolved":false,"context_lines":[{"line_number":320,"context_line":"    def remove_all_project_tags(self, project_id):"},{"line_number":321,"context_line":"        with sql.session_for_write() as session:"},{"line_number":322,"context_line":"            query \u003d session.query(ProjectTag)"},{"line_number":323,"context_line":"            project_tag_refs \u003d sql.filter_limit_query("},{"line_number":324,"context_line":"                ProjectTag.project_id \u003d\u003d project_id, query)"},{"line_number":325,"context_line":"            for project_tag_ref in project_tag_refs:"},{"line_number":326,"context_line":"                session.delete(project_tag_ref)"}],"source_content_type":"text/x-python","patch_set":25,"id":"3f1d235d_96cc2b8a","line":323,"range":{"start_line":323,"start_character":35,"end_line":323,"end_character":53},"updated":"2017-06-30 17:56:26.000000000","message":"this will just return query since hints is None","commit_id":"89f2063bd5e86457df783ffa06478bc4d1de2e72"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"5b9d78df08fb9b1e1372b384d657061922b7ee58","unresolved":false,"context_lines":[{"line_number":100,"context_line":"        with sql.session_for_read() as session:"},{"line_number":101,"context_line":"            query \u003d session.query(Project)"},{"line_number":102,"context_line":"            project_refs \u003d sql.filter_limit_query(Project, query, hints)"},{"line_number":103,"context_line":"            refs \u003d [project_ref.to_dict() for project_ref in project_refs"},{"line_number":104,"context_line":"                    if not self._is_hidden_ref(project_ref)]"},{"line_number":105,"context_line":"            for ref in refs:"},{"line_number":106,"context_line":"                ref[\u0027tags\u0027] \u003d self._list_project_tags_by_name(ref[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":35,"id":"3f1d235d_340c653a","line":103,"range":{"start_line":103,"start_character":12,"end_line":103,"end_character":16},"updated":"2017-07-07 17:41:50.000000000","message":"i think i\u0027ll move this out to the controller to satisfy most of the pre-written unit tests that have hashing. Instead of going into these tests and doing del ref[\u0027tags\u0027]","commit_id":"647825a34dae527c8ec6ad8de89d8a2318633ce5"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"f9148dab3b9fe1ea11e7b5b808ac2e89c2145336","unresolved":false,"context_lines":[{"line_number":470,"context_line":""},{"line_number":471,"context_line":"    __tablename__ \u003d \u0027project_tag\u0027"},{"line_number":472,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027project_id\u0027, \u0027name\u0027]"},{"line_number":473,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":474,"context_line":"    project_id \u003d sql.Column("},{"line_number":475,"context_line":"        sql.String(64), sql.ForeignKey(\u0027project.id\u0027, ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":476,"context_line":"        nullable\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":59,"id":"1f1a1f67_307bb57b","line":473,"range":{"start_line":473,"start_character":4,"end_line":473,"end_character":53},"updated":"2017-07-18 00:44:21.000000000","message":"Please do not use strings as Primary Keys. The PK should be an autoinc int. If you need a resource externally representable, you may have a tag_id that is a UUID.","commit_id":"e98f6a349de74e0177e89881e17efe4a53ddecc7"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"19f69f77c3e250420f9efefa5a2daba1dda17f34","unresolved":false,"context_lines":[{"line_number":470,"context_line":""},{"line_number":471,"context_line":"    __tablename__ \u003d \u0027project_tag\u0027"},{"line_number":472,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027project_id\u0027, \u0027name\u0027]"},{"line_number":473,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":474,"context_line":"    project_id \u003d sql.Column("},{"line_number":475,"context_line":"        sql.String(64), sql.ForeignKey(\u0027project.id\u0027, ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":476,"context_line":"        nullable\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":59,"id":"1f1a1f67_93161349","line":473,"range":{"start_line":473,"start_character":4,"end_line":473,"end_character":53},"in_reply_to":"1f1a1f67_307bb57b","updated":"2017-07-18 01:30:52.000000000","message":"But then wouldn\u0027t there be confusion between id and tag_id? That sounds like a bug waiting to happen.\n\nIn truth this resource probably shouldn\u0027t ever be queried or filtered by the id from a user perspective since tags aren\u0027t shared across multiple projects, and most queries will be by name.\n\nBut... If there is a use case to have the id usable, what\u0027s wrong with UUID as PK? All other Keystone resources seem to already do that, makes sense to keep that convention the same.","commit_id":"e98f6a349de74e0177e89881e17efe4a53ddecc7"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"4286d10cdab0062a4442e3b73e3df82e0a069468","unresolved":false,"context_lines":[{"line_number":470,"context_line":""},{"line_number":471,"context_line":"    __tablename__ \u003d \u0027project_tag\u0027"},{"line_number":472,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027project_id\u0027, \u0027name\u0027]"},{"line_number":473,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":474,"context_line":"    project_id \u003d sql.Column("},{"line_number":475,"context_line":"        sql.String(64), sql.ForeignKey(\u0027project.id\u0027, ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":476,"context_line":"        nullable\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":59,"id":"1f1a1f67_7ef2ca71","line":473,"range":{"start_line":473,"start_character":4,"end_line":473,"end_character":53},"in_reply_to":"1f1a1f67_6386e0bb","updated":"2017-07-20 00:49:56.000000000","message":"Ah cool! Good to know. :)\n\nAt any rate, this model doesn\u0027t really need direct UUID reference anyway since query by id here from a user perspective isn\u0027t useful.","commit_id":"e98f6a349de74e0177e89881e17efe4a53ddecc7"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"1a518cf7a5d72c62a50acaba738088837f306e80","unresolved":false,"context_lines":[{"line_number":470,"context_line":""},{"line_number":471,"context_line":"    __tablename__ \u003d \u0027project_tag\u0027"},{"line_number":472,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027project_id\u0027, \u0027name\u0027]"},{"line_number":473,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":474,"context_line":"    project_id \u003d sql.Column("},{"line_number":475,"context_line":"        sql.String(64), sql.ForeignKey(\u0027project.id\u0027, ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":476,"context_line":"        nullable\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":59,"id":"1f1a1f67_6386e0bb","line":473,"range":{"start_line":473,"start_character":4,"end_line":473,"end_character":53},"in_reply_to":"1f1a1f67_93161349","updated":"2017-07-19 00:11:45.000000000","message":"We have been migrating away from the PK being uuids where at all possible. This is due to how the indexing and references work for FKs and the like internal to the application.\n\ntl;dr the convention is mostly \"use auto_inc int\" for PK for new schema additions and migrate to auto_inc int where possible. Some thing are not really possible to migrate easily and those have been left alone.","commit_id":"e98f6a349de74e0177e89881e17efe4a53ddecc7"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"3e9fbb15e0755a60d6bd7004dcafa774e07c73be","unresolved":false,"context_lines":[{"line_number":334,"context_line":"                raise exception.ProjectTagNotFound(project_tag_id\u003dtag_name)"},{"line_number":335,"context_line":"            return project_tag_ref.to_dict()"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"    def get_all_project_tags_with_name(self, tag_name):"},{"line_number":338,"context_line":"        with sql.session_for_read() as session:"},{"line_number":339,"context_line":"            query \u003d session.query(ProjectTag)"},{"line_number":340,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":65,"id":"1f1a1f67_cac36037","line":337,"range":{"start_line":337,"start_character":8,"end_line":337,"end_character":38},"updated":"2017-07-19 20:55:39.000000000","message":"could be removed. TBD","commit_id":"df8fac6bca06f51abfaee4f97f332cdc2749c5a9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"d1527cfe260778ac6e6b0032eaa376bd5bcc8b50","unresolved":false,"context_lines":[{"line_number":425,"context_line":"    project_id \u003d sql.Column("},{"line_number":426,"context_line":"        sql.String(64), sql.ForeignKey(\u0027project.id\u0027, ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":427,"context_line":"        nullable\u003dFalse)"},{"line_number":428,"context_line":"    name \u003d sql.Column(sql.String(60), nullable\u003dFalse)"},{"line_number":429,"context_line":"    __table_args__ \u003d (sql.UniqueConstraint(\u0027project_id\u0027, \u0027name\u0027),)"}],"source_content_type":"text/x-python","patch_set":73,"id":"ff346bd7_95efa6af","line":428,"range":{"start_line":428,"start_character":4,"end_line":428,"end_character":8},"updated":"2017-07-21 18:16:38.000000000","message":"this should now have collation since that was added","commit_id":"e2f9f47554cd16d95927116676eb15f91bd7d4e1"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"dd94f48a5e812d9109530e263f4b3490491a648b","unresolved":false,"context_lines":[{"line_number":11,"context_line":"# under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"from oslo_log import log"},{"line_number":14,"context_line":"from six import text_type"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from keystone.common import driver_hints"},{"line_number":17,"context_line":"from keystone.common import sql"}],"source_content_type":"text/x-python","patch_set":100,"id":"ff346bd7_73716c0c","line":14,"range":{"start_line":14,"start_character":0,"end_line":14,"end_character":25},"updated":"2017-07-26 21:26:55.000000000","message":"Dont need this import anymore?","commit_id":"c4c9378e5190d857df88ba5f629854de4d02eb5a"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"6cb1662e2249a083a4071a1079410ec5489ceb9b","unresolved":false,"context_lines":[{"line_number":11,"context_line":"# under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"from oslo_log import log"},{"line_number":14,"context_line":"from six import text_type"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from keystone.common import driver_hints"},{"line_number":17,"context_line":"from keystone.common import sql"}],"source_content_type":"text/x-python","patch_set":100,"id":"ff346bd7_56ebf611","line":14,"range":{"start_line":14,"start_character":0,"end_line":14,"end_character":25},"in_reply_to":"ff346bd7_73716c0c","updated":"2017-07-26 21:30:57.000000000","message":"no this gets used below, as in _encode_list_to_unicode","commit_id":"c4c9378e5190d857df88ba5f629854de4d02eb5a"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        else:"},{"line_number":36,"context_line":"            return ref"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def _encode_list_to_unicode(self, values):"},{"line_number":39,"context_line":"        new_values \u003d []"},{"line_number":40,"context_line":"        for val in values:"},{"line_number":41,"context_line":"            new_values.append(text_type(val))"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_d2cd9231","line":38,"updated":"2017-07-27 17:03:58.000000000","message":"This feels like it\u0027s something that should be done in the manager or controller since it\u0027s dealing with input. We typically try and refrain from putting this login in drivers so that it can be reused across backend implementations.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":171,"context_line":"                project \u003d parent_project"},{"line_number":172,"context_line":"            return parents"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"    def list_projects_with_tags(self, tag_names):"},{"line_number":175,"context_line":"        with sql.session_for_read() as session:"},{"line_number":176,"context_line":"            tag_names \u003d self._encode_list_to_unicode(tag_names)"},{"line_number":177,"context_line":"            # filter with names to get the project ids of related"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_724026a6","line":174,"updated":"2017-07-27 17:03:58.000000000","message":"No interface definition for these?","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"b915e834347d433809026146863e76be18275908","unresolved":false,"context_lines":[{"line_number":171,"context_line":"                project \u003d parent_project"},{"line_number":172,"context_line":"            return parents"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"    def list_projects_with_tags(self, tag_names):"},{"line_number":175,"context_line":"        with sql.session_for_read() as session:"},{"line_number":176,"context_line":"            tag_names \u003d self._encode_list_to_unicode(tag_names)"},{"line_number":177,"context_line":"            # filter with names to get the project ids of related"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_205e74e6","line":174,"in_reply_to":"ff346bd7_724026a6","updated":"2017-07-28 19:52:51.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":325,"context_line":"            return project_tag_ref.to_dict()"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":328,"context_line":"    def create_project_tag(self, project_tag):"},{"line_number":329,"context_line":"        with sql.session_for_write() as session:"},{"line_number":330,"context_line":"            project_tag[\u0027name\u0027] \u003d text_type(project_tag[\u0027name\u0027])"},{"line_number":331,"context_line":"            project_tag_ref \u003d ProjectTag.from_dict(project_tag)"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_b2e44ee1","line":328,"updated":"2017-07-27 17:03:58.000000000","message":"Don\u0027t we need the project id here?","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"025c22ba95505c7e691a89b4d2a30e10d664a4cf","unresolved":false,"context_lines":[{"line_number":325,"context_line":"            return project_tag_ref.to_dict()"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":328,"context_line":"    def create_project_tag(self, project_tag):"},{"line_number":329,"context_line":"        with sql.session_for_write() as session:"},{"line_number":330,"context_line":"            project_tag[\u0027name\u0027] \u003d text_type(project_tag[\u0027name\u0027])"},{"line_number":331,"context_line":"            project_tag_ref \u003d ProjectTag.from_dict(project_tag)"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_25d566ba","line":328,"in_reply_to":"ff346bd7_b2e44ee1","updated":"2017-07-28 19:22:49.000000000","message":"we actually didnt since it was a dict containing project_id and tag_name in it (we did this for consistency) but we changed it to project_id and tag_name for clarity.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":338,"context_line":"            project_tag_refs \u003d query.filter("},{"line_number":339,"context_line":"                ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":340,"context_line":"            return [project_tag_ref.to_dict()[\u0027name\u0027]"},{"line_number":341,"context_line":"                    for project_tag_ref in project_tag_refs]"},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":344,"context_line":"    def delete_project_tag(self, project_id, tag_name):"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_32f17e96","line":341,"updated":"2017-07-27 17:03:58.000000000","message":"This bit is inconsistent with the documentation string in the abstract base class.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"025c22ba95505c7e691a89b4d2a30e10d664a4cf","unresolved":false,"context_lines":[{"line_number":338,"context_line":"            project_tag_refs \u003d query.filter("},{"line_number":339,"context_line":"                ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":340,"context_line":"            return [project_tag_ref.to_dict()[\u0027name\u0027]"},{"line_number":341,"context_line":"                    for project_tag_ref in project_tag_refs]"},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"    @sql.handle_conflicts(conflict_type\u003d\u0027project_tag\u0027)"},{"line_number":344,"context_line":"    def delete_project_tag(self, project_id, tag_name):"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_e5d63ec4","line":341,"in_reply_to":"ff346bd7_32f17e96","updated":"2017-07-28 19:22:49.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"e0c8bb5fd1550a751d4f2bcc5f3268454e462ecd","unresolved":false,"context_lines":[{"line_number":185,"context_line":"                ProjectTag.project_id).group_by(ProjectTag.project_id)"},{"line_number":186,"context_line":"            for q in query:"},{"line_number":187,"context_line":"                    relevant_project_ids.append(q[\u0027project_id\u0027])"},{"line_number":188,"context_line":"            # With a unique list, query the ProjectTags table"},{"line_number":189,"context_line":"            # and obtain a count of how many unique tag names exist"},{"line_number":190,"context_line":"            # with that unique project_id and if the count is the"},{"line_number":191,"context_line":"            # same as length of tag_names, return those project_ids"},{"line_number":192,"context_line":"            # Then, call list project by ids."},{"line_number":193,"context_line":"            for project_id in relevant_project_ids:"},{"line_number":194,"context_line":"                query \u003d session.query(ProjectTag)"},{"line_number":195,"context_line":"                query \u003d query.filter(ProjectTag.project_id \u003d\u003d project_id)"}],"source_content_type":"text/x-python","patch_set":108,"id":"ff346bd7_9d9a595f","line":192,"range":{"start_line":188,"start_character":14,"end_line":192,"end_character":45},"updated":"2017-07-28 15:06:41.000000000","message":"This comment doesn\u0027t match the code below. You\u0027re actually comparing the lists of tags.","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"f975c319a72e3575027b6479fd95ddf72da0c43f","unresolved":false,"context_lines":[{"line_number":185,"context_line":"                ProjectTag.project_id).group_by(ProjectTag.project_id)"},{"line_number":186,"context_line":"            for q in query:"},{"line_number":187,"context_line":"                    relevant_project_ids.append(q[\u0027project_id\u0027])"},{"line_number":188,"context_line":"            # With a unique list, query the ProjectTags table"},{"line_number":189,"context_line":"            # and obtain a count of how many unique tag names exist"},{"line_number":190,"context_line":"            # with that unique project_id and if the count is the"},{"line_number":191,"context_line":"            # same as length of tag_names, return those project_ids"},{"line_number":192,"context_line":"            # Then, call list project by ids."},{"line_number":193,"context_line":"            for project_id in relevant_project_ids:"},{"line_number":194,"context_line":"                query \u003d session.query(ProjectTag)"},{"line_number":195,"context_line":"                query \u003d query.filter(ProjectTag.project_id \u003d\u003d project_id)"}],"source_content_type":"text/x-python","patch_set":108,"id":"ff346bd7_4349abb4","line":192,"range":{"start_line":188,"start_character":14,"end_line":192,"end_character":45},"in_reply_to":"ff346bd7_9d9a595f","updated":"2017-07-28 17:41:06.000000000","message":"Done","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"e0c8bb5fd1550a751d4f2bcc5f3268454e462ecd","unresolved":false,"context_lines":[{"line_number":193,"context_line":"            for project_id in relevant_project_ids:"},{"line_number":194,"context_line":"                query \u003d session.query(ProjectTag)"},{"line_number":195,"context_line":"                query \u003d query.filter(ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":196,"context_line":"                names \u003d query.distinct(ProjectTag.name).all()"},{"line_number":197,"context_line":"                result \u003d map(lambda x: x[\u0027name\u0027], names)"},{"line_number":198,"context_line":"                if sorted(result) \u003d\u003d sorted(tag_names):"},{"line_number":199,"context_line":"                    filtered_project_ids.append(project_id)"}],"source_content_type":"text/x-python","patch_set":108,"id":"ff346bd7_9db379e9","line":196,"range":{"start_line":196,"start_character":16,"end_line":196,"end_character":61},"updated":"2017-07-28 15:06:41.000000000","message":"Is it necessary to do distinct? You\u0027ve already placed a uniqueness contraint on (project_id, name)","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"f975c319a72e3575027b6479fd95ddf72da0c43f","unresolved":false,"context_lines":[{"line_number":193,"context_line":"            for project_id in relevant_project_ids:"},{"line_number":194,"context_line":"                query \u003d session.query(ProjectTag)"},{"line_number":195,"context_line":"                query \u003d query.filter(ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":196,"context_line":"                names \u003d query.distinct(ProjectTag.name).all()"},{"line_number":197,"context_line":"                result \u003d map(lambda x: x[\u0027name\u0027], names)"},{"line_number":198,"context_line":"                if sorted(result) \u003d\u003d sorted(tag_names):"},{"line_number":199,"context_line":"                    filtered_project_ids.append(project_id)"}],"source_content_type":"text/x-python","patch_set":108,"id":"ff346bd7_c3d23bd1","line":196,"range":{"start_line":196,"start_character":16,"end_line":196,"end_character":61},"in_reply_to":"ff346bd7_9db379e9","updated":"2017-07-28 17:41:06.000000000","message":"can be deleted","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"e0c8bb5fd1550a751d4f2bcc5f3268454e462ecd","unresolved":false,"context_lines":[{"line_number":247,"context_line":"            filtered_project_ids \u003d []"},{"line_number":248,"context_line":"            # if project_id associated with a tag, then blacklist that tag"},{"line_number":249,"context_line":"            query \u003d session.query(ProjectTag)"},{"line_number":250,"context_line":"            query \u003d query.filter(ProjectTag.name.in_(tag_names))"},{"line_number":251,"context_line":"            query \u003d query.distinct("},{"line_number":252,"context_line":"                ProjectTag.project_id).group_by(ProjectTag.project_id)"},{"line_number":253,"context_line":"            for q in query:"}],"source_content_type":"text/x-python","patch_set":108,"id":"ff346bd7_bd5abd7f","line":250,"range":{"start_line":250,"start_character":12,"end_line":250,"end_character":64},"updated":"2017-07-28 15:06:41.000000000","message":"You can get the inverse of this directly. https://stackoverflow.com/questions/26182027/how-to-use-not-in-clause-in-sqlalchemy-orm-query","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"3037ccf8a00780aeb86bf79540ac2bbb61e114fe","unresolved":false,"context_lines":[{"line_number":247,"context_line":"            filtered_project_ids \u003d []"},{"line_number":248,"context_line":"            # if project_id associated with a tag, then blacklist that tag"},{"line_number":249,"context_line":"            query \u003d session.query(ProjectTag)"},{"line_number":250,"context_line":"            query \u003d query.filter(ProjectTag.name.in_(tag_names))"},{"line_number":251,"context_line":"            query \u003d query.distinct("},{"line_number":252,"context_line":"                ProjectTag.project_id).group_by(ProjectTag.project_id)"},{"line_number":253,"context_line":"            for q in query:"}],"source_content_type":"text/x-python","patch_set":108,"id":"df3967d1_d42092b3","line":250,"range":{"start_line":250,"start_character":12,"end_line":250,"end_character":64},"in_reply_to":"df3967d1_f13f28b3","updated":"2017-07-28 18:20:20.000000000","message":"actually it seems using ~ProjectTag or using notin_ and reducing the code down to look like tags-any fails to work for me. I\u0027ll leave this for now.","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"f975c319a72e3575027b6479fd95ddf72da0c43f","unresolved":false,"context_lines":[{"line_number":247,"context_line":"            filtered_project_ids \u003d []"},{"line_number":248,"context_line":"            # if project_id associated with a tag, then blacklist that tag"},{"line_number":249,"context_line":"            query \u003d session.query(ProjectTag)"},{"line_number":250,"context_line":"            query \u003d query.filter(ProjectTag.name.in_(tag_names))"},{"line_number":251,"context_line":"            query \u003d query.distinct("},{"line_number":252,"context_line":"                ProjectTag.project_id).group_by(ProjectTag.project_id)"},{"line_number":253,"context_line":"            for q in query:"}],"source_content_type":"text/x-python","patch_set":108,"id":"df3967d1_f13f28b3","line":250,"range":{"start_line":250,"start_character":12,"end_line":250,"end_character":64},"in_reply_to":"ff346bd7_bd5abd7f","updated":"2017-07-28 17:41:06.000000000","message":"Done","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"e0c8bb5fd1550a751d4f2bcc5f3268454e462ecd","unresolved":false,"context_lines":[{"line_number":348,"context_line":"            # below won\u0027t work with filter_limit_query unless hint is passed"},{"line_number":349,"context_line":"            query \u003d query.filter("},{"line_number":350,"context_line":"                ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":351,"context_line":"            project_tag_refs \u003d query.filter("},{"line_number":352,"context_line":"                ProjectTag.name \u003d\u003d tag_name)"},{"line_number":353,"context_line":"            for project_tag_ref in project_tag_refs:"},{"line_number":354,"context_line":"                session.delete(project_tag_ref)"},{"line_number":355,"context_line":""}],"source_content_type":"text/x-python","patch_set":108,"id":"ff346bd7_bd6bddee","line":352,"range":{"start_line":351,"start_character":12,"end_line":352,"end_character":44},"updated":"2017-07-28 15:06:41.000000000","message":"Can do delete directly after this filter. http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.delete","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"f975c319a72e3575027b6479fd95ddf72da0c43f","unresolved":false,"context_lines":[{"line_number":348,"context_line":"            # below won\u0027t work with filter_limit_query unless hint is passed"},{"line_number":349,"context_line":"            query \u003d query.filter("},{"line_number":350,"context_line":"                ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":351,"context_line":"            project_tag_refs \u003d query.filter("},{"line_number":352,"context_line":"                ProjectTag.name \u003d\u003d tag_name)"},{"line_number":353,"context_line":"            for project_tag_ref in project_tag_refs:"},{"line_number":354,"context_line":"                session.delete(project_tag_ref)"},{"line_number":355,"context_line":""}],"source_content_type":"text/x-python","patch_set":108,"id":"df3967d1_5151540e","line":352,"range":{"start_line":351,"start_character":12,"end_line":352,"end_character":44},"in_reply_to":"ff346bd7_bd6bddee","updated":"2017-07-28 17:41:06.000000000","message":"Done","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"e0c8bb5fd1550a751d4f2bcc5f3268454e462ecd","unresolved":false,"context_lines":[{"line_number":358,"context_line":"        with sql.session_for_write() as session:"},{"line_number":359,"context_line":"            query \u003d session.query(ProjectTag)"},{"line_number":360,"context_line":"            # below won\u0027t work with filter_limit_query unless hint is passed"},{"line_number":361,"context_line":"            project_tag_refs \u003d query.filter("},{"line_number":362,"context_line":"                ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":363,"context_line":"            for project_tag_ref in project_tag_refs:"},{"line_number":364,"context_line":"                session.delete(project_tag_ref)"},{"line_number":365,"context_line":""}],"source_content_type":"text/x-python","patch_set":108,"id":"ff346bd7_fd65e51e","line":362,"range":{"start_line":361,"start_character":12,"end_line":362,"end_character":52},"updated":"2017-07-28 15:06:41.000000000","message":"Can do delete directly after this filter. http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.delete","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"f975c319a72e3575027b6479fd95ddf72da0c43f","unresolved":false,"context_lines":[{"line_number":358,"context_line":"        with sql.session_for_write() as session:"},{"line_number":359,"context_line":"            query \u003d session.query(ProjectTag)"},{"line_number":360,"context_line":"            # below won\u0027t work with filter_limit_query unless hint is passed"},{"line_number":361,"context_line":"            project_tag_refs \u003d query.filter("},{"line_number":362,"context_line":"                ProjectTag.project_id \u003d\u003d project_id)"},{"line_number":363,"context_line":"            for project_tag_ref in project_tag_refs:"},{"line_number":364,"context_line":"                session.delete(project_tag_ref)"},{"line_number":365,"context_line":""}],"source_content_type":"text/x-python","patch_set":108,"id":"df3967d1_3156d008","line":362,"range":{"start_line":361,"start_character":12,"end_line":362,"end_character":52},"in_reply_to":"ff346bd7_fd65e51e","updated":"2017-07-28 17:41:06.000000000","message":"Done","commit_id":"4d9f8716c126b9e262cd52ff163dd0f9df1d0a57"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"683d6166a125511c020fdabde3d5c3762600f14e","unresolved":false,"context_lines":[{"line_number":348,"context_line":"    __tablename__ \u003d \u0027project_tag\u0027"},{"line_number":349,"context_line":"    attributes \u003d [\u0027project_id\u0027, \u0027name\u0027]"},{"line_number":350,"context_line":"    project_id \u003d sql.Column("},{"line_number":351,"context_line":"        sql.String(64), sql.ForeignKey(\u0027project.id\u0027, ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":352,"context_line":"        nullable\u003dFalse, primary_key\u003dTrue)"},{"line_number":353,"context_line":"    name \u003d sql.Column(sql.Unicode(60), nullable\u003dFalse, primary_key\u003dTrue)"},{"line_number":354,"context_line":"    __table_args__ \u003d (sql.UniqueConstraint(\u0027project_id\u0027, \u0027name\u0027),)"}],"source_content_type":"text/x-python","patch_set":121,"id":"7f287b81_a275fbfb","line":351,"range":{"start_line":351,"start_character":8,"end_line":351,"end_character":22},"updated":"2017-08-30 03:21:28.000000000","message":"This doesn\u0027t match the spec...and I understand why (maybe update the spec?)","commit_id":"79537885233a0f5b09ac622262f8bb18533ae4c4"},{"author":{"_account_id":20466,"name":"Tin Lam","email":"tin@lam.wtf","username":"tinlam"},"change_message_id":"9039cdc5c25ee077eba3e9903de40cf4e11939f8","unresolved":false,"context_lines":[{"line_number":348,"context_line":"    __tablename__ \u003d \u0027project_tag\u0027"},{"line_number":349,"context_line":"    attributes \u003d [\u0027project_id\u0027, \u0027name\u0027]"},{"line_number":350,"context_line":"    project_id \u003d sql.Column("},{"line_number":351,"context_line":"        sql.String(64), sql.ForeignKey(\u0027project.id\u0027, ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":352,"context_line":"        nullable\u003dFalse, primary_key\u003dTrue)"},{"line_number":353,"context_line":"    name \u003d sql.Column(sql.Unicode(60), nullable\u003dFalse, primary_key\u003dTrue)"},{"line_number":354,"context_line":"    __table_args__ \u003d (sql.UniqueConstraint(\u0027project_id\u0027, \u0027name\u0027),)"}],"source_content_type":"text/x-python","patch_set":121,"id":"7f287b81_dee21fd5","line":351,"range":{"start_line":351,"start_character":8,"end_line":351,"end_character":22},"in_reply_to":"7f287b81_a275fbfb","updated":"2017-08-30 10:03:15.000000000","message":"This seems to be updated to varchar(64) in the latest spec [0] via commit [1].\n\n[0] https://github.com/openstack/keystone-specs/blob/master/specs/keystone/queens/project-tags.rst\n[1] https://github.com/openstack/keystone-specs/commit/e2c6a37428c07d07ce5aa797f5a373399c476293","commit_id":"79537885233a0f5b09ac622262f8bb18533ae4c4"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"683d6166a125511c020fdabde3d5c3762600f14e","unresolved":false,"context_lines":[{"line_number":350,"context_line":"    project_id \u003d sql.Column("},{"line_number":351,"context_line":"        sql.String(64), sql.ForeignKey(\u0027project.id\u0027, ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":352,"context_line":"        nullable\u003dFalse, primary_key\u003dTrue)"},{"line_number":353,"context_line":"    name \u003d sql.Column(sql.Unicode(60), nullable\u003dFalse, primary_key\u003dTrue)"},{"line_number":354,"context_line":"    __table_args__ \u003d (sql.UniqueConstraint(\u0027project_id\u0027, \u0027name\u0027),)"}],"source_content_type":"text/x-python","patch_set":121,"id":"7f287b81_8270bf09","line":353,"range":{"start_line":353,"start_character":22,"end_line":353,"end_character":37},"updated":"2017-08-30 03:21:28.000000000","message":"why 60?","commit_id":"79537885233a0f5b09ac622262f8bb18533ae4c4"},{"author":{"_account_id":20466,"name":"Tin Lam","email":"tin@lam.wtf","username":"tinlam"},"change_message_id":"9039cdc5c25ee077eba3e9903de40cf4e11939f8","unresolved":false,"context_lines":[{"line_number":350,"context_line":"    project_id \u003d sql.Column("},{"line_number":351,"context_line":"        sql.String(64), sql.ForeignKey(\u0027project.id\u0027, ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":352,"context_line":"        nullable\u003dFalse, primary_key\u003dTrue)"},{"line_number":353,"context_line":"    name \u003d sql.Column(sql.Unicode(60), nullable\u003dFalse, primary_key\u003dTrue)"},{"line_number":354,"context_line":"    __table_args__ \u003d (sql.UniqueConstraint(\u0027project_id\u0027, \u0027name\u0027),)"}],"source_content_type":"text/x-python","patch_set":121,"id":"7f287b81_5e862fbb","line":353,"range":{"start_line":353,"start_character":22,"end_line":353,"end_character":37},"in_reply_to":"7f287b81_8270bf09","updated":"2017-08-30 10:03:15.000000000","message":"I don\u0027t recall how we ended up with 60, but it appears others feel it is too restrictive too [2]. We can up it to 80 like nova\u0027s implementation [3] or even larger.  I think there might be worry that if uncapped, this table can balloon in size - but am not sure.\n\n[2] https://review.openstack.org/#/c/484483/25/keystone/resource/schema.py@26\n[3] https://github.com/openstack/nova/blob/master/nova/db/sqlalchemy/models.py#L1470","commit_id":"79537885233a0f5b09ac622262f8bb18533ae4c4"}],"keystone/resource/controllers.py":[{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"aa6b218b4d88ef513ec9b0ad6421269c89484fd3","unresolved":false,"context_lines":[{"line_number":352,"context_line":""},{"line_number":353,"context_line":""},{"line_number":354,"context_line":"@dependency.requires(\u0027resource_api\u0027)"},{"line_number":355,"context_line":"class ProjectTagV3(controller.V3Controller):"},{"line_number":356,"context_line":"    collection_name \u003d \u0027tags\u0027"},{"line_number":357,"context_line":"    member_name \u003d \u0027tag\u0027"},{"line_number":358,"context_line":""}],"source_content_type":"text/x-python","patch_set":29,"id":"3f1d235d_582a0f90","line":355,"range":{"start_line":355,"start_character":6,"end_line":355,"end_character":18},"updated":"2017-07-03 21:15:09.000000000","message":"add notifications for created, updated etc.","commit_id":"8c6f78ab8018f45883238a9668d3f8d422c7cb4d"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"aa6b218b4d88ef513ec9b0ad6421269c89484fd3","unresolved":false,"context_lines":[{"line_number":372,"context_line":"    @controller.protected()"},{"line_number":373,"context_line":"    def get_project_tag(self, request, project_tag_id):"},{"line_number":374,"context_line":"        ref \u003d self.resource_api.get_project_tag(project_tag_id)"},{"line_number":375,"context_line":"        return ref"},{"line_number":376,"context_line":""},{"line_number":377,"context_line":"    @controller.protected()"},{"line_number":378,"context_line":"    def delete_project_tag(self, request, project_tag_id):"}],"source_content_type":"text/x-python","patch_set":29,"id":"3f1d235d_d83e1fd9","line":375,"range":{"start_line":375,"start_character":15,"end_line":375,"end_character":18},"updated":"2017-07-03 21:15:09.000000000","message":"wrap member","commit_id":"8c6f78ab8018f45883238a9668d3f8d422c7cb4d"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"aa6b218b4d88ef513ec9b0ad6421269c89484fd3","unresolved":false,"context_lines":[{"line_number":381,"context_line":"            initiator\u003drequest.audit_initiator)"},{"line_number":382,"context_line":""},{"line_number":383,"context_line":"    @controller.protected()"},{"line_number":384,"context_line":"    def list_project_tags(self, project_tag_id):"},{"line_number":385,"context_line":"        return self.resource_api.list_project_tags("},{"line_number":386,"context_line":"            project_tag_id)"}],"source_content_type":"text/x-python","patch_set":29,"id":"3f1d235d_3832b311","line":384,"range":{"start_line":384,"start_character":8,"end_line":384,"end_character":25},"updated":"2017-07-03 21:15:09.000000000","message":"add hints","commit_id":"8c6f78ab8018f45883238a9668d3f8d422c7cb4d"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"aa6b218b4d88ef513ec9b0ad6421269c89484fd3","unresolved":false,"context_lines":[{"line_number":382,"context_line":""},{"line_number":383,"context_line":"    @controller.protected()"},{"line_number":384,"context_line":"    def list_project_tags(self, project_tag_id):"},{"line_number":385,"context_line":"        return self.resource_api.list_project_tags("},{"line_number":386,"context_line":"            project_tag_id)"}],"source_content_type":"text/x-python","patch_set":29,"id":"3f1d235d_b825a3c4","line":385,"range":{"start_line":385,"start_character":15,"end_line":385,"end_character":19},"updated":"2017-07-03 21:15:09.000000000","message":"wrap collection","commit_id":"8c6f78ab8018f45883238a9668d3f8d422c7cb4d"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"5b9d78df08fb9b1e1372b384d657061922b7ee58","unresolved":false,"context_lines":[{"line_number":352,"context_line":""},{"line_number":353,"context_line":""},{"line_number":354,"context_line":"@dependency.requires(\u0027resource_api\u0027)"},{"line_number":355,"context_line":"class ProjectTagV3(controller.V3Controller):"},{"line_number":356,"context_line":"    # TODO(aselius): Add notifications for created, updated, deleted."},{"line_number":357,"context_line":"    collection_name \u003d \u0027tags\u0027"},{"line_number":358,"context_line":"    member_name \u003d \u0027tag\u0027"}],"source_content_type":"text/x-python","patch_set":35,"id":"3f1d235d_143f29b6","line":355,"range":{"start_line":355,"start_character":6,"end_line":355,"end_character":18},"updated":"2017-07-07 17:41:50.000000000","message":"add the rest of the actions in the controller","commit_id":"647825a34dae527c8ec6ad8de89d8a2318633ce5"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"5b9d78df08fb9b1e1372b384d657061922b7ee58","unresolved":false,"context_lines":[{"line_number":354,"context_line":"@dependency.requires(\u0027resource_api\u0027)"},{"line_number":355,"context_line":"class ProjectTagV3(controller.V3Controller):"},{"line_number":356,"context_line":"    # TODO(aselius): Add notifications for created, updated, deleted."},{"line_number":357,"context_line":"    collection_name \u003d \u0027tags\u0027"},{"line_number":358,"context_line":"    member_name \u003d \u0027tag\u0027"},{"line_number":359,"context_line":""},{"line_number":360,"context_line":"    def __init__(self):"}],"source_content_type":"text/x-python","patch_set":35,"id":"3f1d235d_146849b8","line":357,"range":{"start_line":357,"start_character":4,"end_line":357,"end_character":19},"updated":"2017-07-07 17:41:50.000000000","message":"think of revising the collection/member names","commit_id":"647825a34dae527c8ec6ad8de89d8a2318633ce5"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"1889827904323734861cedcf5d4d9123a8a8eac6","unresolved":false,"context_lines":[{"line_number":283,"context_line":"            hints.add_filter(\u0027is_domain\u0027, \u00270\u0027)"},{"line_number":284,"context_line":"        refs \u003d self.resource_api.list_projects(hints\u003dhints)"},{"line_number":285,"context_line":"        for ref in refs:"},{"line_number":286,"context_line":"            ref[\u0027tags\u0027] \u003d self.resource_api.list_project_tag_by_name(ref[\u0027id\u0027])"},{"line_number":287,"context_line":"        return ProjectV3.wrap_collection(request.context_dict,"},{"line_number":288,"context_line":"                                         refs, hints\u003dhints)"},{"line_number":289,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"3f1d235d_29cbeb72","line":286,"range":{"start_line":286,"start_character":44,"end_line":286,"end_character":68},"updated":"2017-07-07 21:32:23.000000000","message":"a lot of things going haywire b/c this should be list_project_tags_by_name","commit_id":"bf609976a25f207992d79676ad92b4257c9957a1"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"1889827904323734861cedcf5d4d9123a8a8eac6","unresolved":false,"context_lines":[{"line_number":333,"context_line":"    @controller.protected()"},{"line_number":334,"context_line":"    def get_project(self, request, project_id):"},{"line_number":335,"context_line":"        ref \u003d self.resource_api.get_project(project_id)"},{"line_number":336,"context_line":"        ref[\u0027tags\u0027] \u003d self.resource_api.list_project_tag_by_name(ref[\u0027id\u0027])"},{"line_number":337,"context_line":"        self._expand_project_ref(request, ref)"},{"line_number":338,"context_line":"        return ProjectV3.wrap_member(request.context_dict, ref)"},{"line_number":339,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"3f1d235d_09c82f72","line":336,"range":{"start_line":336,"start_character":40,"end_line":336,"end_character":64},"updated":"2017-07-07 21:32:23.000000000","message":"same here","commit_id":"bf609976a25f207992d79676ad92b4257c9957a1"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b59764c290dc7c88d528e389a5ee2547820f9ec9","unresolved":false,"context_lines":[{"line_number":285,"context_line":""},{"line_number":286,"context_line":"    def _expand_project_ref(self, request, ref):"},{"line_number":287,"context_line":"        params \u003d request.params"},{"line_number":288,"context_line":"        context \u003d request.context_dict"},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"        parents_as_list \u003d \u0027parents_as_list\u0027 in params and ("},{"line_number":291,"context_line":"            self.query_filter_is_true(params[\u0027parents_as_list\u0027]))"}],"source_content_type":"text/x-python","patch_set":52,"id":"1f1a1f67_57509ed4","side":"PARENT","line":288,"updated":"2017-07-14 23:26:58.000000000","message":"Unrelated whitespace change","commit_id":"966fb5125cf1178d8804cf130726fc2a5c581344"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b59764c290dc7c88d528e389a5ee2547820f9ec9","unresolved":false,"context_lines":[{"line_number":306,"context_line":"        not_tags \u003d \u0027not-tags\u0027 in params and ("},{"line_number":307,"context_line":"            self.query_filter_is_true(params[\u0027not-tags\u0027]))"},{"line_number":308,"context_line":"        not_tags_any \u003d \u0027not-tags-any\u0027 in params and ("},{"line_number":309,"context_line":"            self.query_filter_is_true(params[\u0027not-tags-any\u0027]))"},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"        if tags:"},{"line_number":312,"context_line":"            tagged_project \u003d self.resource_api.list_projects_with_tags("}],"source_content_type":"text/x-python","patch_set":52,"id":"1f1a1f67_172fc6f6","line":309,"updated":"2017-07-14 23:26:58.000000000","message":"What about doing something like:\n\n  def _expand_project_list(self, request, ref):\n      params \u003d request.params\n\n      tagged_projects \u003d []\n      tag_map \u003d {\n          \u0027tags\u0027: \u0027list_projects_with_tags\u0027,\n          \u0027tags-any\u0027: \u0027list_projects_with_tags_any\u0027,\n          \u0027not-tags\u0027: \u0027list_projects_not_tags\u0027,\n          \u0027not-tags-any\u0027: \u0027list_projects_not_tags_any\u0027\n      }\n      for k, v in tag_map.items():\n          tag_set  \u003d params[k]\n          if k in params and self.query_filter_is_true(tag_set):\n              tagged_projects.append(getattr(self.resource_api, v)(tag_set))\n      return tagged_projects\n\nThis was totally back of the napkin, so it might need some ironing. This way you might not need as many if statements to get the same result. You also don\u0027t have to convert form tag to boolean back to tag.","commit_id":"1fc8231304c99e82d803cadac3ac7317fb66eca4"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"902ec9e4cb3837e13c57d599b55b355fa39a5cb1","unresolved":false,"context_lines":[{"line_number":239,"context_line":"        ref \u003d self.domain_config_api.get_config_default(group, option)"},{"line_number":240,"context_line":"        return {self.member_name: ref}"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"# TODO(aselius): Use the resource_api in core.py as wrapper for the function"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":""},{"line_number":245,"context_line":"@dependency.requires(\u0027resource_api\u0027)"}],"source_content_type":"text/x-python","patch_set":64,"id":"1f1a1f67_a13974a4","line":242,"range":{"start_line":242,"start_character":0,"end_line":242,"end_character":76},"updated":"2017-07-19 16:44:57.000000000","message":"This is done then right?","commit_id":"c2b03ccedf2fa5a97b6c05fcfb4979ede4b6bfd7"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"f1b0183ea872338f969c440a33992a6fc9ec9e33","unresolved":false,"context_lines":[{"line_number":239,"context_line":"        ref \u003d self.domain_config_api.get_config_default(group, option)"},{"line_number":240,"context_line":"        return {self.member_name: ref}"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"# TODO(aselius): Use the resource_api in core.py as wrapper for the function"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":""},{"line_number":245,"context_line":"@dependency.requires(\u0027resource_api\u0027)"}],"source_content_type":"text/x-python","patch_set":64,"id":"1f1a1f67_a1c054e2","line":242,"range":{"start_line":242,"start_character":0,"end_line":242,"end_character":76},"in_reply_to":"1f1a1f67_a13974a4","updated":"2017-07-19 17:00:52.000000000","message":"yeah for some of these the wrapper actually needs to be taken out.","commit_id":"c2b03ccedf2fa5a97b6c05fcfb4979ede4b6bfd7"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"f1b0183ea872338f969c440a33992a6fc9ec9e33","unresolved":false,"context_lines":[{"line_number":289,"context_line":"            refs \u003d self.resource_api.list_projects(hints\u003dhints)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        for ref in refs:"},{"line_number":292,"context_line":"            ref[\u0027tags\u0027] \u003d self.resource_api.list_project_tags(ref[\u0027id\u0027])"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"        return ProjectV3.wrap_collection(request.context_dict,"},{"line_number":295,"context_line":"                                         refs, hints\u003dhints)"}],"source_content_type":"text/x-python","patch_set":64,"id":"1f1a1f67_0174a8cd","line":292,"range":{"start_line":292,"start_character":44,"end_line":292,"end_character":61},"updated":"2017-07-19 17:00:52.000000000","message":"this is why tag dictionary is currently returned when listing projects. need to bring list_tag_names_in_list back","commit_id":"c2b03ccedf2fa5a97b6c05fcfb4979ede4b6bfd7"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"448b93e34bff8f0bff63fa17a87d7db70168f361","unresolved":false,"context_lines":[{"line_number":366,"context_line":"    @controller.protected()"},{"line_number":367,"context_line":"    def get_project(self, request, project_id):"},{"line_number":368,"context_line":"        ref \u003d self.resource_api.get_project(project_id)"},{"line_number":369,"context_line":"        ref[\u0027tags\u0027] \u003d self.resource_api.list_project_tags(ref[\u0027id\u0027])"},{"line_number":370,"context_line":"        self._expand_project_ref(request, ref)"},{"line_number":371,"context_line":"        return ProjectV3.wrap_member(request.context_dict, ref)"},{"line_number":372,"context_line":""}],"source_content_type":"text/x-python","patch_set":64,"id":"1f1a1f67_15797ec6","line":369,"range":{"start_line":369,"start_character":40,"end_line":369,"end_character":57},"updated":"2017-07-19 18:49:20.000000000","message":"ditto here","commit_id":"c2b03ccedf2fa5a97b6c05fcfb4979ede4b6bfd7"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"6d3f10631caf8360e218182a28c052e22d1363b4","unresolved":false,"context_lines":[{"line_number":289,"context_line":"            refs \u003d self.resource_api.list_projects(hints\u003dhints)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        for ref in refs:"},{"line_number":292,"context_line":"            ref[\u0027tags\u0027] \u003d self.resource_api.list_project_tags(ref[\u0027id\u0027])"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"        return ProjectV3.wrap_collection(request.context_dict,"},{"line_number":295,"context_line":"                                         refs, hints\u003dhints)"}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_915d7deb","line":292,"range":{"start_line":292,"start_character":17,"end_line":292,"end_character":21},"updated":"2017-07-20 16:32:12.000000000","message":"this was .update because list project_tags was returning a dict on patchset 67, and i believe 68.","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"41e1af629ab834a905ba52f99e99e422307356ac","unresolved":false,"context_lines":[{"line_number":289,"context_line":"            refs \u003d self.resource_api.list_projects(hints\u003dhints)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        for ref in refs:"},{"line_number":292,"context_line":"            ref[\u0027tags\u0027] \u003d self.resource_api.list_project_tags(ref[\u0027id\u0027])"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"        return ProjectV3.wrap_collection(request.context_dict,"},{"line_number":295,"context_line":"                                         refs, hints\u003dhints)"}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_b1e8797c","line":292,"range":{"start_line":292,"start_character":17,"end_line":292,"end_character":21},"in_reply_to":"1f1a1f67_915d7deb","updated":"2017-07-20 16:38:34.000000000","message":"we can revert it, as long as the tests are updated","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"28b46f86821247d3c9bdd77be6d3614925abb7ae","unresolved":false,"context_lines":[{"line_number":239,"context_line":"        ref \u003d self.domain_config_api.get_config_default(group, option)"},{"line_number":240,"context_line":"        return {self.member_name: ref}"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"# TODO(aselius): Use the resource_api in core.py as wrapper for the function"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":""},{"line_number":245,"context_line":"@dependency.requires(\u0027resource_api\u0027)"}],"source_content_type":"text/x-python","patch_set":80,"id":"ff346bd7_9ce443ae","line":242,"updated":"2017-07-24 15:39:36.000000000","message":"what function?","commit_id":"0d9df4582a608cd63a192640a48055c64fd0c7e9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"4eb38d17378cda3d3adaede82d624baedc1dc031","unresolved":false,"context_lines":[{"line_number":239,"context_line":"        ref \u003d self.domain_config_api.get_config_default(group, option)"},{"line_number":240,"context_line":"        return {self.member_name: ref}"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"# TODO(aselius): Use the resource_api in core.py as wrapper for the function"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":""},{"line_number":245,"context_line":"@dependency.requires(\u0027resource_api\u0027)"}],"source_content_type":"text/x-python","patch_set":80,"id":"ff346bd7_3fcc2934","line":242,"in_reply_to":"ff346bd7_9ce443ae","updated":"2017-07-24 16:10:44.000000000","message":"apologies forgot to flush out the todos completed. will get rid of.","commit_id":"0d9df4582a608cd63a192640a48055c64fd0c7e9"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"28b46f86821247d3c9bdd77be6d3614925abb7ae","unresolved":false,"context_lines":[{"line_number":281,"context_line":"        # False (which in query terms means \u00270\u0027)"},{"line_number":282,"context_line":"        if \u0027is_domain\u0027 not in request.params:"},{"line_number":283,"context_line":"            hints.add_filter(\u0027is_domain\u0027, \u00270\u0027)"},{"line_number":284,"context_line":"        tag_params \u003d [\u0027tags\u0027, \u0027tags-any\u0027, \u0027not-tags\u0027, \u0027not-tags-any\u0027]"},{"line_number":285,"context_line":"        is_in \u003d lambda a, b: any(i in b for i in a)"},{"line_number":286,"context_line":"        if is_in(request.params.keys(), tag_params):"},{"line_number":287,"context_line":"            refs \u003d self._expand_project_list(request)"},{"line_number":288,"context_line":"        else:"},{"line_number":289,"context_line":"            refs \u003d self.resource_api.list_projects(hints\u003dhints)"},{"line_number":290,"context_line":""}],"source_content_type":"text/x-python","patch_set":80,"id":"ff346bd7_fcd58fba","line":287,"range":{"start_line":284,"start_character":0,"end_line":287,"end_character":53},"updated":"2017-07-24 15:39:36.000000000","message":"it is not obvious what this portion of code is doing. please add a comment","commit_id":"0d9df4582a608cd63a192640a48055c64fd0c7e9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"4eb38d17378cda3d3adaede82d624baedc1dc031","unresolved":false,"context_lines":[{"line_number":281,"context_line":"        # False (which in query terms means \u00270\u0027)"},{"line_number":282,"context_line":"        if \u0027is_domain\u0027 not in request.params:"},{"line_number":283,"context_line":"            hints.add_filter(\u0027is_domain\u0027, \u00270\u0027)"},{"line_number":284,"context_line":"        tag_params \u003d [\u0027tags\u0027, \u0027tags-any\u0027, \u0027not-tags\u0027, \u0027not-tags-any\u0027]"},{"line_number":285,"context_line":"        is_in \u003d lambda a, b: any(i in b for i in a)"},{"line_number":286,"context_line":"        if is_in(request.params.keys(), tag_params):"},{"line_number":287,"context_line":"            refs \u003d self._expand_project_list(request)"},{"line_number":288,"context_line":"        else:"},{"line_number":289,"context_line":"            refs \u003d self.resource_api.list_projects(hints\u003dhints)"},{"line_number":290,"context_line":""}],"source_content_type":"text/x-python","patch_set":80,"id":"ff346bd7_ffd581ba","line":287,"range":{"start_line":284,"start_character":0,"end_line":287,"end_character":53},"in_reply_to":"ff346bd7_fcd58fba","updated":"2017-07-24 16:10:44.000000000","message":"Done","commit_id":"0d9df4582a608cd63a192640a48055c64fd0c7e9"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"28b46f86821247d3c9bdd77be6d3614925abb7ae","unresolved":false,"context_lines":[{"line_number":295,"context_line":"        return ProjectV3.wrap_collection(request.context_dict,"},{"line_number":296,"context_line":"                                         refs, hints\u003dhints)"},{"line_number":297,"context_line":""},{"line_number":298,"context_line":"    def _expand_project_list(self, request):"},{"line_number":299,"context_line":"        params \u003d request.params"},{"line_number":300,"context_line":"        tag_map \u003d {"},{"line_number":301,"context_line":"            \u0027tags\u0027: \u0027list_projects_with_tags\u0027,"}],"source_content_type":"text/x-python","patch_set":80,"id":"ff346bd7_3c9af713","line":298,"updated":"2017-07-24 15:39:36.000000000","message":"same here, a function doc would be useful","commit_id":"0d9df4582a608cd63a192640a48055c64fd0c7e9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"4eb38d17378cda3d3adaede82d624baedc1dc031","unresolved":false,"context_lines":[{"line_number":295,"context_line":"        return ProjectV3.wrap_collection(request.context_dict,"},{"line_number":296,"context_line":"                                         refs, hints\u003dhints)"},{"line_number":297,"context_line":""},{"line_number":298,"context_line":"    def _expand_project_list(self, request):"},{"line_number":299,"context_line":"        params \u003d request.params"},{"line_number":300,"context_line":"        tag_map \u003d {"},{"line_number":301,"context_line":"            \u0027tags\u0027: \u0027list_projects_with_tags\u0027,"}],"source_content_type":"text/x-python","patch_set":80,"id":"ff346bd7_9fe435ae","line":298,"in_reply_to":"ff346bd7_3c9af713","updated":"2017-07-24 16:10:44.000000000","message":"Done","commit_id":"0d9df4582a608cd63a192640a48055c64fd0c7e9"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"28b46f86821247d3c9bdd77be6d3614925abb7ae","unresolved":false,"context_lines":[{"line_number":412,"context_line":"            project_id\u003dproject_id,"},{"line_number":413,"context_line":"            project_tag_name\u003dvalue)"},{"line_number":414,"context_line":""},{"line_number":415,"context_line":"    # TODO(aselius): Add hints to provide more info about limits etc."},{"line_number":416,"context_line":"    @controller.protected()"},{"line_number":417,"context_line":"    def list_project_tags(self, request, project_id):"},{"line_number":418,"context_line":"        resp \u003d self.resource_api.list_project_tags(project_id)"}],"source_content_type":"text/x-python","patch_set":80,"id":"ff346bd7_5c637b1b","line":415,"range":{"start_line":415,"start_character":31,"end_line":415,"end_character":68},"updated":"2017-07-24 15:39:36.000000000","message":"hint on the name is the only thing I can imagine for this tag entity","commit_id":"0d9df4582a608cd63a192640a48055c64fd0c7e9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"4eb38d17378cda3d3adaede82d624baedc1dc031","unresolved":false,"context_lines":[{"line_number":412,"context_line":"            project_id\u003dproject_id,"},{"line_number":413,"context_line":"            project_tag_name\u003dvalue)"},{"line_number":414,"context_line":""},{"line_number":415,"context_line":"    # TODO(aselius): Add hints to provide more info about limits etc."},{"line_number":416,"context_line":"    @controller.protected()"},{"line_number":417,"context_line":"    def list_project_tags(self, request, project_id):"},{"line_number":418,"context_line":"        resp \u003d self.resource_api.list_project_tags(project_id)"}],"source_content_type":"text/x-python","patch_set":80,"id":"ff346bd7_22dd2c42","line":415,"range":{"start_line":415,"start_character":31,"end_line":415,"end_character":68},"in_reply_to":"ff346bd7_5c637b1b","updated":"2017-07-24 16:10:44.000000000","message":"like the other todos this was something jotted down way early and which can be deleted now. sorry about the mess. i\u0027ll go and double check to see all the todos have been resolved / deleted","commit_id":"0d9df4582a608cd63a192640a48055c64fd0c7e9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"137817a58bf6743f1b1613c9dd045cc4c136d1bd","unresolved":false,"context_lines":[{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    @controller.protected()"},{"line_number":430,"context_line":"    def remove_all_project_tags(self, request, project_id):"},{"line_number":431,"context_line":"        # initiator\u003drequest.audit_initiator removed"},{"line_number":432,"context_line":"        return self.resource_api.remove_all_project_tags("},{"line_number":433,"context_line":"            project_id)"}],"source_content_type":"text/x-python","patch_set":83,"id":"ff346bd7_e35e03e5","line":431,"range":{"start_line":431,"start_character":10,"end_line":431,"end_character":19},"updated":"2017-07-24 19:53:22.000000000","message":"remove","commit_id":"5416f25d9b9f26b2deaf7c5ed5c81b5648ce6dd2"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"92c6c43f02c15eb96b7a8f119319960fc931608e","unresolved":false,"context_lines":[{"line_number":427,"context_line":""},{"line_number":428,"context_line":"    @controller.protected()"},{"line_number":429,"context_line":"    def remove_all_project_tags(self, request, project_id):"},{"line_number":430,"context_line":"        # initiator\u003drequest.audit_initiator removed"},{"line_number":431,"context_line":"        return self.resource_api.remove_all_project_tags("},{"line_number":432,"context_line":"            project_id)"}],"source_content_type":"text/x-python","patch_set":87,"id":"ff346bd7_120a6fd1","line":430,"range":{"start_line":430,"start_character":10,"end_line":430,"end_character":19},"updated":"2017-07-24 22:20:40.000000000","message":"remove","commit_id":"ccbc030b7597b97c731ed87762851a1fa212001b"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"811f74a7cbc9553f7fec788fa3e9dbae3e41571a","unresolved":false,"context_lines":[{"line_number":396,"context_line":"        self.resource_api.create_project_tag("},{"line_number":397,"context_line":"            project_id, value, initiator\u003drequest.audit_initiator)"},{"line_number":398,"context_line":"        resp \u003d request.context_dict"},{"line_number":399,"context_line":"        try:"},{"line_number":400,"context_line":"            url \u003d resp[\u0027host_url\u0027] + resp[\u0027environment\u0027][\u0027REQUEST_URI\u0027]"},{"line_number":401,"context_line":"        except Exception:"},{"line_number":402,"context_line":"            url \u003d resp[\u0027path\u0027]"},{"line_number":403,"context_line":"        return {\u0027location\u0027: url}"},{"line_number":404,"context_line":""},{"line_number":405,"context_line":"    @controller.protected()"},{"line_number":406,"context_line":"    def get_project_tag(self, request, project_id, value):"}],"source_content_type":"text/x-python","patch_set":91,"id":"ff346bd7_125a5629","line":403,"range":{"start_line":399,"start_character":0,"end_line":403,"end_character":32},"updated":"2017-07-25 13:32:38.000000000","message":"what is this?","commit_id":"3031b3af1695370db5e121ab6e1ececd9d3840df"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"d661c3529fc2c0bc302e1ff18dc5349351176ba6","unresolved":false,"context_lines":[{"line_number":396,"context_line":"        self.resource_api.create_project_tag("},{"line_number":397,"context_line":"            project_id, value, initiator\u003drequest.audit_initiator)"},{"line_number":398,"context_line":"        resp \u003d request.context_dict"},{"line_number":399,"context_line":"        try:"},{"line_number":400,"context_line":"            url \u003d resp[\u0027host_url\u0027] + resp[\u0027environment\u0027][\u0027REQUEST_URI\u0027]"},{"line_number":401,"context_line":"        except Exception:"},{"line_number":402,"context_line":"            url \u003d resp[\u0027path\u0027]"},{"line_number":403,"context_line":"        return {\u0027location\u0027: url}"},{"line_number":404,"context_line":""},{"line_number":405,"context_line":"    @controller.protected()"},{"line_number":406,"context_line":"    def get_project_tag(self, request, project_id, value):"}],"source_content_type":"text/x-python","patch_set":91,"id":"ff346bd7_d591559b","line":403,"range":{"start_line":399,"start_character":0,"end_line":403,"end_character":32},"in_reply_to":"ff346bd7_125a5629","updated":"2017-07-25 15:05:00.000000000","message":"This is building the location url of the tag, this is returned with nova server tags so we added it here.","commit_id":"3031b3af1695370db5e121ab6e1ececd9d3840df"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"811f74a7cbc9553f7fec788fa3e9dbae3e41571a","unresolved":false,"context_lines":[{"line_number":415,"context_line":"    @controller.protected()"},{"line_number":416,"context_line":"    def list_project_tags(self, request, project_id):"},{"line_number":417,"context_line":"        resp \u003d self.resource_api.list_project_tags(project_id)"},{"line_number":418,"context_line":"        if not resp[\u0027tags\u0027]:"},{"line_number":419,"context_line":"            raise exception.ProjectTagsNotFound(project_id\u003dproject_id)"},{"line_number":420,"context_line":"        return resp"},{"line_number":421,"context_line":""},{"line_number":422,"context_line":"    @controller.protected()"}],"source_content_type":"text/x-python","patch_set":91,"id":"ff346bd7_f2aeb2e5","line":419,"range":{"start_line":418,"start_character":0,"end_line":419,"end_character":70},"updated":"2017-07-25 13:32:38.000000000","message":"why? is it forbidden/an error to not have any tag on a project?","commit_id":"3031b3af1695370db5e121ab6e1ececd9d3840df"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"d661c3529fc2c0bc302e1ff18dc5349351176ba6","unresolved":false,"context_lines":[{"line_number":415,"context_line":"    @controller.protected()"},{"line_number":416,"context_line":"    def list_project_tags(self, request, project_id):"},{"line_number":417,"context_line":"        resp \u003d self.resource_api.list_project_tags(project_id)"},{"line_number":418,"context_line":"        if not resp[\u0027tags\u0027]:"},{"line_number":419,"context_line":"            raise exception.ProjectTagsNotFound(project_id\u003dproject_id)"},{"line_number":420,"context_line":"        return resp"},{"line_number":421,"context_line":""},{"line_number":422,"context_line":"    @controller.protected()"}],"source_content_type":"text/x-python","patch_set":91,"id":"ff346bd7_95d3cd38","line":419,"range":{"start_line":418,"start_character":0,"end_line":419,"end_character":70},"in_reply_to":"ff346bd7_f2aeb2e5","updated":"2017-07-25 15:05:00.000000000","message":"We may not need this, we could just return an empty list instead.","commit_id":"3031b3af1695370db5e121ab6e1ececd9d3840df"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f72f8c9c8b689bed68994209d08826f4c2c7065d","unresolved":false,"context_lines":[{"line_number":325,"context_line":"                if self.query_filter_is_true(tag_set):"},{"line_number":326,"context_line":"                    tagged_projects \u003d (getattr(self.resource_api, v)(tag_set))"},{"line_number":327,"context_line":"            else:"},{"line_number":328,"context_line":"                pass"},{"line_number":329,"context_line":"        return tagged_projects"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"    def _expand_project_ref(self, request, ref):"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_d10c9eed","line":328,"updated":"2017-07-26 15:54:11.000000000","message":"I think these two lines could be removed.","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"ad5d4c300d3c756b69cb93be058895c049bcd5c2","unresolved":false,"context_lines":[{"line_number":325,"context_line":"                if self.query_filter_is_true(tag_set):"},{"line_number":326,"context_line":"                    tagged_projects \u003d (getattr(self.resource_api, v)(tag_set))"},{"line_number":327,"context_line":"            else:"},{"line_number":328,"context_line":"                pass"},{"line_number":329,"context_line":"        return tagged_projects"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"    def _expand_project_ref(self, request, ref):"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_d7380eef","line":328,"in_reply_to":"ff346bd7_d10c9eed","updated":"2017-07-26 17:03:39.000000000","message":"good catch. i think this was there before we put the lambda in in list projects. yes this can be removed","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f72f8c9c8b689bed68994209d08826f4c2c7065d","unresolved":false,"context_lines":[{"line_number":418,"context_line":"        validation.lazy_validate(schema.project_tag_create, value)"},{"line_number":419,"context_line":"        self.resource_api.create_project_tag("},{"line_number":420,"context_line":"            project_id, value, initiator\u003drequest.audit_initiator)"},{"line_number":421,"context_line":"        r \u003d request.context_dict"},{"line_number":422,"context_line":"        try:"},{"line_number":423,"context_line":"            url \u003d r[\u0027host_url\u0027] + r[\u0027environment\u0027][\u0027REQUEST_URI\u0027]"},{"line_number":424,"context_line":"        except Exception:"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_d1813efd","line":421,"updated":"2017-07-26 15:54:11.000000000","message":"We typically use wrap_member for handling this.","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"ad5d4c300d3c756b69cb93be058895c049bcd5c2","unresolved":false,"context_lines":[{"line_number":418,"context_line":"        validation.lazy_validate(schema.project_tag_create, value)"},{"line_number":419,"context_line":"        self.resource_api.create_project_tag("},{"line_number":420,"context_line":"            project_id, value, initiator\u003drequest.audit_initiator)"},{"line_number":421,"context_line":"        r \u003d request.context_dict"},{"line_number":422,"context_line":"        try:"},{"line_number":423,"context_line":"            url \u003d r[\u0027host_url\u0027] + r[\u0027environment\u0027][\u0027REQUEST_URI\u0027]"},{"line_number":424,"context_line":"        except Exception:"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_e90b367a","line":421,"in_reply_to":"ff346bd7_d1813efd","updated":"2017-07-26 17:03:39.000000000","message":"so something along the lines of..\n        ref \u003d self.resource_api.create_project_tag(\n            project_id, value, initiator\u003drequest.audit_initiator)\n        r \u003d ProectTagV3.wrap_member(request.context_dict, ref)\nseem good to you?","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f72f8c9c8b689bed68994209d08826f4c2c7065d","unresolved":false,"context_lines":[{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    @controller.protected()"},{"line_number":430,"context_line":"    def get_project_tag(self, request, project_id, value):"},{"line_number":431,"context_line":"        self.resource_api.get_project_tag(project_id, value)"},{"line_number":432,"context_line":""},{"line_number":433,"context_line":"    @controller.protected()"},{"line_number":434,"context_line":"    def delete_project_tag(self, request, project_id, value):"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_51c30e39","line":431,"updated":"2017-07-26 15:54:11.000000000","message":"This needs to return I think\n\n  ref \u003d self.resource_api.get_project_tag(project_id, value)\n  return ProjectTagV3.wrap_member(request.context_dict, ref)","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"ad5d4c300d3c756b69cb93be058895c049bcd5c2","unresolved":false,"context_lines":[{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    @controller.protected()"},{"line_number":430,"context_line":"    def get_project_tag(self, request, project_id, value):"},{"line_number":431,"context_line":"        self.resource_api.get_project_tag(project_id, value)"},{"line_number":432,"context_line":""},{"line_number":433,"context_line":"    @controller.protected()"},{"line_number":434,"context_line":"    def delete_project_tag(self, request, project_id, value):"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_29f25e71","line":431,"in_reply_to":"ff346bd7_51c30e39","updated":"2017-07-26 17:03:39.000000000","message":"get_project_tag doesnt actually return a body as per the spec and the nova server tags we benchmarked [0]\n\n0: https://developer.openstack.org/api-ref/compute/?expanded\u003dcheck-tag-existence-detail#add-a-single-tag","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"671a3351dacb3821d9d74abd5ae321bbd9fe429f","unresolved":false,"context_lines":[{"line_number":131,"context_line":"    @controller.protected()"},{"line_number":132,"context_line":"    def create_domain(self, request, domain):"},{"line_number":133,"context_line":"        validation.lazy_validate(schema.domain_create, domain)"},{"line_number":134,"context_line":"        ref \u003d self._assign_unique_id(self._normalize_dict(domain))"},{"line_number":135,"context_line":"        tags \u003d domain.pop(\u0027tags\u0027, [])"},{"line_number":136,"context_line":"        ref \u003d self.resource_api.create_domain("},{"line_number":137,"context_line":"            ref[\u0027id\u0027], ref, initiator\u003drequest.audit_initiator"}],"source_content_type":"text/x-python","patch_set":98,"id":"ff346bd7_776ba21d","line":134,"updated":"2017-07-26 16:27:06.000000000","message":"so, the project manager shoudl return the project representations wiht the tags attribute within it already. so we dont need to do the same thing at all the other places that use project\n\nthis helps for consistency on how we\u0027ve been doing it all over.\n\nnormally we just add \u0027links\u0027 at controller level. the entity already comes fully represented as a dict from managers","commit_id":"d580090cfc3e46765bd571c3430ea4a6dfaee79d"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"6cb1662e2249a083a4071a1079410ec5489ceb9b","unresolved":false,"context_lines":[{"line_number":419,"context_line":"        self.resource_api.create_project_tag("},{"line_number":420,"context_line":"            project_id, value, initiator\u003drequest.audit_initiator)"},{"line_number":421,"context_line":"        r \u003d request.context_dict"},{"line_number":422,"context_line":"        try:"},{"line_number":423,"context_line":"            url \u003d r[\u0027host_url\u0027] + r[\u0027environment\u0027][\u0027REQUEST_URI\u0027]"},{"line_number":424,"context_line":"        except Exception:"},{"line_number":425,"context_line":"            url \u003d r[\u0027path\u0027]"},{"line_number":426,"context_line":"        headers \u003d [(\u0027location\u0027, url)]"},{"line_number":427,"context_line":"        return wsgi.render_response(headers\u003dheaders)"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    @controller.protected()"},{"line_number":430,"context_line":"    def get_project_tag(self, request, project_id, value):"}],"source_content_type":"text/x-python","patch_set":100,"id":"ff346bd7_f06f92f9","line":427,"range":{"start_line":422,"start_character":8,"end_line":427,"end_character":52},"updated":"2017-07-26 21:30:57.000000000","message":"Need to wrap this","commit_id":"c4c9378e5190d857df88ba5f629854de4d02eb5a"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"6cb1662e2249a083a4071a1079410ec5489ceb9b","unresolved":false,"context_lines":[{"line_number":438,"context_line":""},{"line_number":439,"context_line":"    @controller.protected()"},{"line_number":440,"context_line":"    def list_project_tags(self, request, project_id):"},{"line_number":441,"context_line":"        resp \u003d {\u0027tags\u0027: self.resource_api.list_project_tags(project_id)}"},{"line_number":442,"context_line":"        if not resp[\u0027tags\u0027]:"},{"line_number":443,"context_line":"            resp[\u0027tags\u0027] \u003d []"},{"line_number":444,"context_line":"        return resp"},{"line_number":445,"context_line":""},{"line_number":446,"context_line":"    @controller.protected()"},{"line_number":447,"context_line":"    def update_project_tags(self, request, project_id, tags):"}],"source_content_type":"text/x-python","patch_set":100,"id":"ff346bd7_b0758acd","line":444,"range":{"start_line":441,"start_character":8,"end_line":444,"end_character":19},"updated":"2017-07-26 21:30:57.000000000","message":"Same","commit_id":"c4c9378e5190d857df88ba5f629854de4d02eb5a"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"6cb1662e2249a083a4071a1079410ec5489ceb9b","unresolved":false,"context_lines":[{"line_number":445,"context_line":""},{"line_number":446,"context_line":"    @controller.protected()"},{"line_number":447,"context_line":"    def update_project_tags(self, request, project_id, tags):"},{"line_number":448,"context_line":"        validation.lazy_validate(schema.project_tags_update, tags)"},{"line_number":449,"context_line":"        return {\u0027tags\u0027: self.resource_api.update_project_tags("},{"line_number":450,"context_line":"            project_id, tags, initiator\u003drequest.audit_initiator)}"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    @controller.protected()"},{"line_number":453,"context_line":"    def delete_all_project_tags(self, request, project_id):"}],"source_content_type":"text/x-python","patch_set":100,"id":"ff346bd7_d0612e07","line":450,"range":{"start_line":448,"start_character":8,"end_line":450,"end_character":65},"updated":"2017-07-26 21:30:57.000000000","message":"Same","commit_id":"c4c9378e5190d857df88ba5f629854de4d02eb5a"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"02477031177d15cf1e887c91166c3ff3be5321fd","unresolved":false,"context_lines":[{"line_number":324,"context_line":"                tag_set \u003d params[k]"},{"line_number":325,"context_line":"                if self.query_filter_is_true(tag_set):"},{"line_number":326,"context_line":"                    tagged_projects \u003d (getattr(self.resource_api, v)(tag_set))"},{"line_number":327,"context_line":"            else:"},{"line_number":328,"context_line":"                pass"},{"line_number":329,"context_line":"        return tagged_projects"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"    def _expand_project_ref(self, request, ref):"}],"source_content_type":"text/x-python","patch_set":102,"id":"ff346bd7_16120e63","line":328,"range":{"start_line":327,"start_character":12,"end_line":328,"end_character":20},"updated":"2017-07-26 22:06:07.000000000","message":"this can go now i believe.","commit_id":"8c481485b4b99a2d9bcad9d747133d71fc48ef3d"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"79961d6b69d3d80958efa8476992f914efaed49d","unresolved":false,"context_lines":[{"line_number":425,"context_line":""},{"line_number":426,"context_line":"    @classmethod"},{"line_number":427,"context_line":"    def wrap_header(cls, context):"},{"line_number":428,"context_line":"        url \u003d context.get(\u0027path\u0027)"},{"line_number":429,"context_line":"        headers \u003d [(\u0027location\u0027, url)]"},{"line_number":430,"context_line":"        return wsgi.render_response(headers\u003dheaders)"},{"line_number":431,"context_line":""}],"source_content_type":"text/x-python","patch_set":102,"id":"ff346bd7_5691b646","line":428,"range":{"start_line":428,"start_character":7,"end_line":428,"end_character":33},"updated":"2017-07-26 21:39:09.000000000","message":"So about using \u0027path\u0027, this will return something like http://localhost:35357/projects/6c21e83b0646459e81f788cbabf28412/tags/blah\nwithout specifying the api version. its enough to pass tests, but if we want the version in there, we need to do something like r[\u0027host_url\u0027] + r[\u0027environment\u0027][\u0027REQUEST_URI\u0027]. (Which is why i had the try except in the previous create_project_tag","commit_id":"8c481485b4b99a2d9bcad9d747133d71fc48ef3d"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":146,"context_line":"        refs \u003d self.resource_api.list_domains(hints\u003dhints)"},{"line_number":147,"context_line":"        for ref in refs:"},{"line_number":148,"context_line":"            ref[\u0027tags\u0027] \u003d self.resource_api.list_project_tags("},{"line_number":149,"context_line":"                ref[\u0027id\u0027])"},{"line_number":150,"context_line":"        return DomainV3.wrap_collection(request.context_dict,"},{"line_number":151,"context_line":"                                        refs, hints\u003dhints)"},{"line_number":152,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_92ecaa8f","line":149,"updated":"2017-07-27 17:03:58.000000000","message":"It\u0027s possible to use hybrid properties in sql to give you this information in the driver instead of doing it manually here. We do this across the identity backend with the different user types.\n\nWhat you can do is define a hybrid property called tags on the sql driver for projects. When you call project.tags you can tell it to list all tags associated to the project by having it query a separate table [0].\n\nI haven\u0027t benchmarked this approach, but I\u0027d guess that it\u0027s probably more efficient than carrying this logic in python.\n\n[0] https://github.com/openstack/keystone/blob/c3b5d2d77b029880521912e43ad963f9b0c5bf99/keystone/identity/backends/sql_model.py#L71","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"42d91a2c414dd6be203a98fd207c0306bcf0591a","unresolved":false,"context_lines":[{"line_number":146,"context_line":"        refs \u003d self.resource_api.list_domains(hints\u003dhints)"},{"line_number":147,"context_line":"        for ref in refs:"},{"line_number":148,"context_line":"            ref[\u0027tags\u0027] \u003d self.resource_api.list_project_tags("},{"line_number":149,"context_line":"                ref[\u0027id\u0027])"},{"line_number":150,"context_line":"        return DomainV3.wrap_collection(request.context_dict,"},{"line_number":151,"context_line":"                                        refs, hints\u003dhints)"},{"line_number":152,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_c0fc4840","line":149,"in_reply_to":"ff346bd7_92ecaa8f","updated":"2017-07-28 20:23:34.000000000","message":"Thanks for all the feedback. Is this method actually possible for resources though? It doesn\u0027t construct a model the same way Users does.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":282,"context_line":"            raise exception.ValidationError(e)"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"        ref[\u0027tags\u0027] \u003d self.resource_api.update_project_tags("},{"line_number":285,"context_line":"            ref[\u0027id\u0027], tags)"},{"line_number":286,"context_line":"        return ProjectV3.wrap_member(request.context_dict, ref)"},{"line_number":287,"context_line":""},{"line_number":288,"context_line":"    @controller.filterprotected(\u0027domain_id\u0027, \u0027enabled\u0027, \u0027name\u0027,"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_75d25002","line":285,"updated":"2017-07-27 17:03:58.000000000","message":"We\u0027d be able to omit this if we have a hybrid property in the backend. The tags for a project would come back as an attribute automatically.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":309,"context_line":"        return ProjectV3.wrap_collection(request.context_dict,"},{"line_number":310,"context_line":"                                         refs, hints\u003dhints)"},{"line_number":311,"context_line":""},{"line_number":312,"context_line":"    def _expand_project_list(self, request):"},{"line_number":313,"context_line":"        # If one of the filter with tags parameters are found, point to"},{"line_number":314,"context_line":"        # respective logic to proceed with querying"},{"line_number":315,"context_line":"        params \u003d request.params"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_15ee64b3","line":312,"updated":"2017-07-27 17:03:58.000000000","message":"nit: that naming of this method is throwing me off. The name implies that we\u0027re expanding a list of project from IDs or something like that, which doesn\u0027t really seem to be the case. Judging the code, this is more responsible for handling the appropriate filters.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"025c22ba95505c7e691a89b4d2a30e10d664a4cf","unresolved":false,"context_lines":[{"line_number":309,"context_line":"        return ProjectV3.wrap_collection(request.context_dict,"},{"line_number":310,"context_line":"                                         refs, hints\u003dhints)"},{"line_number":311,"context_line":""},{"line_number":312,"context_line":"    def _expand_project_list(self, request):"},{"line_number":313,"context_line":"        # If one of the filter with tags parameters are found, point to"},{"line_number":314,"context_line":"        # respective logic to proceed with querying"},{"line_number":315,"context_line":"        params \u003d request.params"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_05270215","line":312,"in_reply_to":"ff346bd7_15ee64b3","updated":"2017-07-28 19:22:49.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":325,"context_line":"                if self.query_filter_is_true(tag_set):"},{"line_number":326,"context_line":"                    tagged_projects \u003d (getattr(self.resource_api, v)(tag_set))"},{"line_number":327,"context_line":"            else:"},{"line_number":328,"context_line":"                pass"},{"line_number":329,"context_line":"        return tagged_projects"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"    def _expand_project_ref(self, request, ref):"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_754010a6","line":328,"updated":"2017-07-27 17:03:58.000000000","message":"I think lines 327 and 328 can be omitted.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"b915e834347d433809026146863e76be18275908","unresolved":false,"context_lines":[{"line_number":325,"context_line":"                if self.query_filter_is_true(tag_set):"},{"line_number":326,"context_line":"                    tagged_projects \u003d (getattr(self.resource_api, v)(tag_set))"},{"line_number":327,"context_line":"            else:"},{"line_number":328,"context_line":"                pass"},{"line_number":329,"context_line":"        return tagged_projects"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"    def _expand_project_ref(self, request, ref):"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_c06c489e","line":328,"in_reply_to":"ff346bd7_754010a6","updated":"2017-07-28 19:52:51.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":359,"context_line":"                ref[\u0027id\u0027], request.context.user_id)"},{"line_number":360,"context_line":"            for project in parents:"},{"line_number":361,"context_line":"                project[\u0027tags\u0027] \u003d self.resource_api.list_project_tags("},{"line_number":362,"context_line":"                    project[\u0027id\u0027])"},{"line_number":363,"context_line":"            ref[\u0027parents\u0027] \u003d [ProjectV3.wrap_member(context, p)"},{"line_number":364,"context_line":"                              for p in parents]"},{"line_number":365,"context_line":"        elif parents_as_ids:"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_f515209d","line":362,"updated":"2017-07-27 17:03:58.000000000","message":"Same comments here regarding the hybrid property. Ideally - all the changes in this class would effectively be done by the hybrid_property in the backend.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":424,"context_line":"        except Exception:"},{"line_number":425,"context_line":"            url \u003d r[\u0027path\u0027]"},{"line_number":426,"context_line":"        headers \u003d [(\u0027location\u0027, url)]"},{"line_number":427,"context_line":"        return wsgi.render_response(headers\u003dheaders)"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    @controller.protected()"},{"line_number":430,"context_line":"    def get_project_tag(self, request, project_id, value):"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_95481487","line":427,"updated":"2017-07-27 17:03:58.000000000","message":"We typically wrap responses using the wrap_member() method. This comment applies to all methods here.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"025c22ba95505c7e691a89b4d2a30e10d664a4cf","unresolved":false,"context_lines":[{"line_number":424,"context_line":"        except Exception:"},{"line_number":425,"context_line":"            url \u003d r[\u0027path\u0027]"},{"line_number":426,"context_line":"        headers \u003d [(\u0027location\u0027, url)]"},{"line_number":427,"context_line":"        return wsgi.render_response(headers\u003dheaders)"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    @controller.protected()"},{"line_number":430,"context_line":"    def get_project_tag(self, request, project_id, value):"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_450d0a8f","line":427,"in_reply_to":"ff346bd7_95481487","updated":"2017-07-28 19:22:49.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"d194ecde9f5d5b5bf414d75a908dd081268e68d4","unresolved":false,"context_lines":[{"line_number":261,"context_line":"        # project, just by providing a domain_id."},{"line_number":262,"context_line":"        if not ref.get(\u0027parent_id\u0027):"},{"line_number":263,"context_line":"            ref[\u0027parent_id\u0027] \u003d ref.get(\u0027domain_id\u0027)"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"        try:"},{"line_number":266,"context_line":"            ref \u003d self.resource_api.create_project("},{"line_number":267,"context_line":"                ref[\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":112,"id":"bf3e73b7_20b896c6","side":"PARENT","line":264,"updated":"2017-08-07 14:56:55.000000000","message":"Put this back","commit_id":"71cef363810208708df0f467d05f3aeafafecd8b"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"d194ecde9f5d5b5bf414d75a908dd081268e68d4","unresolved":false,"context_lines":[{"line_number":268,"context_line":"                initiator\u003drequest.audit_initiator)"},{"line_number":269,"context_line":"        except (exception.DomainNotFound, exception.ProjectNotFound) as e:"},{"line_number":270,"context_line":"            raise exception.ValidationError(e)"},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"        return ProjectV3.wrap_member(request.context_dict, ref)"},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"    @controller.filterprotected(\u0027domain_id\u0027, \u0027enabled\u0027, \u0027name\u0027,"}],"source_content_type":"text/x-python","patch_set":112,"id":"bf3e73b7_c0b66ada","line":271,"updated":"2017-08-07 14:56:55.000000000","message":"remove this","commit_id":"c40d10f3add8418c9bf644e3bcf8e1a335fc6779"}],"keystone/resource/core.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"8dbe62afb4f52e5da9c8d07c99788933574380c9","unresolved":false,"context_lines":[{"line_number":221,"context_line":"        project_tag \u003d project_tag.copy()"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"        project_tag.setdefault(\u0027enabled\u0027, True)"},{"line_number":224,"context_line":"        project_tag[\u0027name\u0027] \u003d project_tag[\u0027name\u0027].strip()"},{"line_number":225,"context_line":""},{"line_number":226,"context_line":"        project_tag.setdefault(\u0027project_id\u0027, None)"},{"line_number":227,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"5f201791_e89dee66","line":224,"range":{"start_line":224,"start_character":8,"end_line":224,"end_character":57},"updated":"2017-06-20 20:28:20.000000000","message":"We will also need to enforce regex here per the spec[0]. An easier regex to check against would probably be something like:\n\n/\\\\|,/g\n\nwhere that should match anything that is an INVALID tag.\n\nhttps://github.com/openstack/keystone-specs/blob/master/specs/keystone/pike/project-tags.rst#proposed-changes","commit_id":"261144e4376e407c91d641ce1ffc965046fad54c"},{"author":{"_account_id":20466,"name":"Tin Lam","email":"tin@lam.wtf","username":"tinlam"},"change_message_id":"3ae82af927fafea36a1a63a8bcf42e3d2e834540","unresolved":false,"context_lines":[{"line_number":883,"context_line":"        regex \u003d re.search(\u0027\\\\\\\\|\\||\\,|\\/|\\{|\\}|\\^|\\~|\\[|\\]|\\`|\\\u003c|\\\u003e|\\#|\\%\u0027,"},{"line_number":884,"context_line":"                          project_tag[\u0027name\u0027])"},{"line_number":885,"context_line":"        if regex is not None:"},{"line_number":886,"context_line":"            raise exception.Conflict("},{"line_number":887,"context_line":"                type\u003d\u0027project_tag_name\u0027,"},{"line_number":888,"context_line":"                details\u003d\"Tag name cannot contain \u0027\" + regex.group() + \"\u0027.\")"},{"line_number":889,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"5f201791_58f3a174","line":886,"range":{"start_line":886,"start_character":18,"end_line":886,"end_character":36},"updated":"2017-06-28 23:37:53.000000000","message":"This will cause the server to return a 409 Conflict. Should this be a 400 Bad Request if we are trying to store a bad tag.","commit_id":"abfb13e95f45c1f584a976e26766682a80e1912e"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0569481e0f26a37275c25717ba33395bd543f133","unresolved":false,"context_lines":[{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    def _check_limit(self, project_id):"},{"line_number":60,"context_line":"        current_tags \u003d self.driver.list_project_tags(project_id)"},{"line_number":61,"context_line":"        if len(current_tags) \u003e 50:"},{"line_number":62,"context_line":"                raise exception.InvalidError("},{"line_number":63,"context_line":"                    attribute\u003d\"number of tags (max 50)\","},{"line_number":64,"context_line":"                    target\u003d\"project \" + project_id)"}],"source_content_type":"text/x-python","patch_set":25,"id":"3f1d235d_65eaf4ac","line":61,"range":{"start_line":61,"start_character":31,"end_line":61,"end_character":33},"updated":"2017-06-30 21:16:02.000000000","message":"We should probably put this value up top as a global constant, maybe something like \"MAX_PROJECT_TAG_COUNT\".","commit_id":"89f2063bd5e86457df783ffa06478bc4d1de2e72"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0569481e0f26a37275c25717ba33395bd543f133","unresolved":false,"context_lines":[{"line_number":59,"context_line":"    def _check_limit(self, project_id):"},{"line_number":60,"context_line":"        current_tags \u003d self.driver.list_project_tags(project_id)"},{"line_number":61,"context_line":"        if len(current_tags) \u003e 50:"},{"line_number":62,"context_line":"                raise exception.InvalidError("},{"line_number":63,"context_line":"                    attribute\u003d\"number of tags (max 50)\","},{"line_number":64,"context_line":"                    target\u003d\"project \" + project_id)"},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"3f1d235d_0577c004","line":62,"range":{"start_line":62,"start_character":32,"end_line":62,"end_character":44},"updated":"2017-06-30 21:16:02.000000000","message":"We don\u0027t really need this new exception, we could use the existing \"ValidationError\" and change the attribute below to something like \"no more than %d tags\" % MAX_PROJECT_TAG_COUNT","commit_id":"89f2063bd5e86457df783ffa06478bc4d1de2e72"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0569481e0f26a37275c25717ba33395bd543f133","unresolved":false,"context_lines":[{"line_number":889,"context_line":""},{"line_number":890,"context_line":"        project_tag[\u0027name\u0027] \u003d project_tag[\u0027name\u0027].strip()"},{"line_number":891,"context_line":""},{"line_number":892,"context_line":"        regex \u003d re.search(\u0027\\\\\\\\|\\||\\,|\\/|\\{|\\}|\\^|\\~|\\[|\\]|\\`|\\\u003c|\\\u003e|\\#|\\%\u0027,"},{"line_number":893,"context_line":"                          project_tag[\u0027name\u0027])"},{"line_number":894,"context_line":"        if regex is not None:"},{"line_number":895,"context_line":"            raise exception.InvalidError("}],"source_content_type":"text/x-python","patch_set":25,"id":"3f1d235d_25d63cc5","line":892,"range":{"start_line":892,"start_character":27,"end_line":892,"end_character":73},"updated":"2017-06-30 21:16:02.000000000","message":"This might not be really 100% URL safe, it would be better to go with the invalid regex example:\n\n/\\\\|,/g","commit_id":"89f2063bd5e86457df783ffa06478bc4d1de2e72"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0569481e0f26a37275c25717ba33395bd543f133","unresolved":false,"context_lines":[{"line_number":893,"context_line":"                          project_tag[\u0027name\u0027])"},{"line_number":894,"context_line":"        if regex is not None:"},{"line_number":895,"context_line":"            raise exception.InvalidError("},{"line_number":896,"context_line":"                attribute\u003dregex.group(),"},{"line_number":897,"context_line":"                target\u003d\"tag name: \" + project_tag[\u0027name\u0027])"},{"line_number":898,"context_line":""},{"line_number":899,"context_line":"        project_tag_id \u003d project_tag[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":25,"id":"3f1d235d_05fea036","line":896,"range":{"start_line":896,"start_character":26,"end_line":896,"end_character":39},"updated":"2017-06-30 21:16:02.000000000","message":"nit: replace with something like \"project tags containing URL safe characters\"","commit_id":"89f2063bd5e86457df783ffa06478bc4d1de2e72"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"aa6b218b4d88ef513ec9b0ad6421269c89484fd3","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        resource_driver \u003d CONF.resource.driver"},{"line_number":58,"context_line":"        super(Manager, self).__init__(resource_driver)"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def _check_limit(self, project_id):"},{"line_number":61,"context_line":"        current_tags \u003d self.driver.list_project_tags(project_id)"},{"line_number":62,"context_line":"        if len(current_tags) \u003e MAX_PROJECT_TAG_COUNT:"},{"line_number":63,"context_line":"            raise exception.ValidationError("}],"source_content_type":"text/x-python","patch_set":29,"id":"3f1d235d_b8600303","line":60,"range":{"start_line":60,"start_character":8,"end_line":60,"end_character":20},"updated":"2017-07-03 21:15:09.000000000","message":"also, this doesn\u0027t check the character limit. And its not a part of the create_tags below.","commit_id":"8c6f78ab8018f45883238a9668d3f8d422c7cb4d"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"39b0d2f168c767b4d02a33058e01221ddbb8464c","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        current_tags \u003d self.driver.list_project_tags(project_id)"},{"line_number":62,"context_line":"        if len(current_tags) \u003e MAX_PROJECT_TAG_COUNT:"},{"line_number":63,"context_line":"            raise exception.ValidationError("},{"line_number":64,"context_line":"                attribute\u003d\"fewer than %d\" % MAX_PROJECT_TAG_COUNT,"},{"line_number":65,"context_line":"                target\u003d\"project \" + project_id)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    def _get_hierarchy_depth(self, parents_list):"}],"source_content_type":"text/x-python","patch_set":29,"id":"3f1d235d_320652d0","line":64,"range":{"start_line":64,"start_character":27,"end_line":64,"end_character":40},"updated":"2017-07-03 19:31:33.000000000","message":"We should change this to \"%d or fewer\" so we avoid any confusion, this currently sounds like you can only have 49 tags per project.","commit_id":"8c6f78ab8018f45883238a9668d3f8d422c7cb4d"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"b51bdb19a2f8513f7150b0b0483bcb4c8bdf3721","unresolved":false,"context_lines":[{"line_number":33,"context_line":"CONF \u003d keystone.conf.CONF"},{"line_number":34,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":35,"context_line":"MEMOIZE \u003d cache.get_memoization_decorator(group\u003d\u0027resource\u0027)"},{"line_number":36,"context_line":"MAX_PROJECT_TAG_COUNT \u003d 50"},{"line_number":37,"context_line":"MAX_PROJECT_TAG_NAME_LENGTH \u003d 60"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"@dependency.provider(\u0027resource_api\u0027)"}],"source_content_type":"text/x-python","patch_set":39,"id":"3f1d235d_07ffcf67","line":37,"range":{"start_line":36,"start_character":0,"end_line":37,"end_character":32},"updated":"2017-07-10 16:54:24.000000000","message":"Move out to schema validation","commit_id":"b722f77c2a5ba206ee91e15bd3083b281c097f4d"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"b51bdb19a2f8513f7150b0b0483bcb4c8bdf3721","unresolved":false,"context_lines":[{"line_number":58,"context_line":"        resource_driver \u003d CONF.resource.driver"},{"line_number":59,"context_line":"        super(Manager, self).__init__(resource_driver)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    def _check_limit(self, project_id, name):"},{"line_number":62,"context_line":"        current_tags \u003d self.driver.list_project_tags(project_id)"},{"line_number":63,"context_line":"        if len(current_tags) \u003e MAX_PROJECT_TAG_COUNT:"},{"line_number":64,"context_line":"            raise exception.ValidationError("},{"line_number":65,"context_line":"                attribute\u003d\"fewer than %d\" % MAX_PROJECT_TAG_COUNT,"},{"line_number":66,"context_line":"                target\u003d\"project \" + project_id)"},{"line_number":67,"context_line":"        if len(name) \u003e MAX_PROJECT_TAG_NAME_LENGTH:"},{"line_number":68,"context_line":"            raise exception.ValidationError("},{"line_number":69,"context_line":"                attribute\u003d\"fewer than %d\" % MAX_PROJECT_TAG_NAME_LENGTH,"},{"line_number":70,"context_line":"                target\u003d\"project \" + project_id)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def _get_hierarchy_depth(self, parents_list):"},{"line_number":73,"context_line":"        return len(parents_list) + 1"}],"source_content_type":"text/x-python","patch_set":39,"id":"3f1d235d_c7f797d4","line":70,"range":{"start_line":61,"start_character":0,"end_line":70,"end_character":47},"updated":"2017-07-10 16:54:24.000000000","message":"We can move this out to JSON schema validation\n\nhttps://spacetelescope.github.io/understanding-json-schema/index.html","commit_id":"b722f77c2a5ba206ee91e15bd3083b281c097f4d"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"3c3f3bbade17fba48126c3e28e091cb1db17d70d","unresolved":false,"context_lines":[{"line_number":58,"context_line":"        resource_driver \u003d CONF.resource.driver"},{"line_number":59,"context_line":"        super(Manager, self).__init__(resource_driver)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    def _check_limit(self, project_id, name):"},{"line_number":62,"context_line":"        current_tags \u003d self.driver.list_project_tags(project_id)"},{"line_number":63,"context_line":"        if len(current_tags) \u003e MAX_PROJECT_TAG_COUNT:"},{"line_number":64,"context_line":"            raise exception.ValidationError("},{"line_number":65,"context_line":"                attribute\u003d\"fewer than %d\" % MAX_PROJECT_TAG_COUNT,"},{"line_number":66,"context_line":"                target\u003d\"project \" + project_id)"},{"line_number":67,"context_line":"        if len(name) \u003e MAX_PROJECT_TAG_NAME_LENGTH:"},{"line_number":68,"context_line":"            raise exception.ValidationError("},{"line_number":69,"context_line":"                attribute\u003d\"fewer than %d\" % MAX_PROJECT_TAG_NAME_LENGTH,"},{"line_number":70,"context_line":"                target\u003d\"project \" + project_id)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def _get_hierarchy_depth(self, parents_list):"},{"line_number":73,"context_line":"        return len(parents_list) + 1"}],"source_content_type":"text/x-python","patch_set":39,"id":"3f1d235d_e5704bdf","line":70,"range":{"start_line":61,"start_character":0,"end_line":70,"end_character":47},"in_reply_to":"3f1d235d_2a1852d1","updated":"2017-07-10 18:17:12.000000000","message":"yup!","commit_id":"b722f77c2a5ba206ee91e15bd3083b281c097f4d"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"b3da638ef358939417ba8fce6843f40a85c474ef","unresolved":false,"context_lines":[{"line_number":58,"context_line":"        resource_driver \u003d CONF.resource.driver"},{"line_number":59,"context_line":"        super(Manager, self).__init__(resource_driver)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    def _check_limit(self, project_id, name):"},{"line_number":62,"context_line":"        current_tags \u003d self.driver.list_project_tags(project_id)"},{"line_number":63,"context_line":"        if len(current_tags) \u003e MAX_PROJECT_TAG_COUNT:"},{"line_number":64,"context_line":"            raise exception.ValidationError("},{"line_number":65,"context_line":"                attribute\u003d\"fewer than %d\" % MAX_PROJECT_TAG_COUNT,"},{"line_number":66,"context_line":"                target\u003d\"project \" + project_id)"},{"line_number":67,"context_line":"        if len(name) \u003e MAX_PROJECT_TAG_NAME_LENGTH:"},{"line_number":68,"context_line":"            raise exception.ValidationError("},{"line_number":69,"context_line":"                attribute\u003d\"fewer than %d\" % MAX_PROJECT_TAG_NAME_LENGTH,"},{"line_number":70,"context_line":"                target\u003d\"project \" + project_id)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def _get_hierarchy_depth(self, parents_list):"},{"line_number":73,"context_line":"        return len(parents_list) + 1"}],"source_content_type":"text/x-python","patch_set":39,"id":"3f1d235d_2a1852d1","line":70,"range":{"start_line":61,"start_character":0,"end_line":70,"end_character":47},"in_reply_to":"3f1d235d_c7f797d4","updated":"2017-07-10 17:23:20.000000000","message":"so you mean validate at the controller level with lazy_validate and add to the schema right?","commit_id":"b722f77c2a5ba206ee91e15bd3083b281c097f4d"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"b51bdb19a2f8513f7150b0b0483bcb4c8bdf3721","unresolved":false,"context_lines":[{"line_number":938,"context_line":"    def _create_project_tags_with_presets(self, project_id, project_name):"},{"line_number":939,"context_line":"        return []"},{"line_number":940,"context_line":""},{"line_number":941,"context_line":"    def update_project_tags(self, project_id, project_tags):"},{"line_number":942,"context_line":"        # project \u003d self.driver.get_project(project_id)"},{"line_number":943,"context_line":"        self.driver.remove_all_project_tags(project_id)"},{"line_number":944,"context_line":"        # Note(aselius): Need a method which will change the name"}],"source_content_type":"text/x-python","patch_set":39,"id":"3f1d235d_c7f8b77d","line":941,"range":{"start_line":941,"start_character":8,"end_line":941,"end_character":27},"updated":"2017-07-10 16:54:24.000000000","message":"need schema validation here","commit_id":"b722f77c2a5ba206ee91e15bd3083b281c097f4d"},{"author":{"_account_id":26325,"name":"Omar Tleimat","email":"otleimat@ucla.edu","username":"otleimat"},"change_message_id":"1f650b0079915bcc16d8a1bb39cc5a8ab2b06265","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def _check_limit(self, project_id, name):"},{"line_number":61,"context_line":"        current_tags \u003d self.driver.list_project_tags(project_id)"},{"line_number":62,"context_line":"        if len(current_tags) \u003e MAX_PROJECT_TAG_COUNT:"},{"line_number":63,"context_line":"            raise exception.ValidationError("},{"line_number":64,"context_line":"                attribute\u003d\"fewer than %d\" % MAX_PROJECT_TAG_COUNT,"},{"line_number":65,"context_line":"                target\u003d\"project \" + project_id)"}],"source_content_type":"text/x-python","patch_set":44,"id":"1f1a1f67_1e3cb1bd","line":62,"range":{"start_line":62,"start_character":28,"end_line":62,"end_character":30},"updated":"2017-07-13 17:11:41.000000000","message":"I think this should be greater than and equal to, because check limit is called at the beginning of create project tags, even if it were the 51st tag, it wouldn\u0027t get caught because 50 ! greater than 50. It would get caught the next time around at the 52nd tag.","commit_id":"482ced2116ce0971985e077819609465302f3a81"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"349f8b067a5fca5a93036817cd53fb241eed75c4","unresolved":false,"context_lines":[{"line_number":32,"context_line":"CONF \u003d keystone.conf.CONF"},{"line_number":33,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":34,"context_line":"MEMOIZE \u003d cache.get_memoization_decorator(group\u003d\u0027resource\u0027)"},{"line_number":35,"context_line":"MAX_PROJECT_TAG_COUNT \u003d 50"},{"line_number":36,"context_line":"MAX_PROJECT_TAG_NAME_LENGTH \u003d 60"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"@dependency.provider(\u0027resource_api\u0027)"}],"source_content_type":"text/x-python","patch_set":57,"id":"1f1a1f67_f01f8205","line":36,"range":{"start_line":35,"start_character":0,"end_line":36,"end_character":32},"updated":"2017-07-17 21:13:18.000000000","message":"Since we are validating via schema, we can remove these","commit_id":"2adb32f9e52c4bbf69e1640789f654ee703c1ad2"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"8ee1ab72f34e72c0dd56342b967854d0969270e9","unresolved":false,"context_lines":[{"line_number":32,"context_line":"CONF \u003d keystone.conf.CONF"},{"line_number":33,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":34,"context_line":"MEMOIZE \u003d cache.get_memoization_decorator(group\u003d\u0027resource\u0027)"},{"line_number":35,"context_line":"MAX_PROJECT_TAG_COUNT \u003d 50"},{"line_number":36,"context_line":"MAX_PROJECT_TAG_NAME_LENGTH \u003d 60"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"@dependency.provider(\u0027resource_api\u0027)"}],"source_content_type":"text/x-python","patch_set":57,"id":"1f1a1f67_361052a8","line":36,"range":{"start_line":35,"start_character":0,"end_line":36,"end_character":32},"in_reply_to":"1f1a1f67_10cd5e65","updated":"2017-07-17 22:41:29.000000000","message":"Well, we can remove the name length. For tag updating, we can leave the count value here","commit_id":"2adb32f9e52c4bbf69e1640789f654ee703c1ad2"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"9154b612f51e3275a7039f684446bfd9744a5bec","unresolved":false,"context_lines":[{"line_number":32,"context_line":"CONF \u003d keystone.conf.CONF"},{"line_number":33,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":34,"context_line":"MEMOIZE \u003d cache.get_memoization_decorator(group\u003d\u0027resource\u0027)"},{"line_number":35,"context_line":"MAX_PROJECT_TAG_COUNT \u003d 50"},{"line_number":36,"context_line":"MAX_PROJECT_TAG_NAME_LENGTH \u003d 60"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"@dependency.provider(\u0027resource_api\u0027)"}],"source_content_type":"text/x-python","patch_set":57,"id":"1f1a1f67_10cd5e65","line":36,"range":{"start_line":35,"start_character":0,"end_line":36,"end_character":32},"in_reply_to":"1f1a1f67_f01f8205","updated":"2017-07-17 21:18:54.000000000","message":"How are we validating in the schema? There is no way to have the schema check with the sql to see if there are too many tags","commit_id":"2adb32f9e52c4bbf69e1640789f654ee703c1ad2"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"349f8b067a5fca5a93036817cd53fb241eed75c4","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    def __init__(self):"},{"line_number":57,"context_line":"        resource_driver \u003d CONF.resource.driver"},{"line_number":58,"context_line":"        super(Manager, self).__init__(resource_driver)"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def _check_limit(self, project_id, name):"},{"line_number":61,"context_line":"        current_tags \u003d self.driver.list_project_tags(project_id)"},{"line_number":62,"context_line":"        if len(current_tags) \u003e\u003d MAX_PROJECT_TAG_COUNT:"},{"line_number":63,"context_line":"            raise exception.ValidationError("},{"line_number":64,"context_line":"                attribute\u003d\"fewer than %d\" % MAX_PROJECT_TAG_COUNT,"},{"line_number":65,"context_line":"                target\u003d\"project \" + project_id)"},{"line_number":66,"context_line":"        if len(name) \u003e MAX_PROJECT_TAG_NAME_LENGTH:"},{"line_number":67,"context_line":"            raise exception.ValidationError("},{"line_number":68,"context_line":"                attribute\u003d\"fewer than %d\" % MAX_PROJECT_TAG_NAME_LENGTH,"},{"line_number":69,"context_line":"                target\u003d\"project \" + project_id)"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    def _get_hierarchy_depth(self, parents_list):"},{"line_number":72,"context_line":"        return len(parents_list) + 1"}],"source_content_type":"text/x-python","patch_set":57,"id":"1f1a1f67_b0158ae7","line":69,"range":{"start_line":59,"start_character":0,"end_line":69,"end_character":47},"updated":"2017-07-17 21:13:18.000000000","message":"Can remove this as well","commit_id":"2adb32f9e52c4bbf69e1640789f654ee703c1ad2"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"349f8b067a5fca5a93036817cd53fb241eed75c4","unresolved":false,"context_lines":[{"line_number":920,"context_line":"        # project exception"},{"line_number":921,"context_line":"        project_tag \u003d project_tag.copy()"},{"line_number":922,"context_line":"        # TODO(aselius): Evaluate if the regex is actually url safe"},{"line_number":923,"context_line":"        if (utils.is_not_url_safe(project_tag[\u0027name\u0027])):"},{"line_number":924,"context_line":"            self._raise_reserved_character_exception("},{"line_number":925,"context_line":"                \u0027Project Tag\u0027, project_tag[\u0027name\u0027])"},{"line_number":926,"context_line":"        project_tag.setdefault(\u0027project_id\u0027, None)"},{"line_number":927,"context_line":"        try:"},{"line_number":928,"context_line":"            ret \u003d self.driver.create_project_tag(project_tag)"}],"source_content_type":"text/x-python","patch_set":57,"id":"1f1a1f67_d0eda6f0","line":925,"range":{"start_line":923,"start_character":0,"end_line":925,"end_character":51},"updated":"2017-07-17 21:13:18.000000000","message":"We can maybe keep this, this looks like it could be useful for url-safe checking.","commit_id":"2adb32f9e52c4bbf69e1640789f654ee703c1ad2"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"8ee1ab72f34e72c0dd56342b967854d0969270e9","unresolved":false,"context_lines":[{"line_number":962,"context_line":"    def _create_project_tags_with_presets(self, project_id, project_name):"},{"line_number":963,"context_line":"        return []"},{"line_number":964,"context_line":""},{"line_number":965,"context_line":"    def update_project_tags(self, project_id, values, initiator\u003dNone):"},{"line_number":966,"context_line":"        \"\"\"Update project tags calls a combination of other core functions.\"\"\""},{"line_number":967,"context_line":"        # Note(nhelgeson): Update project tags uses the code for"},{"line_number":968,"context_line":"        # remove_all_project_tags, create_project_tag and get_project"}],"source_content_type":"text/x-python","patch_set":57,"id":"1f1a1f67_166e762e","line":965,"range":{"start_line":965,"start_character":8,"end_line":965,"end_character":28},"updated":"2017-07-17 22:41:29.000000000","message":"https://github.com/openstack/nova/blob/9dde4fe0eacc01c135401da3313c493caa99a30c/nova/api/openstack/compute/server_tags.py#L105-L152","commit_id":"2adb32f9e52c4bbf69e1640789f654ee703c1ad2"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"f3f0e64484c949955a25b296a724f1ed00499771","unresolved":false,"context_lines":[{"line_number":922,"context_line":"        project_tag \u003d {}"},{"line_number":923,"context_line":"        project_tag[\u0027project_id\u0027] \u003d project_id"},{"line_number":924,"context_line":"        project_tag[\u0027name\u0027] \u003d value.strip()"},{"line_number":925,"context_line":"        project_tag[\u0027id\u0027] \u003d uuid.uuid4().hex"},{"line_number":926,"context_line":"        try:"},{"line_number":927,"context_line":"            ret \u003d self.driver.create_project_tag(project_tag)"},{"line_number":928,"context_line":"        except exception.Conflict:"}],"source_content_type":"text/x-python","patch_set":64,"id":"1f1a1f67_35eb5a78","line":925,"range":{"start_line":925,"start_character":8,"end_line":925,"end_character":44},"updated":"2017-07-19 18:48:21.000000000","message":"We need to fix this as well, we should be able to just insert the name/project_id","commit_id":"c2b03ccedf2fa5a97b6c05fcfb4979ede4b6bfd7"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"448b93e34bff8f0bff63fa17a87d7db70168f361","unresolved":false,"context_lines":[{"line_number":922,"context_line":"        project_tag \u003d {}"},{"line_number":923,"context_line":"        project_tag[\u0027project_id\u0027] \u003d project_id"},{"line_number":924,"context_line":"        project_tag[\u0027name\u0027] \u003d value.strip()"},{"line_number":925,"context_line":"        project_tag[\u0027id\u0027] \u003d uuid.uuid4().hex"},{"line_number":926,"context_line":"        try:"},{"line_number":927,"context_line":"            ret \u003d self.driver.create_project_tag(project_tag)"},{"line_number":928,"context_line":"        except exception.Conflict:"}],"source_content_type":"text/x-python","patch_set":64,"id":"1f1a1f67_95658e20","line":925,"range":{"start_line":925,"start_character":8,"end_line":925,"end_character":44},"in_reply_to":"1f1a1f67_35eb5a78","updated":"2017-07-19 18:49:20.000000000","message":"yup agreed.","commit_id":"c2b03ccedf2fa5a97b6c05fcfb4979ede4b6bfd7"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0ef62e249123fc127dc0104f0276cdc514628c63","unresolved":false,"context_lines":[{"line_number":504,"context_line":"            ret \u003d self.driver.delete_projects_from_ids(projects_ids)"},{"line_number":505,"context_line":"            for prj in project_list:"},{"line_number":506,"context_line":"                self._post_delete_cleanup_project(prj[\u0027id\u0027], prj, initiator)"},{"line_number":507,"context_line":"            self.remove_all_project_tags(project_id)"},{"line_number":508,"context_line":"        else:"},{"line_number":509,"context_line":"            self._pre_delete_cleanup_project(project_id)"},{"line_number":510,"context_line":"            ret \u003d self.driver.delete_project(project_id)"}],"source_content_type":"text/x-python","patch_set":66,"id":"1f1a1f67_20f435f0","line":507,"range":{"start_line":507,"start_character":11,"end_line":507,"end_character":52},"updated":"2017-07-19 22:18:16.000000000","message":"This actually breaks a lot of the tests, since by this point the project is deleted and the project_id will point to a non-existing project.","commit_id":"f4364059d700b1812e5c8c2bbc6a8b985b3de887"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"f60bf33587bae3bd8bb360a9c7efc0df33ebcfae","unresolved":false,"context_lines":[{"line_number":504,"context_line":"            ret \u003d self.driver.delete_projects_from_ids(projects_ids)"},{"line_number":505,"context_line":"            for prj in project_list:"},{"line_number":506,"context_line":"                self._post_delete_cleanup_project(prj[\u0027id\u0027], prj, initiator)"},{"line_number":507,"context_line":"            self.remove_all_project_tags(project_id)"},{"line_number":508,"context_line":"        else:"},{"line_number":509,"context_line":"            self._pre_delete_cleanup_project(project_id)"},{"line_number":510,"context_line":"            ret \u003d self.driver.delete_project(project_id)"}],"source_content_type":"text/x-python","patch_set":67,"id":"1f1a1f67_c01fc1b4","line":507,"range":{"start_line":507,"start_character":17,"end_line":507,"end_character":40},"updated":"2017-07-19 22:40:33.000000000","message":"this should be fine for sanity (and getting the tests to pass purposes) but technically this should happen automatically with sqlA but we can leave it for now","commit_id":"a8e9146661b373c9a5661a07f338717bd2834166"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"6d3f10631caf8360e218182a28c052e22d1363b4","unresolved":false,"context_lines":[{"line_number":941,"context_line":"    def list_project_tags(self, project_id):"},{"line_number":942,"context_line":"        \"\"\"List all tags on project.\"\"\""},{"line_number":943,"context_line":"        self._check_project_exists(project_id)"},{"line_number":944,"context_line":"        return self.driver.list_project_tags(project_id)"},{"line_number":945,"context_line":""},{"line_number":946,"context_line":"    def delete_project_tag(self, project_id, project_tag_name):"},{"line_number":947,"context_line":"        \"\"\"Delete single tag from project.\"\"\""}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_71c42193","line":944,"range":{"start_line":944,"start_character":8,"end_line":944,"end_character":14},"updated":"2017-07-20 16:32:12.000000000","message":"we put a wrapper here so that it would enclose it in a dict with k, v with k \u003d \u0027tags\u0027, but since that was taken out the response is now a list","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"41e1af629ab834a905ba52f99e99e422307356ac","unresolved":false,"context_lines":[{"line_number":941,"context_line":"    def list_project_tags(self, project_id):"},{"line_number":942,"context_line":"        \"\"\"List all tags on project.\"\"\""},{"line_number":943,"context_line":"        self._check_project_exists(project_id)"},{"line_number":944,"context_line":"        return self.driver.list_project_tags(project_id)"},{"line_number":945,"context_line":""},{"line_number":946,"context_line":"    def delete_project_tag(self, project_id, project_tag_name):"},{"line_number":947,"context_line":"        \"\"\"Delete single tag from project.\"\"\""}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_f1bcb16d","line":944,"range":{"start_line":944,"start_character":8,"end_line":944,"end_character":14},"in_reply_to":"1f1a1f67_71c42193","updated":"2017-07-20 16:38:34.000000000","message":"There was the issue though with it being:\n\n{ \"tags\": \"tags\": []}}\n\nBut you\u0027re right in that we need it to be a single dict.","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"28b46f86821247d3c9bdd77be6d3614925abb7ae","unresolved":false,"context_lines":[{"line_number":884,"context_line":"            if new_ref[\u0027domain_id\u0027] !\u003d orig_ref[\u0027domain_id\u0027]:"},{"line_number":885,"context_line":"                raise exception.ValidationError(_(\u0027Cannot change Domain ID\u0027))"},{"line_number":886,"context_line":""},{"line_number":887,"context_line":"    def _check_project_exists(self, project_id):"},{"line_number":888,"context_line":"        try:"},{"line_number":889,"context_line":"            self.driver.get_project(project_id)"},{"line_number":890,"context_line":"        except exception.ProjectNotFound:"}],"source_content_type":"text/x-python","patch_set":80,"id":"ff346bd7_3f042915","line":887,"updated":"2017-07-24 15:39:36.000000000","message":"what\u0027s the rationale to have a separate controller but not a separate manager for proejct tags?","commit_id":"0d9df4582a608cd63a192640a48055c64fd0c7e9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"4eb38d17378cda3d3adaede82d624baedc1dc031","unresolved":false,"context_lines":[{"line_number":884,"context_line":"            if new_ref[\u0027domain_id\u0027] !\u003d orig_ref[\u0027domain_id\u0027]:"},{"line_number":885,"context_line":"                raise exception.ValidationError(_(\u0027Cannot change Domain ID\u0027))"},{"line_number":886,"context_line":""},{"line_number":887,"context_line":"    def _check_project_exists(self, project_id):"},{"line_number":888,"context_line":"        try:"},{"line_number":889,"context_line":"            self.driver.get_project(project_id)"},{"line_number":890,"context_line":"        except exception.ProjectNotFound:"}],"source_content_type":"text/x-python","patch_set":80,"id":"ff346bd7_df763dd9","line":887,"in_reply_to":"ff346bd7_3f042915","updated":"2017-07-24 16:10:44.000000000","message":"i think the reason why we did this was because tags are a property of projects, but are still separate entities and collections (benchmarked domains vs projects)","commit_id":"0d9df4582a608cd63a192640a48055c64fd0c7e9"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0be3de8db5712fa43c035b2cffc5db126527c1f5","unresolved":false,"context_lines":[{"line_number":217,"context_line":"                type\u003d\u0027project\u0027,"},{"line_number":218,"context_line":"                details\u003dself._generate_project_name_conflict_msg(project))"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"        for tag in tags:"},{"line_number":221,"context_line":"            tag_ref \u003d {\u0027project_id\u0027: project_id,"},{"line_number":222,"context_line":"                       \u0027name\u0027: tag}"},{"line_number":223,"context_line":"            self.driver.create_project_tag(tag_ref)"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"        if project.get(\u0027is_domain\u0027):"},{"line_number":226,"context_line":"            notifications.Audit.created(self._DOMAIN, project_id, initiator)"}],"source_content_type":"text/x-python","patch_set":84,"id":"ff346bd7_399b1eca","line":223,"range":{"start_line":220,"start_character":0,"end_line":223,"end_character":51},"updated":"2017-07-24 20:40:40.000000000","message":"Could just do an update here instead of create","commit_id":"937436495525be7f74d3ef4e69820c601bb2deab"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"811f74a7cbc9553f7fec788fa3e9dbae3e41571a","unresolved":false,"context_lines":[{"line_number":888,"context_line":"            if new_ref[\u0027domain_id\u0027] !\u003d orig_ref[\u0027domain_id\u0027]:"},{"line_number":889,"context_line":"                raise exception.ValidationError(_(\u0027Cannot change Domain ID\u0027))"},{"line_number":890,"context_line":""},{"line_number":891,"context_line":"    def _check_project_exists(self, project_id):"},{"line_number":892,"context_line":"        try:"},{"line_number":893,"context_line":"            self.driver.get_project(project_id)"},{"line_number":894,"context_line":"        except exception.ProjectNotFound:"},{"line_number":895,"context_line":"            raise exception.ProjectNotFound(project_id\u003dproject_id)"},{"line_number":896,"context_line":""},{"line_number":897,"context_line":"    def list_projects_with_tags(self, tag_names):"},{"line_number":898,"context_line":"        \"\"\"Filter projects that contain all provided tags.\"\"\""}],"source_content_type":"text/x-python","patch_set":91,"id":"ff346bd7_52d57e42","line":895,"range":{"start_line":891,"start_character":0,"end_line":895,"end_character":66},"updated":"2017-07-25 13:32:38.000000000","message":"this is basically doing nothing. what is the difference of just calling self.driver.get_project in this method\u0027s caller","commit_id":"3031b3af1695370db5e121ab6e1ececd9d3840df"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"7145c26e02c3abf620bdb493ea93aedbb9ba0000","unresolved":false,"context_lines":[{"line_number":888,"context_line":"            if new_ref[\u0027domain_id\u0027] !\u003d orig_ref[\u0027domain_id\u0027]:"},{"line_number":889,"context_line":"                raise exception.ValidationError(_(\u0027Cannot change Domain ID\u0027))"},{"line_number":890,"context_line":""},{"line_number":891,"context_line":"    def _check_project_exists(self, project_id):"},{"line_number":892,"context_line":"        try:"},{"line_number":893,"context_line":"            self.driver.get_project(project_id)"},{"line_number":894,"context_line":"        except exception.ProjectNotFound:"},{"line_number":895,"context_line":"            raise exception.ProjectNotFound(project_id\u003dproject_id)"},{"line_number":896,"context_line":""},{"line_number":897,"context_line":"    def list_projects_with_tags(self, tag_names):"},{"line_number":898,"context_line":"        \"\"\"Filter projects that contain all provided tags.\"\"\""}],"source_content_type":"text/x-python","patch_set":91,"id":"ff346bd7_c9953942","line":895,"range":{"start_line":891,"start_character":0,"end_line":895,"end_character":66},"in_reply_to":"ff346bd7_52d57e42","updated":"2017-07-25 18:29:34.000000000","message":"good point","commit_id":"3031b3af1695370db5e121ab6e1ececd9d3840df"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"dd94f48a5e812d9109530e263f4b3490491a648b","unresolved":false,"context_lines":[{"line_number":888,"context_line":"            if new_ref[\u0027domain_id\u0027] !\u003d orig_ref[\u0027domain_id\u0027]:"},{"line_number":889,"context_line":"                raise exception.ValidationError(_(\u0027Cannot change Domain ID\u0027))"},{"line_number":890,"context_line":""},{"line_number":891,"context_line":"    def _check_project_exists(self, project_id):"},{"line_number":892,"context_line":"        try:"},{"line_number":893,"context_line":"            self.driver.get_project(project_id)"},{"line_number":894,"context_line":"        except exception.ProjectNotFound:"},{"line_number":895,"context_line":"            raise exception.ProjectNotFound(project_id\u003dproject_id)"},{"line_number":896,"context_line":""},{"line_number":897,"context_line":"    def list_projects_with_tags(self, tag_names):"},{"line_number":898,"context_line":"        \"\"\"Filter projects that contain all provided tags.\"\"\""}],"source_content_type":"text/x-python","patch_set":100,"id":"ff346bd7_961a7e6c","line":895,"range":{"start_line":891,"start_character":0,"end_line":895,"end_character":66},"updated":"2017-07-26 21:26:55.000000000","message":"This can go...","commit_id":"c4c9378e5190d857df88ba5f629854de4d02eb5a"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"6cb1662e2249a083a4071a1079410ec5489ceb9b","unresolved":false,"context_lines":[{"line_number":888,"context_line":"            if new_ref[\u0027domain_id\u0027] !\u003d orig_ref[\u0027domain_id\u0027]:"},{"line_number":889,"context_line":"                raise exception.ValidationError(_(\u0027Cannot change Domain ID\u0027))"},{"line_number":890,"context_line":""},{"line_number":891,"context_line":"    def _check_project_exists(self, project_id):"},{"line_number":892,"context_line":"        try:"},{"line_number":893,"context_line":"            self.driver.get_project(project_id)"},{"line_number":894,"context_line":"        except exception.ProjectNotFound:"},{"line_number":895,"context_line":"            raise exception.ProjectNotFound(project_id\u003dproject_id)"},{"line_number":896,"context_line":""},{"line_number":897,"context_line":"    def list_projects_with_tags(self, tag_names):"},{"line_number":898,"context_line":"        \"\"\"Filter projects that contain all provided tags.\"\"\""}],"source_content_type":"text/x-python","patch_set":100,"id":"ff346bd7_b6c46292","line":895,"range":{"start_line":891,"start_character":0,"end_line":895,"end_character":66},"in_reply_to":"ff346bd7_961a7e6c","updated":"2017-07-26 21:30:57.000000000","message":"Done","commit_id":"c4c9378e5190d857df88ba5f629854de4d02eb5a"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"dd94f48a5e812d9109530e263f4b3490491a648b","unresolved":false,"context_lines":[{"line_number":985,"context_line":""},{"line_number":986,"context_line":"    def update_project_tags(self, project_id, tags, initiator\u003dNone):"},{"line_number":987,"context_line":"        \"\"\"Update project tags calls a combination of other core functions.\"\"\""},{"line_number":988,"context_line":"        self._check_project_exists(project_id)"},{"line_number":989,"context_line":"        self.delete_all_project_tags(project_id)"},{"line_number":990,"context_line":"        for tag_name in tags:"},{"line_number":991,"context_line":"            tag_name \u003d urllib.parse.unquote(tag_name)"}],"source_content_type":"text/x-python","patch_set":100,"id":"ff346bd7_362f528f","line":988,"range":{"start_line":988,"start_character":0,"end_line":988,"end_character":46},"updated":"2017-07-26 21:26:55.000000000","message":"This can go...","commit_id":"c4c9378e5190d857df88ba5f629854de4d02eb5a"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"6cb1662e2249a083a4071a1079410ec5489ceb9b","unresolved":false,"context_lines":[{"line_number":985,"context_line":""},{"line_number":986,"context_line":"    def update_project_tags(self, project_id, tags, initiator\u003dNone):"},{"line_number":987,"context_line":"        \"\"\"Update project tags calls a combination of other core functions.\"\"\""},{"line_number":988,"context_line":"        self._check_project_exists(project_id)"},{"line_number":989,"context_line":"        self.delete_all_project_tags(project_id)"},{"line_number":990,"context_line":"        for tag_name in tags:"},{"line_number":991,"context_line":"            tag_name \u003d urllib.parse.unquote(tag_name)"}],"source_content_type":"text/x-python","patch_set":100,"id":"ff346bd7_d6c7e695","line":988,"range":{"start_line":988,"start_character":0,"end_line":988,"end_character":46},"in_reply_to":"ff346bd7_362f528f","updated":"2017-07-26 21:30:57.000000000","message":"Done","commit_id":"c4c9378e5190d857df88ba5f629854de4d02eb5a"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    def _check_limit(self, project_id):"},{"line_number":61,"context_line":"        current_tags \u003d self.driver.list_project_tags(project_id)"},{"line_number":62,"context_line":"        if len(current_tags) \u003e\u003d MAX_PROJECT_TAG_COUNT:"},{"line_number":63,"context_line":"            raise exception.ValidationError("},{"line_number":64,"context_line":"                attribute\u003d\"fewer than %d tags\" % MAX_PROJECT_TAG_COUNT,"},{"line_number":65,"context_line":"                target\u003d\"project \" + project_id)"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_15e1c42a","line":63,"updated":"2017-07-27 17:03:58.000000000","message":"nit: this method is raising validation errors, but i\u0027m not sure what\u0027s being validated or when. Instead, one way to decouple this, is to have the method return True or False answer the question \"is the current tag limit at capacity?\". Then the methods in the API or Manager, are responsible for raising the ValidationErrors\n\n  def _is_project_over_tag_limit(self, project_id):\n  \"\"\"Check the capacity of the current tags associate to a project.\"\"\"\n      return len(self.driver.list_project_tags(project_id)) \u003e\u003d MAX_PROJECT_TAG_COUNT\n\nthen we can do things like:\n\n  def create_project_tag(self, project_id, tag_name):\n      if is_project_over_tag_limit(project_id):\n          raise exception.ValidationError(...)","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":501,"context_line":"            project_list \u003d subtree_list + [project]"},{"line_number":502,"context_line":"            projects_ids \u003d [x[\u0027id\u0027] for x in project_list]"},{"line_number":503,"context_line":""},{"line_number":504,"context_line":"            self.remove_all_project_tags(project_id)"},{"line_number":505,"context_line":""},{"line_number":506,"context_line":"            for prj in project_list:"},{"line_number":507,"context_line":"                self._pre_delete_cleanup_project(prj[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_151664f2","line":504,"updated":"2017-07-27 17:03:58.000000000","message":"Shouldn\u0027t this be done by the FK constraint?","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"025c22ba95505c7e691a89b4d2a30e10d664a4cf","unresolved":false,"context_lines":[{"line_number":501,"context_line":"            project_list \u003d subtree_list + [project]"},{"line_number":502,"context_line":"            projects_ids \u003d [x[\u0027id\u0027] for x in project_list]"},{"line_number":503,"context_line":""},{"line_number":504,"context_line":"            self.remove_all_project_tags(project_id)"},{"line_number":505,"context_line":""},{"line_number":506,"context_line":"            for prj in project_list:"},{"line_number":507,"context_line":"                self._pre_delete_cleanup_project(prj[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_c5d9fa22","line":504,"in_reply_to":"ff346bd7_151664f2","updated":"2017-07-28 19:22:49.000000000","message":"It does. this is for tests. cascade\u003dTrue is only passed in as a kwarg on tests (eg. test_delete_project_cascade)","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":964,"context_line":"        return action"},{"line_number":965,"context_line":""},{"line_number":966,"context_line":"    def update_project_tags(self, project_id, tags, initiator\u003dNone):"},{"line_number":967,"context_line":"        \"\"\"Update project tags calls a combination of other core functions.\"\"\""},{"line_number":968,"context_line":"        self._check_project_exists(project_id)"},{"line_number":969,"context_line":"        self.remove_all_project_tags(project_id)"},{"line_number":970,"context_line":"        for tag_name in tags:"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_d5957c34","line":967,"updated":"2017-07-27 17:03:58.000000000","message":"nit: this doc string doesn\u0027t necessarily describe the behavior of the API.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"b915e834347d433809026146863e76be18275908","unresolved":false,"context_lines":[{"line_number":964,"context_line":"        return action"},{"line_number":965,"context_line":""},{"line_number":966,"context_line":"    def update_project_tags(self, project_id, tags, initiator\u003dNone):"},{"line_number":967,"context_line":"        \"\"\"Update project tags calls a combination of other core functions.\"\"\""},{"line_number":968,"context_line":"        self._check_project_exists(project_id)"},{"line_number":969,"context_line":"        self.remove_all_project_tags(project_id)"},{"line_number":970,"context_line":"        for tag_name in tags:"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_60091cdc","line":967,"in_reply_to":"ff346bd7_d5957c34","updated":"2017-07-28 19:52:51.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"}],"keystone/resource/routers.py":[{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"5b9d78df08fb9b1e1372b384d657061922b7ee58","unresolved":false,"context_lines":[{"line_number":118,"context_line":"                          \u0027projects\u0027, \u0027project\u0027,"},{"line_number":119,"context_line":"                          resource_descriptions\u003dself.v3_resources))"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        routers.append("},{"line_number":122,"context_line":"            router.Router(controllers.ProjectTagV3(),"},{"line_number":123,"context_line":"                          \u0027tags\u0027, \u0027tag\u0027,"},{"line_number":124,"context_line":"                          resource_descriptions\u003dself.v3_resources))"}],"source_content_type":"text/x-python","patch_set":35,"id":"3f1d235d_9499f9d1","line":121,"range":{"start_line":121,"start_character":8,"end_line":121,"end_character":15},"updated":"2017-07-07 17:41:50.000000000","message":"remove","commit_id":"647825a34dae527c8ec6ad8de89d8a2318633ce5"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"5b9d78df08fb9b1e1372b384d657061922b7ee58","unresolved":false,"context_lines":[{"line_number":123,"context_line":"                          \u0027tags\u0027, \u0027tag\u0027,"},{"line_number":124,"context_line":"                          resource_descriptions\u003dself.v3_resources))"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"        # self._add_resource("},{"line_number":127,"context_line":"        #     mapper, config_controller,"},{"line_number":128,"context_line":"        #     path\u003d\u0027/v3/projects/{project_id}/tags\u0027,"},{"line_number":129,"context_line":"        #     get_action\u003d\u0027list_project_tags\u0027,"}],"source_content_type":"text/x-python","patch_set":35,"id":"3f1d235d_b4b3d54d","line":126,"range":{"start_line":126,"start_character":10,"end_line":126,"end_character":14},"updated":"2017-07-07 17:41:50.000000000","message":"add_resource for /tags and /tags/{value}","commit_id":"647825a34dae527c8ec6ad8de89d8a2318633ce5"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"6d3f10631caf8360e218182a28c052e22d1363b4","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        self._add_resource("},{"line_number":123,"context_line":"            mapper, tag_controller,"},{"line_number":124,"context_line":"            path\u003d\u0027/projects/{project_id}/tags\u0027,"},{"line_number":125,"context_line":"            get_action\u003d\u0027list_project_tags\u0027,"},{"line_number":126,"context_line":"            put_action\u003d\u0027update_project_tags\u0027,"},{"line_number":127,"context_line":"            delete_action\u003d\u0027remove_all_project_tags\u0027,"},{"line_number":128,"context_line":"            rel\u003djson_home.build_v3_resource_relation("}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_118ded7a","line":125,"range":{"start_line":125,"start_character":12,"end_line":125,"end_character":22},"updated":"2017-07-20 16:32:12.000000000","message":"why was this reverted back to get_action?\nFrom our discussion i rmbr we wanted to be able to just call a HEAD request to list and get","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"41e1af629ab834a905ba52f99e99e422307356ac","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        self._add_resource("},{"line_number":123,"context_line":"            mapper, tag_controller,"},{"line_number":124,"context_line":"            path\u003d\u0027/projects/{project_id}/tags\u0027,"},{"line_number":125,"context_line":"            get_action\u003d\u0027list_project_tags\u0027,"},{"line_number":126,"context_line":"            put_action\u003d\u0027update_project_tags\u0027,"},{"line_number":127,"context_line":"            delete_action\u003d\u0027remove_all_project_tags\u0027,"},{"line_number":128,"context_line":"            rel\u003djson_home.build_v3_resource_relation("}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_f1615113","line":125,"range":{"start_line":125,"start_character":12,"end_line":125,"end_character":22},"in_reply_to":"1f1a1f67_118ded7a","updated":"2017-07-20 16:38:34.000000000","message":"This shouldn\u0027t have been reverted, we need to call HEAD","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"6d3f10631caf8360e218182a28c052e22d1363b4","unresolved":false,"context_lines":[{"line_number":134,"context_line":"        self._add_resource("},{"line_number":135,"context_line":"            mapper, tag_controller,"},{"line_number":136,"context_line":"            path\u003d\u0027/projects/{project_id}/tags/{value}\u0027,"},{"line_number":137,"context_line":"            get_action\u003d\u0027get_project_tag\u0027,"},{"line_number":138,"context_line":"            put_action\u003d\u0027create_project_tag\u0027,"},{"line_number":139,"context_line":"            delete_action\u003d\u0027delete_project_tag\u0027,"},{"line_number":140,"context_line":"            rel\u003djson_home.build_v3_resource_relation("}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_f1e71146","line":137,"range":{"start_line":137,"start_character":12,"end_line":137,"end_character":22},"updated":"2017-07-20 16:32:12.000000000","message":"ditto (im guessing this is the result of a rebase issue?)","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"}],"keystone/resource/schema.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"b51bdb19a2f8513f7150b0b0483bcb4c8bdf3721","unresolved":false,"context_lines":[{"line_number":16,"context_line":"_name_properties \u003d {"},{"line_number":17,"context_line":"    \u0027type\u0027: \u0027string\u0027,"},{"line_number":18,"context_line":"    \u0027minLength\u0027: 1,"},{"line_number":19,"context_line":"    \u0027maxLength\u0027: 64,"},{"line_number":20,"context_line":"    \u0027pattern\u0027: \u0027[\\S]+\u0027"},{"line_number":21,"context_line":"}"},{"line_number":22,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"3f1d235d_87b75f3b","line":19,"range":{"start_line":19,"start_character":5,"end_line":19,"end_character":14},"updated":"2017-07-10 16:54:24.000000000","message":"example","commit_id":"b722f77c2a5ba206ee91e15bd3083b281c097f4d"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"b51bdb19a2f8513f7150b0b0483bcb4c8bdf3721","unresolved":false,"context_lines":[{"line_number":103,"context_line":"}"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"# TODO(aselius): Specify the project_tag schema"},{"line_number":106,"context_line":"_project_tag_properties \u003d {"},{"line_number":107,"context_line":"    \u0027project_id\u0027: validation.nullable(parameter_types.id_string),"},{"line_number":108,"context_line":"    \u0027id\u0027: validation.nullable(parameter_types.id_string),"},{"line_number":109,"context_line":"    \u0027name\u0027: _name_properties"}],"source_content_type":"text/x-python","patch_set":39,"id":"3f1d235d_a7aa5bcf","line":106,"range":{"start_line":106,"start_character":0,"end_line":106,"end_character":23},"updated":"2017-07-10 16:54:24.000000000","message":"We can add \"maxLength: 60\" here, and use schema validation to validate this rather than checking in code.","commit_id":"b722f77c2a5ba206ee91e15bd3083b281c097f4d"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"b51bdb19a2f8513f7150b0b0483bcb4c8bdf3721","unresolved":false,"context_lines":[{"line_number":110,"context_line":"}"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"project_tag_create \u003d {"},{"line_number":113,"context_line":"    \u0027type\u0027: \u0027object\u0027,"},{"line_number":114,"context_line":"    \u0027properties\u0027: _project_tag_properties,"},{"line_number":115,"context_line":"    \u0027required\u0027: [\u0027project_id\u0027, \u0027name\u0027],"},{"line_number":116,"context_line":"    \u0027additionalProperties\u0027: False"},{"line_number":117,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":39,"id":"3f1d235d_c77c3722","line":116,"range":{"start_line":113,"start_character":0,"end_line":116,"end_character":33},"updated":"2017-07-10 16:54:24.000000000","message":"We should be able to do the max length 50 of the list of tags validation here.","commit_id":"b722f77c2a5ba206ee91e15bd3083b281c097f4d"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"349f8b067a5fca5a93036817cd53fb241eed75c4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":57,"id":"1f1a1f67_70349293","updated":"2017-07-17 21:13:18.000000000","message":"This was moved to https://review.openstack.org/#/c/484483/","commit_id":"2adb32f9e52c4bbf69e1640789f654ee703c1ad2"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0ef62e249123fc127dc0104f0276cdc514628c63","unresolved":false,"context_lines":[{"line_number":122,"context_line":"    \u0027minProperties\u0027: 1,"},{"line_number":123,"context_line":"    \u0027additionalProperties\u0027: True"},{"line_number":124,"context_line":"}"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"# TODO(aselius): Specify the project_tag schema"},{"line_number":127,"context_line":"_project_tag_properties \u003d {"},{"line_number":128,"context_line":"    \u0027project_id\u0027: validation.nullable(parameter_types.id_string),"},{"line_number":129,"context_line":"    \u0027id\u0027: validation.nullable(parameter_types.id_string),"},{"line_number":130,"context_line":"    \u0027name\u0027: _name_properties"},{"line_number":131,"context_line":"}"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"project_tag_create \u003d {"},{"line_number":134,"context_line":"    \u0027type\u0027: \u0027object\u0027,"},{"line_number":135,"context_line":"    \u0027properties\u0027: _project_tag_properties,"},{"line_number":136,"context_line":"    \u0027required\u0027: [\u0027project_id\u0027, \u0027name\u0027],"},{"line_number":137,"context_line":"    \u0027additionalProperties\u0027: False"},{"line_number":138,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":66,"id":"1f1a1f67_00dff968","line":138,"range":{"start_line":125,"start_character":0,"end_line":138,"end_character":1},"updated":"2017-07-19 22:18:16.000000000","message":"These are in another ps, leftovers","commit_id":"f4364059d700b1812e5c8c2bbc6a8b985b3de887"}],"keystone/tests/unit/core.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"8dbe62afb4f52e5da9c8d07c99788933574380c9","unresolved":false,"context_lines":[{"line_number":21,"context_line":"import json"},{"line_number":22,"context_line":"import ldap"},{"line_number":23,"context_line":"import os"},{"line_number":24,"context_line":"import re"},{"line_number":25,"context_line":"import shutil"},{"line_number":26,"context_line":"import socket"},{"line_number":27,"context_line":"import sys"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f201791_08c26a86","line":24,"range":{"start_line":24,"start_character":0,"end_line":24,"end_character":9},"updated":"2017-06-20 20:28:20.000000000","message":"Part of below","commit_id":"261144e4376e407c91d641ce1ffc965046fad54c"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"8dbe62afb4f52e5da9c8d07c99788933574380c9","unresolved":false,"context_lines":[{"line_number":304,"context_line":"        \u0027id\u0027: uuid.uuid4().hex,"},{"line_number":305,"context_line":"        \u0027name\u0027: uuid.uuid64().hex,"},{"line_number":306,"context_line":"        \u0027project_id\u0027: project_id,"},{"line_number":307,"context_line":"        \u0027endabled\u0027: True"},{"line_number":308,"context_line":"    }"},{"line_number":309,"context_line":"    ref.update(kwargs)"},{"line_number":310,"context_line":"    return ref"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f201791_0894aa8a","line":307,"range":{"start_line":307,"start_character":9,"end_line":307,"end_character":17},"updated":"2017-06-20 20:28:20.000000000","message":"enabled*","commit_id":"261144e4376e407c91d641ce1ffc965046fad54c"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"8dbe62afb4f52e5da9c8d07c99788933574380c9","unresolved":false,"context_lines":[{"line_number":810,"context_line":"    def assertNotEmpty(self, l):"},{"line_number":811,"context_line":"        self.assertGreater(len(l), 0)"},{"line_number":812,"context_line":""},{"line_number":813,"context_line":"    def assertRaisesRegexp(self, expected_exception, expected_regexp,"},{"line_number":814,"context_line":"                           callable_obj, *args, **kwargs):"},{"line_number":815,"context_line":"        \"\"\"Assert that the message in a raised exception matches a regexp.\"\"\""},{"line_number":816,"context_line":"        try:"},{"line_number":817,"context_line":"            callable_obj(*args, **kwargs)"},{"line_number":818,"context_line":"        except expected_exception as exc_value:"},{"line_number":819,"context_line":"            if isinstance(expected_regexp, six.string_types):"},{"line_number":820,"context_line":"                expected_regexp \u003d re.compile(expected_regexp)"},{"line_number":821,"context_line":""},{"line_number":822,"context_line":"            if isinstance(exc_value.args[0], six.text_type):"},{"line_number":823,"context_line":"                if not expected_regexp.search(six.text_type(exc_value)):"},{"line_number":824,"context_line":"                    raise self.failureException("},{"line_number":825,"context_line":"                        \u0027\"%s\" does not match \"%s\"\u0027 %"},{"line_number":826,"context_line":"                        (expected_regexp.pattern, six.text_type(exc_value)))"},{"line_number":827,"context_line":"            else:"},{"line_number":828,"context_line":"                if not expected_regexp.search(str(exc_value)):"},{"line_number":829,"context_line":"                    raise self.failureException("},{"line_number":830,"context_line":"                        \u0027\"%s\" does not match \"%s\"\u0027 %"},{"line_number":831,"context_line":"                        (expected_regexp.pattern, str(exc_value)))"},{"line_number":832,"context_line":"        else:"},{"line_number":833,"context_line":"            if hasattr(expected_exception, \u0027__name__\u0027):"},{"line_number":834,"context_line":"                excName \u003d expected_exception.__name__"},{"line_number":835,"context_line":"            else:"},{"line_number":836,"context_line":"                excName \u003d str(expected_exception)"},{"line_number":837,"context_line":"            raise self.failureException(\"%s not raised\" % excName)"},{"line_number":838,"context_line":""},{"line_number":839,"context_line":"    def assertUserDictEqual(self, expected, observed, message\u003d\u0027\u0027):"},{"line_number":840,"context_line":"        \"\"\"Assert that a user dict is equal to another user dict."}],"source_content_type":"text/x-python","patch_set":10,"id":"5f201791_28c5268f","line":837,"range":{"start_line":813,"start_character":0,"end_line":837,"end_character":66},"updated":"2017-06-20 20:28:20.000000000","message":"I think this patchset may need a rebase, this was removed in a previous change: https://review.openstack.org/#/c/470360/","commit_id":"261144e4376e407c91d641ce1ffc965046fad54c"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"e91027f6d9e6c7fece3b96c2d28b28dddd4243b7","unresolved":false,"context_lines":[{"line_number":287,"context_line":"        \u0027enabled\u0027: True,"},{"line_number":288,"context_line":"        \u0027domain_id\u0027: domain_id,"},{"line_number":289,"context_line":"        \u0027is_domain\u0027: is_domain,"},{"line_number":290,"context_line":"        \u0027tags\u0027: [],"},{"line_number":291,"context_line":"    }"},{"line_number":292,"context_line":"    # NOTE(henry-nash): We don\u0027t include parent_id in the initial list above"},{"line_number":293,"context_line":"    # since specifying it is optional depending on where the project sits in"}],"source_content_type":"text/x-python","patch_set":31,"id":"3f1d235d_8b3da890","line":290,"range":{"start_line":290,"start_character":9,"end_line":290,"end_character":13},"updated":"2017-07-05 23:42:41.000000000","message":"ref to default fixtures","commit_id":"581adb90affedd0d908f7d33b1de4f8bb72a4fb7"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"5b9d78df08fb9b1e1372b384d657061922b7ee58","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        \u0027name\u0027: uuid.uuid4().hex,"},{"line_number":275,"context_line":"        \u0027description\u0027: uuid.uuid4().hex,"},{"line_number":276,"context_line":"        \u0027enabled\u0027: True,"},{"line_number":277,"context_line":"        \u0027tags\u0027: [],"},{"line_number":278,"context_line":"    }"},{"line_number":279,"context_line":"    ref.update(kwargs)"},{"line_number":280,"context_line":"    return ref"}],"source_content_type":"text/x-python","patch_set":35,"id":"3f1d235d_f4926d9f","line":277,"range":{"start_line":277,"start_character":9,"end_line":277,"end_character":13},"updated":"2017-07-07 17:41:50.000000000","message":"remove","commit_id":"647825a34dae527c8ec6ad8de89d8a2318633ce5"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"5b9d78df08fb9b1e1372b384d657061922b7ee58","unresolved":false,"context_lines":[{"line_number":289,"context_line":"        \u0027enabled\u0027: True,"},{"line_number":290,"context_line":"        \u0027domain_id\u0027: domain_id,"},{"line_number":291,"context_line":"        \u0027is_domain\u0027: is_domain,"},{"line_number":292,"context_line":"        \u0027tags\u0027: [],"},{"line_number":293,"context_line":"    }"},{"line_number":294,"context_line":"    # NOTE(henry-nash): We don\u0027t include parent_id in the initial list above"},{"line_number":295,"context_line":"    # since specifying it is optional depending on where the project sits in"}],"source_content_type":"text/x-python","patch_set":35,"id":"3f1d235d_14960996","line":292,"range":{"start_line":292,"start_character":9,"end_line":292,"end_character":13},"updated":"2017-07-07 17:41:50.000000000","message":"remove","commit_id":"647825a34dae527c8ec6ad8de89d8a2318633ce5"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"77ce7c1de48b29faa8f64da7c06103bfbb667c3f","unresolved":false,"context_lines":[{"line_number":273,"context_line":"        \u0027id\u0027: uuid.uuid4().hex,"},{"line_number":274,"context_line":"        \u0027name\u0027: uuid.uuid4().hex,"},{"line_number":275,"context_line":"        \u0027description\u0027: uuid.uuid4().hex,"},{"line_number":276,"context_line":"        \u0027enabled\u0027: True,"},{"line_number":277,"context_line":"    }"},{"line_number":278,"context_line":"    ref.update(kwargs)"},{"line_number":279,"context_line":"    return ref"}],"source_content_type":"text/x-python","patch_set":56,"id":"1f1a1f67_aa42bba9","line":276,"range":{"start_line":276,"start_character":23,"end_line":276,"end_character":24},"updated":"2017-07-17 20:06:40.000000000","message":"unrelated comma, please remove","commit_id":"4f94f88df2bc99bf3cdee81b57ee7b6efe653013"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"572209ba3b269487000aa422a924948b86560fe5","unresolved":false,"context_lines":[{"line_number":300,"context_line":"    if project_id is None:"},{"line_number":301,"context_line":"        project_id \u003d uuid.uuid4().hex"},{"line_number":302,"context_line":"    ref \u003d {"},{"line_number":303,"context_line":"        \u0027id\u0027: uuid.uuid4().hex,"},{"line_number":304,"context_line":"        \u0027name\u0027: uuid.uuid4().hex,"},{"line_number":305,"context_line":"        \u0027project_id\u0027: project_id"},{"line_number":306,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":65,"id":"ff346bd7_63c6936a","line":303,"range":{"start_line":303,"start_character":14,"end_line":303,"end_character":18},"updated":"2017-07-24 19:29:53.000000000","message":"shouldnt this be randint","commit_id":"df8fac6bca06f51abfaee4f97f332cdc2749c5a9"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0ef62e249123fc127dc0104f0276cdc514628c63","unresolved":false,"context_lines":[{"line_number":273,"context_line":"        \u0027id\u0027: uuid.uuid4().hex,"},{"line_number":274,"context_line":"        \u0027name\u0027: uuid.uuid4().hex,"},{"line_number":275,"context_line":"        \u0027description\u0027: uuid.uuid4().hex,"},{"line_number":276,"context_line":"        \u0027enabled\u0027: True,"},{"line_number":277,"context_line":"    }"},{"line_number":278,"context_line":"    ref.update(kwargs)"},{"line_number":279,"context_line":"    return ref"}],"source_content_type":"text/x-python","patch_set":66,"id":"1f1a1f67_c0e4613e","line":276,"range":{"start_line":276,"start_character":23,"end_line":276,"end_character":24},"updated":"2017-07-19 22:18:16.000000000","message":"unrelated change","commit_id":"f4364059d700b1812e5c8c2bbc6a8b985b3de887"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"c12eb39a95f2161232d4b31815cedbd28d029f8b","unresolved":false,"context_lines":[{"line_number":299,"context_line":"def new_project_tag_ref(project_id\u003dNone, **kwargs):"},{"line_number":300,"context_line":"    if project_id is None:"},{"line_number":301,"context_line":"        project_id \u003d uuid.uuid4().hex"},{"line_number":302,"context_line":"    ref \u003d {"},{"line_number":303,"context_line":"        \u0027name\u0027: uuid.uuid4().hex,"},{"line_number":304,"context_line":"        \u0027project_id\u0027: project_id"},{"line_number":305,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":83,"id":"ff346bd7_e3af2392","line":302,"range":{"start_line":302,"start_character":10,"end_line":302,"end_character":11},"updated":"2017-07-24 19:34:32.000000000","message":"should there be an ID parameter added back in here?","commit_id":"5416f25d9b9f26b2deaf7c5ed5c81b5648ce6dd2"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"811f74a7cbc9553f7fec788fa3e9dbae3e41571a","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        \u0027description\u0027: uuid.uuid4().hex,"},{"line_number":287,"context_line":"        \u0027enabled\u0027: True,"},{"line_number":288,"context_line":"        \u0027domain_id\u0027: domain_id,"},{"line_number":289,"context_line":"        \u0027is_domain\u0027: is_domain"},{"line_number":290,"context_line":"    }"},{"line_number":291,"context_line":"    # NOTE(henry-nash): We don\u0027t include parent_id in the initial list above"},{"line_number":292,"context_line":"    # since specifying it is optional depending on where the project sits in"}],"source_content_type":"text/x-python","patch_set":91,"id":"ff346bd7_e75f123f","line":289,"updated":"2017-07-25 13:32:38.000000000","message":"unrelated please revert so it\u0027s one file less to look at","commit_id":"3031b3af1695370db5e121ab6e1ececd9d3840df"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"d661c3529fc2c0bc302e1ff18dc5349351176ba6","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        \u0027description\u0027: uuid.uuid4().hex,"},{"line_number":287,"context_line":"        \u0027enabled\u0027: True,"},{"line_number":288,"context_line":"        \u0027domain_id\u0027: domain_id,"},{"line_number":289,"context_line":"        \u0027is_domain\u0027: is_domain"},{"line_number":290,"context_line":"    }"},{"line_number":291,"context_line":"    # NOTE(henry-nash): We don\u0027t include parent_id in the initial list above"},{"line_number":292,"context_line":"    # since specifying it is optional depending on where the project sits in"}],"source_content_type":"text/x-python","patch_set":91,"id":"ff346bd7_95bceddc","line":289,"in_reply_to":"ff346bd7_e75f123f","updated":"2017-07-25 15:05:00.000000000","message":"will do","commit_id":"3031b3af1695370db5e121ab6e1ececd9d3840df"}],"keystone/tests/unit/default_fixtures.py":[{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"e91027f6d9e6c7fece3b96c2d28b28dddd4243b7","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        \u0027enabled\u0027: True,"},{"line_number":35,"context_line":"        \u0027parent_id\u0027: DEFAULT_DOMAIN_ID,"},{"line_number":36,"context_line":"        \u0027is_domain\u0027: False,"},{"line_number":37,"context_line":"        \u0027tags\u0027: [],"},{"line_number":38,"context_line":"    }, {"},{"line_number":39,"context_line":"        \u0027id\u0027: BAZ_TENANT_ID,"},{"line_number":40,"context_line":"        \u0027name\u0027: \u0027BAZ\u0027,"}],"source_content_type":"text/x-python","patch_set":31,"id":"3f1d235d_ebbc1c07","line":37,"range":{"start_line":37,"start_character":9,"end_line":37,"end_character":13},"updated":"2017-07-05 23:42:41.000000000","message":"this and the change to core.py in unit tests may not be needed.\nCheck again.","commit_id":"581adb90affedd0d908f7d33b1de4f8bb72a4fb7"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"5b9d78df08fb9b1e1372b384d657061922b7ee58","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        \u0027domain_id\u0027: DEFAULT_DOMAIN_ID,"},{"line_number":53,"context_line":"        \u0027parent_id\u0027: DEFAULT_DOMAIN_ID,"},{"line_number":54,"context_line":"        \u0027is_domain\u0027: False,"},{"line_number":55,"context_line":"        \u0027tags\u0027: [],"},{"line_number":56,"context_line":"    }, {"},{"line_number":57,"context_line":"        \u0027id\u0027: SERVICE_TENANT_ID,"},{"line_number":58,"context_line":"        \u0027name\u0027: \u0027service\u0027,"}],"source_content_type":"text/x-python","patch_set":35,"id":"3f1d235d_547c8171","line":55,"range":{"start_line":55,"start_character":9,"end_line":55,"end_character":13},"updated":"2017-07-07 17:41:50.000000000","message":"remove all tags","commit_id":"647825a34dae527c8ec6ad8de89d8a2318633ce5"}],"keystone/tests/unit/resource/test_backends.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"c2580f885beff92f7d06f0df27dd26578d536e42","unresolved":false,"context_lines":[{"line_number":1595,"context_line":"                          self.resource_api.create_project_tag,"},{"line_number":1596,"context_line":"                          project_tag[\u0027id\u0027],"},{"line_number":1597,"context_line":"                          project_tag)"},{"line_number":1598,"context_line":""},{"line_number":1599,"context_line":"    def test_update_project_tags(self):"},{"line_number":1600,"context_line":"        # PUT /v3/projects/{projecti_id}/tags"},{"line_number":1601,"context_line":"        self.assertRaises(exception.ProjectNotFound,"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f201791_43a3a550","line":1598,"updated":"2017-06-20 21:35:31.000000000","message":"We also should add a test for valid \u0026 invalid regex tags as part of the url-safe checking.","commit_id":"fe472f9154840af2c9fe3ab25f6dc8a1a9bbb120"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"c2580f885beff92f7d06f0df27dd26578d536e42","unresolved":false,"context_lines":[{"line_number":1598,"context_line":""},{"line_number":1599,"context_line":"    def test_update_project_tags(self):"},{"line_number":1600,"context_line":"        # PUT /v3/projects/{projecti_id}/tags"},{"line_number":1601,"context_line":"        self.assertRaises(exception.ProjectNotFound,"},{"line_number":1602,"context_line":"                          self.resource_api.update_project_tags,"},{"line_number":1603,"context_line":"                          uuid.uuid4().hex, \u00270\u0027)"},{"line_number":1604,"context_line":""},{"line_number":1605,"context_line":"    def test_update_project_tags_returns_not_found(self):"},{"line_number":1606,"context_line":"        self.assertRaises(exception.ProjectNotFound,"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f201791_e3fcf13f","line":1603,"range":{"start_line":1601,"start_character":0,"end_line":1603,"end_character":48},"updated":"2017-06-20 21:35:31.000000000","message":"This looks like a copy of the one below.","commit_id":"fe472f9154840af2c9fe3ab25f6dc8a1a9bbb120"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"296844d6e687ae510b3fb7a05b942e0bbf17e924","unresolved":false,"context_lines":[{"line_number":1622,"context_line":"            name\u003d\u0027a\u0027, project_id\u003dproject_id)"},{"line_number":1623,"context_line":"        project_tag_alt \u003d unit.new_project_tag_ref("},{"line_number":1624,"context_line":"            name\u003d\u0027b\u0027, project_id\u003dproject_id)"},{"line_number":1625,"context_line":"        # self.resource_api.update_project_tag("},{"line_number":1626,"context_line":"        #    project_id, [project_tag, project_tag_alt])"},{"line_number":1627,"context_line":"        self.resource_api.delete_all_project_tags(project_id)"},{"line_number":1628,"context_line":"        self.assertRaises(exception.ProjectTagNotFound,"},{"line_number":1629,"context_line":"                          self.resource_api.list_project_tags,"}],"source_content_type":"text/x-python","patch_set":12,"id":"5f201791_d454cccc","line":1626,"range":{"start_line":1625,"start_character":8,"end_line":1626,"end_character":56},"updated":"2017-06-22 17:47:13.000000000","message":"this test needs to be cleaned up.. but I\u0027ll uncomment out in the meanwhile for pep8","commit_id":"d635a21c51edb6ea3b91e889380d66a53067ea66"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"1889827904323734861cedcf5d4d9123a8a8eac6","unresolved":false,"context_lines":[{"line_number":1700,"context_line":"        self.assertNotEqual(project_tag_prior[\u0027project_id\u0027], project_id)"},{"line_number":1701,"context_line":""},{"line_number":1702,"context_line":"    def test_update_project_tags_returns_not_found(self):"},{"line_number":1703,"context_line":"        self.assertRaises(exception.ProjectTagNotFound,"},{"line_number":1704,"context_line":"                          self.resource_api.update_project_tags,"},{"line_number":1705,"context_line":"                          uuid.uuid4().hex,"},{"line_number":1706,"context_line":"                          uuid.uuid4().hex,"}],"source_content_type":"text/x-python","patch_set":36,"id":"3f1d235d_ea0048ae","line":1703,"range":{"start_line":1703,"start_character":36,"end_line":1703,"end_character":54},"updated":"2017-07-07 21:32:23.000000000","message":"this should be ProjectNotFound","commit_id":"bf609976a25f207992d79676ad92b4257c9957a1"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"1889827904323734861cedcf5d4d9123a8a8eac6","unresolved":false,"context_lines":[{"line_number":1725,"context_line":"        self.resource_api.remove_all_project_tags(project_id)"},{"line_number":1726,"context_line":"        project_tag_ref \u003d self.resource_api.list_project_tags(project_id)"},{"line_number":1727,"context_line":"        self.assertEqual(project_tag_ref, [])"},{"line_number":1728,"context_line":""},{"line_number":1729,"context_line":""},{"line_number":1730,"context_line":"class ResourceDriverTests(object):"},{"line_number":1731,"context_line":"    \"\"\"Test for the resource driver."}],"source_content_type":"text/x-python","patch_set":36,"id":"3f1d235d_6a26786b","line":1728,"updated":"2017-07-07 21:32:23.000000000","message":"add a case for testing if the tags are removed in cascade when projects that they are attached to are deleted","commit_id":"bf609976a25f207992d79676ad92b4257c9957a1"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"1889827904323734861cedcf5d4d9123a8a8eac6","unresolved":false,"context_lines":[{"line_number":1726,"context_line":"        project_tag_ref \u003d self.resource_api.list_project_tags(project_id)"},{"line_number":1727,"context_line":"        self.assertEqual(project_tag_ref, [])"},{"line_number":1728,"context_line":""},{"line_number":1729,"context_line":""},{"line_number":1730,"context_line":"class ResourceDriverTests(object):"},{"line_number":1731,"context_line":"    \"\"\"Test for the resource driver."},{"line_number":1732,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"3f1d235d_cac46c62","line":1729,"updated":"2017-07-07 21:32:23.000000000","message":"also add a test for checking if the 50 tags per project is enforced or not","commit_id":"bf609976a25f207992d79676ad92b4257c9957a1"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"902ec9e4cb3837e13c57d599b55b355fa39a5cb1","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    domain_count \u003d len(default_fixtures.DOMAINS)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    def _get_random_list_of_tag_refs(self, num_tags):"},{"line_number":36,"context_line":"        tag_name_list \u003d []"},{"line_number":37,"context_line":"        for x in range(0, num_tags):"},{"line_number":38,"context_line":"            tag_name_list.append(\u0027just some name\u0027 + str(x))"},{"line_number":39,"context_line":"        return tag_name_list"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    def test_get_project(self):"},{"line_number":42,"context_line":"        tenant_ref \u003d self.resource_api.get_project(self.tenant_bar[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":64,"id":"1f1a1f67_9d0a5acf","line":39,"range":{"start_line":35,"start_character":0,"end_line":39,"end_character":28},"updated":"2017-07-19 16:44:57.000000000","message":"We can delete this","commit_id":"c2b03ccedf2fa5a97b6c05fcfb4979ede4b6bfd7"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"f1b0183ea872338f969c440a33992a6fc9ec9e33","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    domain_count \u003d len(default_fixtures.DOMAINS)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    def _get_random_list_of_tag_refs(self, num_tags):"},{"line_number":36,"context_line":"        tag_name_list \u003d []"},{"line_number":37,"context_line":"        for x in range(0, num_tags):"},{"line_number":38,"context_line":"            tag_name_list.append(\u0027just some name\u0027 + str(x))"},{"line_number":39,"context_line":"        return tag_name_list"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    def test_get_project(self):"},{"line_number":42,"context_line":"        tenant_ref \u003d self.resource_api.get_project(self.tenant_bar[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":64,"id":"1f1a1f67_21b4447f","line":39,"range":{"start_line":35,"start_character":0,"end_line":39,"end_character":28},"in_reply_to":"1f1a1f67_9d0a5acf","updated":"2017-07-19 17:00:52.000000000","message":"agreed","commit_id":"c2b03ccedf2fa5a97b6c05fcfb4979ede4b6bfd7"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0ef62e249123fc127dc0104f0276cdc514628c63","unresolved":false,"context_lines":[{"line_number":1617,"context_line":"                          uuid.uuid4().hex)"},{"line_number":1618,"context_line":""},{"line_number":1619,"context_line":"    def test_check_if_project_contains_tag(self):"},{"line_number":1620,"context_line":"        # GET /v3/projects/{project_id}/tags/{tag}"},{"line_number":1621,"context_line":""},{"line_number":1622,"context_line":"        project \u003d unit.new_project_ref("},{"line_number":1623,"context_line":"            domain_id\u003dCONF.identity.default_domain_id)"},{"line_number":1624,"context_line":"        project_id \u003d project[\u0027id\u0027]"},{"line_number":1625,"context_line":"        self.resource_api.create_project(project_id, project)"},{"line_number":1626,"context_line":"        project_tag \u003d unit.new_project_tag_ref("},{"line_number":1627,"context_line":"            project_id\u003dproject_id)"},{"line_number":1628,"context_line":"        self.resource_api.create_project_tag(project_tag)"},{"line_number":1629,"context_line":"        contained_tags \u003d self.resource_api.check_if_project_contains_tag("},{"line_number":1630,"context_line":"            project[\u0027id\u0027], project_tag[\u0027name\u0027])"},{"line_number":1631,"context_line":"        self.assertTrue(contained_tags)"},{"line_number":1632,"context_line":""},{"line_number":1633,"context_line":"    def test_create_project_tag_with_url_unsafe_name(self):"},{"line_number":1634,"context_line":"        project \u003d unit.new_project_ref("},{"line_number":1635,"context_line":"            domain_id\u003dCONF.identity.default_domain_id)"},{"line_number":1636,"context_line":"        project_id \u003d project[\u0027id\u0027]"},{"line_number":1637,"context_line":"        self.resource_api.create_project(project_id, project)"},{"line_number":1638,"context_line":"        invalid_tag_name \u003d \u0027message,file\u0027"},{"line_number":1639,"context_line":"        project_tag \u003d unit.new_project_tag_ref(project_id\u003dproject_id,"},{"line_number":1640,"context_line":"                                               name\u003dinvalid_tag_name)"},{"line_number":1641,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":1642,"context_line":"                          self.resource_api.create_project_tag,"},{"line_number":1643,"context_line":"                          project_tag)"},{"line_number":1644,"context_line":""},{"line_number":1645,"context_line":"    def test_create_project_tag_with_trailing_whitespace(self):"},{"line_number":1646,"context_line":"        # PUT /v3/projects/{project_id}/tags/{tag}"},{"line_number":1647,"context_line":""},{"line_number":1648,"context_line":"        project \u003d unit.new_project_ref("},{"line_number":1649,"context_line":"            domain_id\u003dCONF.identity.default_domain_id)"},{"line_number":1650,"context_line":"        project_id \u003d project[\u0027id\u0027]"},{"line_number":1651,"context_line":"        # NOTE(aselius): Adding a project is necessary because of the"},{"line_number":1652,"context_line":"        # _check_limits. See resources/core.py"},{"line_number":1653,"context_line":"        self.resource_api.create_project(project_id, project)"},{"line_number":1654,"context_line":"        project_tag \u003d unit.new_project_tag_ref(project_id\u003dproject_id)"},{"line_number":1655,"context_line":"        project_tag_name \u003d project_tag[\u0027name\u0027] \u003d (project_tag[\u0027name\u0027] + \u0027    \u0027)"},{"line_number":1656,"context_line":"        project_tag_id \u003d project_tag[\u0027id\u0027]"},{"line_number":1657,"context_line":"        project_tag_returned \u003d self.resource_api.create_project_tag("},{"line_number":1658,"context_line":"            project_tag)"},{"line_number":1659,"context_line":"        self.assertEqual(project_tag_id, project_tag_returned[\u0027id\u0027])"},{"line_number":1660,"context_line":"        self.assertEqual("},{"line_number":1661,"context_line":"            project_tag_name.strip(), project_tag_returned[\u0027name\u0027])"},{"line_number":1662,"context_line":""},{"line_number":1663,"context_line":"    def test_create_project_tag_long_name_fails(self):"},{"line_number":1664,"context_line":"        project \u003d unit.new_project_ref("},{"line_number":1665,"context_line":"            domain_id\u003dCONF.identity.default_domain_id)"},{"line_number":1666,"context_line":"        project_id \u003d project[\u0027id\u0027]"},{"line_number":1667,"context_line":"        self.resource_api.create_project(project_id, project)"},{"line_number":1668,"context_line":"        project_tag \u003d unit.new_project_tag_ref("},{"line_number":1669,"context_line":"            name\u003d\u0027a\u0027 * 65, project_id\u003dproject_id)"},{"line_number":1670,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":1671,"context_line":"                          self.resource_api.create_project_tag,"},{"line_number":1672,"context_line":"                          project_tag)"},{"line_number":1673,"context_line":""},{"line_number":1674,"context_line":"    def test_create_project_tags_over_limit_conflict(self):"},{"line_number":1675,"context_line":"        max_tags \u003d 50"},{"line_number":1676,"context_line":"        project_ref \u003d unit.new_project_ref("},{"line_number":1677,"context_line":"            domain_id\u003dCONF.identity.default_domain_id)"},{"line_number":1678,"context_line":"        project_id \u003d project_ref[\u0027id\u0027]"},{"line_number":1679,"context_line":"        self.resource_api.create_project(project_ref[\u0027id\u0027], project_ref)"},{"line_number":1680,"context_line":""},{"line_number":1681,"context_line":"        list_of_tags \u003d self._get_random_list_of_tag_refs(max_tags)"},{"line_number":1682,"context_line":"        for tag in list_of_tags:"},{"line_number":1683,"context_line":"            tag[\u0027project_id\u0027] \u003d project_id"},{"line_number":1684,"context_line":"            self.resource_api.create_project_tag(tag)"},{"line_number":1685,"context_line":""},{"line_number":1686,"context_line":"        last_tag \u003d unit.new_project_tag_ref(project_id\u003dproject_ref[\u0027id\u0027])"},{"line_number":1687,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":1688,"context_line":"                          self.resource_api.create_project_tag,"},{"line_number":1689,"context_line":"                          last_tag)"},{"line_number":1690,"context_line":""},{"line_number":1691,"context_line":"    def test_create_project_tag_case_creates_different_tags(self):"},{"line_number":1692,"context_line":"        # This doesn\u0027t actually test create conflict."},{"line_number":1693,"context_line":"        project \u003d unit.new_project_ref("},{"line_number":1694,"context_line":"            domain_id\u003dCONF.identity.default_domain_id)"},{"line_number":1695,"context_line":"        project_id \u003d project[\u0027id\u0027]"},{"line_number":1696,"context_line":"        self.resource_api.create_project(project_id, project)"},{"line_number":1697,"context_line":"        project_tag_lower \u003d unit.new_project_tag_ref("},{"line_number":1698,"context_line":"            project_id\u003dproject_id, name\u003d\u0027a\u0027)"},{"line_number":1699,"context_line":"        project_tag_upper \u003d unit.new_project_tag_ref("},{"line_number":1700,"context_line":"            project_id\u003dproject_id, name\u003d\u0027A\u0027)"},{"line_number":1701,"context_line":"        self.resource_api.create_project_tag("},{"line_number":1702,"context_line":"            project_tag_lower)"},{"line_number":1703,"context_line":"        self.resource_api.create_project_tag("},{"line_number":1704,"context_line":"            project_tag_upper)"},{"line_number":1705,"context_line":"        contained_tags \u003d self.resource_api.list_project_tags(project_id)"},{"line_number":1706,"context_line":"        self.assertEqual(len(contained_tags), 2)"},{"line_number":1707,"context_line":""},{"line_number":1708,"context_line":"    def test_update_project_tags(self):"},{"line_number":1709,"context_line":"        # PUT /v3/projects/{projecti_id}/tags"}],"source_content_type":"text/x-python","patch_set":66,"id":"1f1a1f67_c000e1ad","line":1706,"range":{"start_line":1620,"start_character":8,"end_line":1706,"end_character":48},"updated":"2017-07-19 22:18:16.000000000","message":"Looks like these tests were reverted, much more complicated here than what was in the previous PS and tests the same thing","commit_id":"f4364059d700b1812e5c8c2bbc6a8b985b3de887"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0ef62e249123fc127dc0104f0276cdc514628c63","unresolved":false,"context_lines":[{"line_number":1895,"context_line":"        project_tag \u003d {"},{"line_number":1896,"context_line":"            \u0027name\u0027: uuid.uuid4().hex,"},{"line_number":1897,"context_line":"            \u0027id\u0027: project_tag[\u0027id\u0027],"},{"line_number":1898,"context_line":"            \u0027project_id\u0027: uuid.uuid4().hex,"},{"line_number":1899,"context_line":"        }"},{"line_number":1900,"context_line":"        self.assertRaises(exception.Conflict, self.driver.create_project_tag,"},{"line_number":1901,"context_line":"                          project_tag)"}],"source_content_type":"text/x-python","patch_set":66,"id":"1f1a1f67_a0b84510","line":1898,"range":{"start_line":1898,"start_character":12,"end_line":1898,"end_character":42},"updated":"2017-07-19 22:18:16.000000000","message":"This will fail since the project_id doesn\u0027t exist","commit_id":"f4364059d700b1812e5c8c2bbc6a8b985b3de887"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0ef62e249123fc127dc0104f0276cdc514628c63","unresolved":false,"context_lines":[{"line_number":1901,"context_line":"                          project_tag)"},{"line_number":1902,"context_line":""},{"line_number":1903,"context_line":"    def test_create_project_tags_same_name_conflict(self):"},{"line_number":1904,"context_line":"        project \u003d unit.new_project_ref()"},{"line_number":1905,"context_line":"        project_id \u003d project[\u0027id\u0027]"},{"line_number":1906,"context_line":"        project_tag \u003d {"},{"line_number":1907,"context_line":"            \u0027name\u0027: \u0027some_valid_name\u0027,"}],"source_content_type":"text/x-python","patch_set":66,"id":"1f1a1f67_403f3186","line":1904,"range":{"start_line":1904,"start_character":8,"end_line":1904,"end_character":40},"updated":"2017-07-19 22:18:16.000000000","message":"Not sure why this was changed, it just adds more lines to do the same thing?","commit_id":"f4364059d700b1812e5c8c2bbc6a8b985b3de887"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0ef62e249123fc127dc0104f0276cdc514628c63","unresolved":false,"context_lines":[{"line_number":1905,"context_line":"        project_id \u003d project[\u0027id\u0027]"},{"line_number":1906,"context_line":"        project_tag \u003d {"},{"line_number":1907,"context_line":"            \u0027name\u0027: \u0027some_valid_name\u0027,"},{"line_number":1908,"context_line":"            \u0027id\u0027: uuid.uuid4().hex,"},{"line_number":1909,"context_line":"            \u0027project_id\u0027: project_id,"},{"line_number":1910,"context_line":"        }"},{"line_number":1911,"context_line":"        self.driver.create_project(project_id, project)"}],"source_content_type":"text/x-python","patch_set":66,"id":"1f1a1f67_004db93c","line":1908,"range":{"start_line":1908,"start_character":18,"end_line":1908,"end_character":34},"updated":"2017-07-19 22:18:16.000000000","message":"Needs to be an integer","commit_id":"f4364059d700b1812e5c8c2bbc6a8b985b3de887"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0ef62e249123fc127dc0104f0276cdc514628c63","unresolved":false,"context_lines":[{"line_number":1911,"context_line":"        self.driver.create_project(project_id, project)"},{"line_number":1912,"context_line":"        self.driver.create_project_tag(project_tag)"},{"line_number":1913,"context_line":"        # Assign unique ID to other tag to avoid ID conflict"},{"line_number":1914,"context_line":"        project_tag[\u0027id\u0027] \u003d uuid.uuid4().hex"},{"line_number":1915,"context_line":"        self.assertRaises(exception.Conflict, self.driver.create_project_tag,"},{"line_number":1916,"context_line":"                          project_tag)"}],"source_content_type":"text/x-python","patch_set":66,"id":"1f1a1f67_e0475d1c","line":1914,"range":{"start_line":1914,"start_character":28,"end_line":1914,"end_character":44},"updated":"2017-07-19 22:18:16.000000000","message":"ditto","commit_id":"f4364059d700b1812e5c8c2bbc6a8b985b3de887"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"6d3f10631caf8360e218182a28c052e22d1363b4","unresolved":false,"context_lines":[{"line_number":1605,"context_line":"        project, tags \u003d self._create_project_and_tags(1)"},{"line_number":1606,"context_line":"        self.resource_api.create_project_tag(project[\u0027id\u0027], tags[0])"},{"line_number":1607,"context_line":"        project_tag_ref \u003d self.resource_api.list_project_tags(project[\u0027id\u0027])"},{"line_number":1608,"context_line":"        self.assertEqual(tags[0], project_tag_ref[0])"},{"line_number":1609,"context_line":""},{"line_number":1610,"context_line":"    def test_list_project_tags_returns_not_found(self):"},{"line_number":1611,"context_line":"        self.assertRaises(exception.ProjectNotFound,"}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_f1b6f1dc","line":1608,"range":{"start_line":1608,"start_character":34,"end_line":1608,"end_character":52},"updated":"2017-07-20 16:32:12.000000000","message":"this should change if the list_project_tags response is going to be changed to a dict to project_tag_ref[\u0027tags\u0027][0]","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"6d3f10631caf8360e218182a28c052e22d1363b4","unresolved":false,"context_lines":[{"line_number":1684,"context_line":"        project, tags \u003d self._create_project_and_tags(1)"},{"line_number":1685,"context_line":"        self.resource_api.create_project_tag(project[\u0027id\u0027], tags[0])"},{"line_number":1686,"context_line":"        self.resource_api.delete_project(project[\u0027id\u0027], cascade\u003dTrue)"},{"line_number":1687,"context_line":"        self.assertRaises(exception.ProjectTagNotFound,"},{"line_number":1688,"context_line":"                          self.resource_api.get_project_tag,"},{"line_number":1689,"context_line":"                          project[\u0027id\u0027],"},{"line_number":1690,"context_line":"                          tags[0])"}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_91ae9d96","line":1687,"range":{"start_line":1687,"start_character":36,"end_line":1687,"end_character":54},"updated":"2017-07-20 16:32:12.000000000","message":"nice catch!","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0be3de8db5712fa43c035b2cffc5db126527c1f5","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    domain_count \u003d len(default_fixtures.DOMAINS)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    def _get_random_list_of_tag_refs(self, num_tags):"},{"line_number":36,"context_line":"        tag_name_list \u003d []"},{"line_number":37,"context_line":"        for x in range(0, num_tags):"},{"line_number":38,"context_line":"            tag_name_list.append(\u0027just some name\u0027 + str(x))"},{"line_number":39,"context_line":"        return tag_name_list"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    def test_get_project(self):"},{"line_number":42,"context_line":"        tenant_ref \u003d self.resource_api.get_project(self.tenant_bar[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":84,"id":"ff346bd7_19897a74","line":39,"range":{"start_line":35,"start_character":0,"end_line":39,"end_character":28},"updated":"2017-07-24 20:40:40.000000000","message":"Don\u0027t need this","commit_id":"937436495525be7f74d3ef4e69820c601bb2deab"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":607,"context_line":"        project4 \u003d unit.new_project_ref("},{"line_number":608,"context_line":"            domain_id\u003dCONF.identity.default_domain_id,"},{"line_number":609,"context_line":"            parent_id\u003dproject2[\u0027id\u0027])"},{"line_number":610,"context_line":"        project4.pop(\u0027tags\u0027, None)"},{"line_number":611,"context_line":""},{"line_number":612,"context_line":"        self.resource_api.create_project(project4[\u0027id\u0027], project4)"},{"line_number":613,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_003060e7","line":610,"updated":"2017-07-27 17:03:58.000000000","message":"Was the presence of the tags attribute causing tests to fail somehow?","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"42d91a2c414dd6be203a98fd207c0306bcf0591a","unresolved":false,"context_lines":[{"line_number":607,"context_line":"        project4 \u003d unit.new_project_ref("},{"line_number":608,"context_line":"            domain_id\u003dCONF.identity.default_domain_id,"},{"line_number":609,"context_line":"            parent_id\u003dproject2[\u0027id\u0027])"},{"line_number":610,"context_line":"        project4.pop(\u0027tags\u0027, None)"},{"line_number":611,"context_line":""},{"line_number":612,"context_line":"        self.resource_api.create_project(project4[\u0027id\u0027], project4)"},{"line_number":613,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_abe2452e","line":610,"in_reply_to":"df3967d1_20ee7488","updated":"2017-07-28 20:23:34.000000000","message":"we are going to leave it in for the meanwhile since tags are still put in on the api for list and get projects","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"3694fabff0053fd4f68c3023e413d1ba71a2bf14","unresolved":false,"context_lines":[{"line_number":607,"context_line":"        project4 \u003d unit.new_project_ref("},{"line_number":608,"context_line":"            domain_id\u003dCONF.identity.default_domain_id,"},{"line_number":609,"context_line":"            parent_id\u003dproject2[\u0027id\u0027])"},{"line_number":610,"context_line":"        project4.pop(\u0027tags\u0027, None)"},{"line_number":611,"context_line":""},{"line_number":612,"context_line":"        self.resource_api.create_project(project4[\u0027id\u0027], project4)"},{"line_number":613,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_20ee7488","line":610,"in_reply_to":"df3967d1_e09e2c53","updated":"2017-07-28 20:05:20.000000000","message":"With handling tag logic in the controller yes, when we move to the hybrid model, then we should remove this","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"b915e834347d433809026146863e76be18275908","unresolved":false,"context_lines":[{"line_number":607,"context_line":"        project4 \u003d unit.new_project_ref("},{"line_number":608,"context_line":"            domain_id\u003dCONF.identity.default_domain_id,"},{"line_number":609,"context_line":"            parent_id\u003dproject2[\u0027id\u0027])"},{"line_number":610,"context_line":"        project4.pop(\u0027tags\u0027, None)"},{"line_number":611,"context_line":""},{"line_number":612,"context_line":"        self.resource_api.create_project(project4[\u0027id\u0027], project4)"},{"line_number":613,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_e09e2c53","line":610,"in_reply_to":"ff346bd7_003060e7","updated":"2017-07-28 19:52:51.000000000","message":"it did before, but since now tags can be created when creating a project this can go.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":1565,"context_line":""},{"line_number":1566,"context_line":"        tags \u003d []"},{"line_number":1567,"context_line":"        for _ in range(0, tag_size):"},{"line_number":1568,"context_line":"            tags.append(uuid.uuid4().hex)"},{"line_number":1569,"context_line":""},{"line_number":1570,"context_line":"        return project, tags"},{"line_number":1571,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_60b04c44","line":1568,"updated":"2017-07-27 17:03:58.000000000","message":"This doesn\u0027t actually create the tags in the backend. Is it suppose to?\n\n  ...\n  tags \u003d []\n  for _ in range(0, tag_size if tag_size else 1):\n      tags.append(uuid.uuid4().hex)\n  project \u003d unit.new_project_ref(\n      domain_id\u003dCONF.identity.default_domain_id,\n      tags\u003dtags\n  )\n  return self.resource_api.create_project(project[\u0027id\u0027], project)\n\nThen you have everything encapsulated in a reference from the Manager without having to pass a tuple.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"b915e834347d433809026146863e76be18275908","unresolved":false,"context_lines":[{"line_number":1565,"context_line":""},{"line_number":1566,"context_line":"        tags \u003d []"},{"line_number":1567,"context_line":"        for _ in range(0, tag_size):"},{"line_number":1568,"context_line":"            tags.append(uuid.uuid4().hex)"},{"line_number":1569,"context_line":""},{"line_number":1570,"context_line":"        return project, tags"},{"line_number":1571,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_60035c0f","line":1568,"in_reply_to":"ff346bd7_60b04c44","updated":"2017-07-28 19:52:51.000000000","message":"It\u0027s not supposed to create the tags in this internal. It returns a list of tags for flexibility because there were occasions when we needed a project created and tag names but not the tags themselves created.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":1570,"context_line":"        return project, tags"},{"line_number":1571,"context_line":""},{"line_number":1572,"context_line":"    def test_create_project_with_tags(self):"},{"line_number":1573,"context_line":"        check_tag \u003d \u0027test\u0027"},{"line_number":1574,"context_line":"        tags \u003d [check_tag, uuid.uuid4().hex]"},{"line_number":1575,"context_line":"        project \u003d unit.new_project_ref("},{"line_number":1576,"context_line":"            domain_id\u003dCONF.identity.default_domain_id,"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_60996cc2","line":1573,"updated":"2017-07-27 17:03:58.000000000","message":"nit: the value of this shouldn\u0027t matter since we\u0027re saving it to a variable for later.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":1590,"context_line":"        self.assertIn(project, project_ref)"},{"line_number":1591,"context_line":""},{"line_number":1592,"context_line":"    def test_list_projects_with_tags_any(self):"},{"line_number":1593,"context_line":"        project, tags \u003d self._create_project_and_tags(2)"},{"line_number":1594,"context_line":"        self.resource_api.update_project_tags(project[\u0027id\u0027], tags)"},{"line_number":1595,"context_line":"        project_ref \u003d self.resource_api.list_projects_with_tags_any("},{"line_number":1596,"context_line":"            tags[0])"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_c03db88f","line":1593,"updated":"2017-07-27 17:03:58.000000000","message":"nit: pass this argument as a kwarg since it\u0027s defined as one. That way if the method ever changes to something like;\n\n  def _create_project_and_tags(self, other_arg\u003dNone, tag_size\u003d1):\n\nWe won\u0027t break these tests.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"b915e834347d433809026146863e76be18275908","unresolved":false,"context_lines":[{"line_number":1590,"context_line":"        self.assertIn(project, project_ref)"},{"line_number":1591,"context_line":""},{"line_number":1592,"context_line":"    def test_list_projects_with_tags_any(self):"},{"line_number":1593,"context_line":"        project, tags \u003d self._create_project_and_tags(2)"},{"line_number":1594,"context_line":"        self.resource_api.update_project_tags(project[\u0027id\u0027], tags)"},{"line_number":1595,"context_line":"        project_ref \u003d self.resource_api.list_projects_with_tags_any("},{"line_number":1596,"context_line":"            tags[0])"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_e0462c22","line":1593,"in_reply_to":"ff346bd7_c03db88f","updated":"2017-07-28 19:52:51.000000000","message":"Done","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0dbce84e07e55330dc11aa520984d97ff79b49cd","unresolved":false,"context_lines":[{"line_number":1604,"context_line":"        self.resource_api.update_project_tags(project[\u0027id\u0027], tags)"},{"line_number":1605,"context_line":"        tag_filter \u003d tags[0] + \u0027,\u0027 + tags[1]"},{"line_number":1606,"context_line":"        project_ref \u003d self.resource_api.list_projects_not_tags(tag_filter)"},{"line_number":1607,"context_line":"        self.assertNotIn(project, project_ref)"},{"line_number":1608,"context_line":""},{"line_number":1609,"context_line":"    def test_list_projects_not_tags_any(self):"},{"line_number":1610,"context_line":"        project, tags \u003d self._create_project_and_tags(2)"}],"source_content_type":"text/x-python","patch_set":105,"id":"ff346bd7_8011f006","line":1607,"updated":"2017-07-27 17:03:58.000000000","message":"This must be asserting a project from setup isn\u0027t in the response. For the sake of having clarity and completeness in the test, I would be in favor of creating two projects in the test instead of relying on something from setup. This would break if setup ever changes and the project we\u0027re relying on in the assertion isn\u0027t created.","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"b915e834347d433809026146863e76be18275908","unresolved":false,"context_lines":[{"line_number":1604,"context_line":"        self.resource_api.update_project_tags(project[\u0027id\u0027], tags)"},{"line_number":1605,"context_line":"        tag_filter \u003d tags[0] + \u0027,\u0027 + tags[1]"},{"line_number":1606,"context_line":"        project_ref \u003d self.resource_api.list_projects_not_tags(tag_filter)"},{"line_number":1607,"context_line":"        self.assertNotIn(project, project_ref)"},{"line_number":1608,"context_line":""},{"line_number":1609,"context_line":"    def test_list_projects_not_tags_any(self):"},{"line_number":1610,"context_line":"        project, tags \u003d self._create_project_and_tags(2)"}],"source_content_type":"text/x-python","patch_set":105,"id":"df3967d1_20af9495","line":1607,"in_reply_to":"ff346bd7_8011f006","updated":"2017-07-28 19:52:51.000000000","message":"Not entirely sure what you mean.. did you mean self.project defined in the setup? this is just asserting the project created from _create_project_and_tags","commit_id":"6e95c3753061a3008f514606aa16fc3ae56068c9"}],"keystone/tests/unit/test_backend_sql.py":[{"author":{"_account_id":20466,"name":"Tin Lam","email":"tin@lam.wtf","username":"tinlam"},"change_message_id":"f46d800fa79c0fe0fcc8f3a5ef2ee1b1921cd5a4","unresolved":false,"context_lines":[{"line_number":228,"context_line":"    def test_project_tags_model(self):"},{"line_number":229,"context_line":"        cols \u003d ((\u0027id\u0027, sql.String, 64),"},{"line_number":230,"context_line":"                (\u0027project_id\u0027, sql.String, 64),"},{"line_number":231,"context_line":"                (\u0027extra\u0027, sql.JsonBlob, None),"},{"line_number":232,"context_line":"                (\u0027name\u0027, sql.String, 80))"},{"line_number":233,"context_line":"        self.assertExpectedSchema(\u0027project_tag\u0027, cols)"},{"line_number":234,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"5f201791_9acef660","line":231,"range":{"start_line":231,"start_character":0,"end_line":231,"end_character":46},"updated":"2017-06-28 00:33:52.000000000","message":"I don\u0027t think we have an this ``extra`` column of JsonBlob.","commit_id":"e62c4f659bc7e3b38de326d53b0158a4a9700b3e"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"6740a6f3d68c34d66f7bda6e285409ada9967f61","unresolved":false,"context_lines":[{"line_number":228,"context_line":"    def test_project_tags_model(self):"},{"line_number":229,"context_line":"        cols \u003d ((\u0027id\u0027, sql.String, 64),"},{"line_number":230,"context_line":"                (\u0027project_id\u0027, sql.String, 64),"},{"line_number":231,"context_line":"                (\u0027extra\u0027, sql.JsonBlob, None),"},{"line_number":232,"context_line":"                (\u0027name\u0027, sql.String, 80))"},{"line_number":233,"context_line":"        self.assertExpectedSchema(\u0027project_tag\u0027, cols)"},{"line_number":234,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"5f201791_7952ed14","line":231,"range":{"start_line":231,"start_character":0,"end_line":231,"end_character":46},"in_reply_to":"5f201791_9acef660","updated":"2017-06-28 15:59:44.000000000","message":"I added this in because of the ModelDictMixinWithExtras extension made in the ProjectTag class in sql.py but I just realized that class has the comments below. I\u0027ll work around it and get rid of extra.\n\n\"NOTE: DO NOT USE THIS FOR FUTURE SQL MODELS. \"Extra\" column is a legacy concept that should not be carried forward with new SQL models as the concept of \"arbitrary\" properties is not in line with the design philosophy of Keystone.\"","commit_id":"e62c4f659bc7e3b38de326d53b0158a4a9700b3e"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"dbb8599658e2c8aa44f8d34669933083df5dee12","unresolved":false,"context_lines":[{"line_number":228,"context_line":"    def test_project_tags_model(self):"},{"line_number":229,"context_line":"        cols \u003d ((\u0027id\u0027, sql.String, 64),"},{"line_number":230,"context_line":"                (\u0027project_id\u0027, sql.String, 64),"},{"line_number":231,"context_line":"                (\u0027name\u0027, sql.String, 80))"},{"line_number":232,"context_line":"        self.assertExpectedSchema(\u0027project_tag\u0027, cols)"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":""}],"source_content_type":"text/x-python","patch_set":58,"id":"1f1a1f67_a1b9becc","line":231,"range":{"start_line":231,"start_character":37,"end_line":231,"end_character":38},"updated":"2017-07-17 23:17:20.000000000","message":"6*","commit_id":"1689ce25115f956765bd6b0628034036e27a4664"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"902ec9e4cb3837e13c57d599b55b355fa39a5cb1","unresolved":false,"context_lines":[{"line_number":226,"context_line":"    # TODO(aselius): Add the model tests, and other project tag related"},{"line_number":227,"context_line":"    # tests below."},{"line_number":228,"context_line":"    def test_project_tags_model(self):"},{"line_number":229,"context_line":"        cols \u003d ((\u0027id\u0027, sql.String, 64),"},{"line_number":230,"context_line":"                (\u0027project_id\u0027, sql.String, 64),"},{"line_number":231,"context_line":"                (\u0027name\u0027, sql.String, 60))"},{"line_number":232,"context_line":"        self.assertExpectedSchema(\u0027project_tag\u0027, cols)"}],"source_content_type":"text/x-python","patch_set":64,"id":"1f1a1f67_41106000","line":229,"range":{"start_line":229,"start_character":23,"end_line":229,"end_character":37},"updated":"2017-07-19 16:44:57.000000000","message":"Change to integer to match","commit_id":"c2b03ccedf2fa5a97b6c05fcfb4979ede4b6bfd7"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"572209ba3b269487000aa422a924948b86560fe5","unresolved":false,"context_lines":[{"line_number":223,"context_line":"                (\u0027audit_chain_id\u0027, sql.String, 32))"},{"line_number":224,"context_line":"        self.assertExpectedSchema(\u0027revocation_event\u0027, cols)"},{"line_number":225,"context_line":""},{"line_number":226,"context_line":"    # TODO(aselius): Add the model tests, and other project tag related"},{"line_number":227,"context_line":"    # tests below."},{"line_number":228,"context_line":"    def test_project_tags_model(self):"},{"line_number":229,"context_line":"        cols \u003d ((\u0027id\u0027, sql.String, 64),"}],"source_content_type":"text/x-python","patch_set":65,"id":"ff346bd7_23bd2bb7","line":226,"range":{"start_line":226,"start_character":6,"end_line":226,"end_character":10},"updated":"2017-07-24 19:29:53.000000000","message":"Done","commit_id":"df8fac6bca06f51abfaee4f97f332cdc2749c5a9"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"6949dfb77c4833b932ce0e09f1b1c342dcff316e","unresolved":false,"context_lines":[{"line_number":228,"context_line":"    def test_project_tags_model(self):"},{"line_number":229,"context_line":"        cols \u003d ((\u0027id\u0027, sql.Integer, None),"},{"line_number":230,"context_line":"                (\u0027project_id\u0027, sql.String, 64),"},{"line_number":231,"context_line":"                (\u0027name\u0027, sql.String, 60))"},{"line_number":232,"context_line":"        self.assertExpectedSchema(\u0027project_tag\u0027, cols)"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":""}],"source_content_type":"text/x-python","patch_set":78,"id":"ff346bd7_032ecea4","line":231,"range":{"start_line":231,"start_character":29,"end_line":231,"end_character":35},"updated":"2017-07-22 23:22:36.000000000","message":"Unicode","commit_id":"3e68f4be82d08a94d24739426d2f02d156b8d423"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"92c6c43f02c15eb96b7a8f119319960fc931608e","unresolved":false,"context_lines":[{"line_number":223,"context_line":"                (\u0027audit_chain_id\u0027, sql.String, 32))"},{"line_number":224,"context_line":"        self.assertExpectedSchema(\u0027revocation_event\u0027, cols)"},{"line_number":225,"context_line":""},{"line_number":226,"context_line":"    # TODO(aselius): Add the model tests, and other project tag related"},{"line_number":227,"context_line":"    # tests below."},{"line_number":228,"context_line":"    def test_project_tags_model(self):"},{"line_number":229,"context_line":"        cols \u003d ((\u0027id\u0027, sql.Integer, None),"},{"line_number":230,"context_line":"                (\u0027project_id\u0027, sql.String, 64),"}],"source_content_type":"text/x-python","patch_set":87,"id":"ff346bd7_f20ecbe3","line":227,"range":{"start_line":226,"start_character":6,"end_line":227,"end_character":18},"updated":"2017-07-24 22:20:40.000000000","message":"remove","commit_id":"ccbc030b7597b97c731ed87762851a1fa212001b"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"ab635b0a153640b20202d5aa1684e68a2ccaeea9","unresolved":false,"context_lines":[{"line_number":315,"context_line":"        ref[\u0027name\u0027] \u003d ref[\u0027name\u0027].upper()"},{"line_number":316,"context_line":"        self.resource_api.create_project(ref[\u0027id\u0027], ref)"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"    # TODO(aselius): Add project tags specific tests here"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"    def test_delete_project_with_user_association(self):"},{"line_number":321,"context_line":"        user \u003d unit.new_user_ref(domain_id\u003dCONF.identity.default_domain_id)"}],"source_content_type":"text/x-python","patch_set":87,"id":"ff346bd7_77abed1c","line":318,"range":{"start_line":318,"start_character":3,"end_line":318,"end_character":57},"updated":"2017-07-24 22:06:56.000000000","message":"Still need to do these?","commit_id":"ccbc030b7597b97c731ed87762851a1fa212001b"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"92c6c43f02c15eb96b7a8f119319960fc931608e","unresolved":false,"context_lines":[{"line_number":315,"context_line":"        ref[\u0027name\u0027] \u003d ref[\u0027name\u0027].upper()"},{"line_number":316,"context_line":"        self.resource_api.create_project(ref[\u0027id\u0027], ref)"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"    # TODO(aselius): Add project tags specific tests here"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"    def test_delete_project_with_user_association(self):"},{"line_number":321,"context_line":"        user \u003d unit.new_user_ref(domain_id\u003dCONF.identity.default_domain_id)"}],"source_content_type":"text/x-python","patch_set":87,"id":"ff346bd7_322e9343","line":318,"range":{"start_line":318,"start_character":3,"end_line":318,"end_character":57},"in_reply_to":"ff346bd7_77abed1c","updated":"2017-07-24 22:20:40.000000000","message":"most of them are covered in test_backend. this can go","commit_id":"ccbc030b7597b97c731ed87762851a1fa212001b"}],"keystone/tests/unit/test_sql_upgrade.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"f4d2dce8b59b1467f211daf98f21db052adcc917","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":54,"id":"1f1a1f67_27e946b6","updated":"2017-07-17 19:22:43.000000000","message":"This has been moved to a separate patch","commit_id":"5c1581fa7bb759d4a332776d558c83c47d77c726"}],"keystone/tests/unit/test_v3.py":[{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"c12eb39a95f2161232d4b31815cedbd28d029f8b","unresolved":false,"context_lines":[{"line_number":875,"context_line":"            self.assertEqual(ref[\u0027domain_id\u0027], entity[\u0027domain_id\u0027])"},{"line_number":876,"context_line":"        return entity"},{"line_number":877,"context_line":""},{"line_number":878,"context_line":"    # project tag validation"},{"line_number":879,"context_line":""},{"line_number":880,"context_line":"    def assertValidProjectTagListResponse(self, resp, *args, **kwargs):"},{"line_number":881,"context_line":"        return self.assertValidListResponse("},{"line_number":882,"context_line":"            resp,"},{"line_number":883,"context_line":"            \u0027tags\u0027,"},{"line_number":884,"context_line":"            self.assertValidProjectTag,"},{"line_number":885,"context_line":"            *args,"},{"line_number":886,"context_line":"            **kwargs)"},{"line_number":887,"context_line":""},{"line_number":888,"context_line":"    def assertValidProjectTagResponse(self, resp, *args, **kwargs):"},{"line_number":889,"context_line":"        return self.assertValidResponse("},{"line_number":890,"context_line":"            resp,"},{"line_number":891,"context_line":"            \u0027tag\u0027,"},{"line_number":892,"context_line":"            self.assertValidProjectTag,"},{"line_number":893,"context_line":"            keys_to_check\u003d[\u0027project_id\u0027,"},{"line_number":894,"context_line":"                           \u0027name\u0027],"},{"line_number":895,"context_line":"            *args,"},{"line_number":896,"context_line":"            **kwargs)"},{"line_number":897,"context_line":""},{"line_number":898,"context_line":"    def assertValidProjectTag(self, entity, ref\u003dNone):"},{"line_number":899,"context_line":"        if ref:"},{"line_number":900,"context_line":"            self.assertEqual(ref[\u0027project_id\u0027], entity[\u0027project_id\u0027])"},{"line_number":901,"context_line":"        return entity"},{"line_number":902,"context_line":""},{"line_number":903,"context_line":"    # user validation"},{"line_number":904,"context_line":""}],"source_content_type":"text/x-python","patch_set":83,"id":"ff346bd7_23e2cbd6","line":901,"range":{"start_line":878,"start_character":4,"end_line":901,"end_character":21},"updated":"2017-07-24 19:34:32.000000000","message":"are these still being used?","commit_id":"5416f25d9b9f26b2deaf7c5ed5c81b5648ce6dd2"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"dd94f48a5e812d9109530e263f4b3490491a648b","unresolved":false,"context_lines":[{"line_number":875,"context_line":"            self.assertEqual(ref[\u0027domain_id\u0027], entity[\u0027domain_id\u0027])"},{"line_number":876,"context_line":"        return entity"},{"line_number":877,"context_line":""},{"line_number":878,"context_line":"    def assertValidProjectTag(self, entity, ref\u003dNone):"},{"line_number":879,"context_line":"        if ref:"},{"line_number":880,"context_line":"            self.assertEqual(ref[\u0027project_id\u0027], entity[\u0027project_id\u0027])"},{"line_number":881,"context_line":"        return entity"},{"line_number":882,"context_line":""},{"line_number":883,"context_line":"    # user validation"},{"line_number":884,"context_line":""}],"source_content_type":"text/x-python","patch_set":100,"id":"ff346bd7_166e8ec8","line":881,"range":{"start_line":878,"start_character":0,"end_line":881,"end_character":21},"updated":"2017-07-26 21:26:55.000000000","message":"Not used.","commit_id":"c4c9378e5190d857df88ba5f629854de4d02eb5a"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"6cb1662e2249a083a4071a1079410ec5489ceb9b","unresolved":false,"context_lines":[{"line_number":875,"context_line":"            self.assertEqual(ref[\u0027domain_id\u0027], entity[\u0027domain_id\u0027])"},{"line_number":876,"context_line":"        return entity"},{"line_number":877,"context_line":""},{"line_number":878,"context_line":"    def assertValidProjectTag(self, entity, ref\u003dNone):"},{"line_number":879,"context_line":"        if ref:"},{"line_number":880,"context_line":"            self.assertEqual(ref[\u0027project_id\u0027], entity[\u0027project_id\u0027])"},{"line_number":881,"context_line":"        return entity"},{"line_number":882,"context_line":""},{"line_number":883,"context_line":"    # user validation"},{"line_number":884,"context_line":""}],"source_content_type":"text/x-python","patch_set":100,"id":"ff346bd7_96bdde03","line":881,"range":{"start_line":878,"start_character":0,"end_line":881,"end_character":21},"in_reply_to":"ff346bd7_166e8ec8","updated":"2017-07-26 21:30:57.000000000","message":"Done","commit_id":"c4c9378e5190d857df88ba5f629854de4d02eb5a"}],"keystone/tests/unit/test_v3_resource.py":[{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"6d3f10631caf8360e218182a28c052e22d1363b4","unresolved":false,"context_lines":[{"line_number":730,"context_line":"            resp \u003d self.put(\u0027/projects/%(project_id)s/tags/%(value)s\u0027 % {"},{"line_number":731,"context_line":"                \u0027project_id\u0027: tag_ref[\u0027project_id\u0027],"},{"line_number":732,"context_line":"                \u0027value\u0027: tag_ref[\u0027name\u0027]},"},{"line_number":733,"context_line":"                expected_status\u003dhttp_client.OK)"},{"line_number":734,"context_line":"            tags.append(resp.result)"},{"line_number":735,"context_line":""},{"line_number":736,"context_line":"        return project, tags"}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_31efc9ea","line":733,"updated":"2017-07-20 16:32:12.000000000","message":"it seems like assertValidProjectTagResponse was taken out from this.\nDo we not need to check the validity of the format? If we think that the schema alone is fine with it, we should delete the assertValidProjectTagResponse and others related to tags in test_v3.py","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"41e1af629ab834a905ba52f99e99e422307356ac","unresolved":false,"context_lines":[{"line_number":730,"context_line":"            resp \u003d self.put(\u0027/projects/%(project_id)s/tags/%(value)s\u0027 % {"},{"line_number":731,"context_line":"                \u0027project_id\u0027: tag_ref[\u0027project_id\u0027],"},{"line_number":732,"context_line":"                \u0027value\u0027: tag_ref[\u0027name\u0027]},"},{"line_number":733,"context_line":"                expected_status\u003dhttp_client.OK)"},{"line_number":734,"context_line":"            tags.append(resp.result)"},{"line_number":735,"context_line":""},{"line_number":736,"context_line":"        return project, tags"}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_f14a7181","line":733,"in_reply_to":"1f1a1f67_31efc9ea","updated":"2017-07-20 16:38:34.000000000","message":"I\u0027m fine with it as long as the tests pass, they were failing on assertValidProjectTagResponse with None !\u003d O(None).","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"6d3f10631caf8360e218182a28c052e22d1363b4","unresolved":false,"context_lines":[{"line_number":741,"context_line":"        # Create a list of tags and a project"},{"line_number":742,"context_line":"        tag_names \u003d []"},{"line_number":743,"context_line":"        for tag in tags:"},{"line_number":744,"context_line":"            tag_names.append(tag[\u0027name\u0027])"},{"line_number":745,"context_line":"        # Extract out the tag names from list of tag objects"},{"line_number":746,"context_line":"        tag_string \u003d \u0027,\u0027.join(tag_names)"},{"line_number":747,"context_line":"        # self.get with query and valid projectlistresponse"}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_11d60df3","line":744,"range":{"start_line":744,"start_character":29,"end_line":744,"end_character":32},"updated":"2017-07-20 16:32:12.000000000","message":"nice catch. i forgot to change this after create_tags was changed","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"},{"author":{"_account_id":23625,"name":"Nicolas Helgeson","email":"nh202b@att.com","username":"nhelgeson"},"change_message_id":"c12eb39a95f2161232d4b31815cedbd28d029f8b","unresolved":false,"context_lines":[{"line_number":824,"context_line":"        self.assertValidProjectListResponse(r)"},{"line_number":825,"context_line":""},{"line_number":826,"context_line":"        projects_result \u003d r.result[\u0027projects\u0027]"},{"line_number":827,"context_line":"        # deleting tags in order to match unit ref obj"},{"line_number":828,"context_line":"        for project_result in projects_result:"},{"line_number":829,"context_line":"            del project_result[\u0027tags\u0027]"},{"line_number":830,"context_line":"        expected_list \u003d [projects[1][\u0027project\u0027]]"},{"line_number":831,"context_line":""},{"line_number":832,"context_line":"        # projects[0] has projects[1] as child"}],"source_content_type":"text/x-python","patch_set":83,"id":"ff346bd7_631e93bb","line":829,"range":{"start_line":827,"start_character":9,"end_line":829,"end_character":38},"updated":"2017-07-24 19:34:32.000000000","message":"should we add tags to the new_project_ref instead of popping them here?","commit_id":"5416f25d9b9f26b2deaf7c5ed5c81b5648ce6dd2"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"92c6c43f02c15eb96b7a8f119319960fc931608e","unresolved":false,"context_lines":[{"line_number":719,"context_line":"                         project."},{"line_number":720,"context_line":""},{"line_number":721,"context_line":"        :returns project: the project that was created."},{"line_number":722,"context_line":"        :returns tags: a list of project tags that were attached to the"},{"line_number":723,"context_line":"                       project."},{"line_number":724,"context_line":"        \"\"\""},{"line_number":725,"context_line":"        project \u003d self.project"}],"source_content_type":"text/x-python","patch_set":87,"id":"ff346bd7_721bfb1a","line":722,"range":{"start_line":722,"start_character":41,"end_line":722,"end_character":45},"updated":"2017-07-24 22:20:40.000000000","message":"tag names","commit_id":"ccbc030b7597b97c731ed87762851a1fa212001b"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f72f8c9c8b689bed68994209d08826f4c2c7065d","unresolved":false,"context_lines":[{"line_number":729,"context_line":""},{"line_number":730,"context_line":"    def test_list_projects_filtering_by_tags(self):"},{"line_number":731,"context_line":"        \"\"\"Call ``GET /projects?tags\u003d{tags}``.\"\"\""},{"line_number":732,"context_line":"        project, tags \u003d self._create_project_and_tags(2)"},{"line_number":733,"context_line":"        tag_string \u003d \u0027,\u0027.join(tags)"},{"line_number":734,"context_line":"        resp \u003d self.get(\u0027/projects?tags\u003d%(values)s\u0027 % {"},{"line_number":735,"context_line":"            \u0027values\u0027: tag_string})"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_f1f68263","line":732,"updated":"2017-07-26 15:54:11.000000000","message":"Since _create_project_and_tags uses a kwarg, it helps readability to call it that way:\n\n  project, tags \u003d self._create_project_and_tags(tag_size\u003d2)","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"ad5d4c300d3c756b69cb93be058895c049bcd5c2","unresolved":false,"context_lines":[{"line_number":729,"context_line":""},{"line_number":730,"context_line":"    def test_list_projects_filtering_by_tags(self):"},{"line_number":731,"context_line":"        \"\"\"Call ``GET /projects?tags\u003d{tags}``.\"\"\""},{"line_number":732,"context_line":"        project, tags \u003d self._create_project_and_tags(2)"},{"line_number":733,"context_line":"        tag_string \u003d \u0027,\u0027.join(tags)"},{"line_number":734,"context_line":"        resp \u003d self.get(\u0027/projects?tags\u003d%(values)s\u0027 % {"},{"line_number":735,"context_line":"            \u0027values\u0027: tag_string})"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_a961ae07","line":732,"in_reply_to":"ff346bd7_f1f68263","updated":"2017-07-26 17:03:39.000000000","message":"sounds good","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f72f8c9c8b689bed68994209d08826f4c2c7065d","unresolved":false,"context_lines":[{"line_number":751,"context_line":"        resp \u003d self.get(\u0027/projects?not-tags\u003d%(values)s\u0027 % {"},{"line_number":752,"context_line":"            \u0027values\u0027: tag_string})"},{"line_number":753,"context_line":"        self.assertValidProjectListResponse(resp)"},{"line_number":754,"context_line":"        self.assertNotEqual(project[\u0027id\u0027], resp.result[\u0027projects\u0027][0][\u0027id\u0027])"},{"line_number":755,"context_line":""},{"line_number":756,"context_line":"    def test_list_projects_filtering_by_not_tags_any(self):"},{"line_number":757,"context_line":"        \"\"\"Call ``GET /projects?not-tags-any\u003d{tags}``.\"\"\""}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_d1113e5f","line":754,"updated":"2017-07-26 15:54:11.000000000","message":"What project is being returned here? I might help to call the utility method twice to and make an assertion:\n\n  project1, tags1 \u003d self._create_project_and_tags(tag_size\u003d2)\n  project2, tags2 \u003d self._create_project_and_tags(tag_size\u003d2)\n  tag_string \u003d \u0027,\u0027.join(tags1)\n  resp \u003d self.get(\n      \u0027/projects?not-tags\u003d%(values)s\u0027 % {\u0027values\u0027: tag_string}\n  )\n  self.assertValidProjectListResponse(resp)\n  self.assertNotEqual(project[\u0027id\u0027], resp.result[\u0027projects\u0027][0][\u0027id\u0027])\n  # or iterate through every project returned and ensure it\u0027s not project1[\u0027id\u0027]\n  # or check that project2[\u0027id\u0027] is in the response.","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"ad5d4c300d3c756b69cb93be058895c049bcd5c2","unresolved":false,"context_lines":[{"line_number":751,"context_line":"        resp \u003d self.get(\u0027/projects?not-tags\u003d%(values)s\u0027 % {"},{"line_number":752,"context_line":"            \u0027values\u0027: tag_string})"},{"line_number":753,"context_line":"        self.assertValidProjectListResponse(resp)"},{"line_number":754,"context_line":"        self.assertNotEqual(project[\u0027id\u0027], resp.result[\u0027projects\u0027][0][\u0027id\u0027])"},{"line_number":755,"context_line":""},{"line_number":756,"context_line":"    def test_list_projects_filtering_by_not_tags_any(self):"},{"line_number":757,"context_line":"        \"\"\"Call ``GET /projects?not-tags-any\u003d{tags}``.\"\"\""}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_cc43e012","line":754,"in_reply_to":"ff346bd7_d1113e5f","updated":"2017-07-26 17:03:39.000000000","message":"so the result of the not-tags would be an empty array, since not-tags looks for projects that strictly do not contain all of the tags passed in. I feel like that suffices, but if you feel that doesnt actually test its functionality we can change it.","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f72f8c9c8b689bed68994209d08826f4c2c7065d","unresolved":false,"context_lines":[{"line_number":755,"context_line":""},{"line_number":756,"context_line":"    def test_list_projects_filtering_by_not_tags_any(self):"},{"line_number":757,"context_line":"        \"\"\"Call ``GET /projects?not-tags-any\u003d{tags}``.\"\"\""},{"line_number":758,"context_line":"        project, tags \u003d self._create_project_and_tags(tag_size\u003d2)"},{"line_number":759,"context_line":"        resp \u003d self.get(\u0027/projects?not-tags-any\u003d%(values)s\u0027 % {"},{"line_number":760,"context_line":"            \u0027values\u0027: tags[0]})"},{"line_number":761,"context_line":"        self.assertValidProjectListResponse(resp)"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_710cd240","line":758,"updated":"2017-07-26 15:54:11.000000000","message":"Same comment here as above.","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"ad5d4c300d3c756b69cb93be058895c049bcd5c2","unresolved":false,"context_lines":[{"line_number":755,"context_line":""},{"line_number":756,"context_line":"    def test_list_projects_filtering_by_not_tags_any(self):"},{"line_number":757,"context_line":"        \"\"\"Call ``GET /projects?not-tags-any\u003d{tags}``.\"\"\""},{"line_number":758,"context_line":"        project, tags \u003d self._create_project_and_tags(tag_size\u003d2)"},{"line_number":759,"context_line":"        resp \u003d self.get(\u0027/projects?not-tags-any\u003d%(values)s\u0027 % {"},{"line_number":760,"context_line":"            \u0027values\u0027: tags[0]})"},{"line_number":761,"context_line":"        self.assertValidProjectListResponse(resp)"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_ec57c4c9","line":758,"in_reply_to":"ff346bd7_710cd240","updated":"2017-07-26 17:03:39.000000000","message":"same as above.","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f72f8c9c8b689bed68994209d08826f4c2c7065d","unresolved":false,"context_lines":[{"line_number":1389,"context_line":"        self.get("},{"line_number":1390,"context_line":"            \u0027/projects/%(project_id)s/tags/%(value)s\u0027 % {"},{"line_number":1391,"context_line":"                \u0027project_id\u0027: self.project_id,"},{"line_number":1392,"context_line":"                \u0027value\u0027: \u0027I_dont_exist\u0027},"},{"line_number":1393,"context_line":"            expected_status\u003dhttp_client.NOT_FOUND)"},{"line_number":1394,"context_line":""},{"line_number":1395,"context_line":"    def test_delete_project_tag(self):"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_3c174148","line":1392,"updated":"2017-07-26 15:54:11.000000000","message":"nit:\n\n  \u0027value\u0027: uuid.uuid4().hex\n\nonly for the sake of consistency with other tests that assume 404.","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f72f8c9c8b689bed68994209d08826f4c2c7065d","unresolved":false,"context_lines":[{"line_number":1412,"context_line":"                \u0027project_id\u0027: project[\u0027id\u0027]},"},{"line_number":1413,"context_line":"            expected_status\u003dhttp_client.NO_CONTENT)"},{"line_number":1414,"context_line":"        self.get("},{"line_number":1415,"context_line":"            \u0027/projects/%(project_id)s/tags/%(value)s\u0027 % {"},{"line_number":1416,"context_line":"                \u0027project_id\u0027: self.project_id,"},{"line_number":1417,"context_line":"                \u0027value\u0027: tags[0]},"},{"line_number":1418,"context_line":"            expected_status\u003dhttp_client.NOT_FOUND)"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_fc7c1984","line":1415,"updated":"2017-07-26 15:54:11.000000000","message":"This test could also ask for a list of all project tags and assert it is 0","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"ad5d4c300d3c756b69cb93be058895c049bcd5c2","unresolved":false,"context_lines":[{"line_number":1412,"context_line":"                \u0027project_id\u0027: project[\u0027id\u0027]},"},{"line_number":1413,"context_line":"            expected_status\u003dhttp_client.NO_CONTENT)"},{"line_number":1414,"context_line":"        self.get("},{"line_number":1415,"context_line":"            \u0027/projects/%(project_id)s/tags/%(value)s\u0027 % {"},{"line_number":1416,"context_line":"                \u0027project_id\u0027: self.project_id,"},{"line_number":1417,"context_line":"                \u0027value\u0027: tags[0]},"},{"line_number":1418,"context_line":"            expected_status\u003dhttp_client.NOT_FOUND)"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_6c6bd484","line":1415,"in_reply_to":"ff346bd7_fc7c1984","updated":"2017-07-26 17:03:39.000000000","message":"sounds good","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f72f8c9c8b689bed68994209d08826f4c2c7065d","unresolved":false,"context_lines":[{"line_number":1479,"context_line":"        self.assertIn(tags[0], resp.result[\u0027tags\u0027])"},{"line_number":1480,"context_line":""},{"line_number":1481,"context_line":"    def test_list_project_tags_for_project_with_no_tags(self):"},{"line_number":1482,"context_line":"        resp \u003d self.get("},{"line_number":1483,"context_line":"            \u0027/projects/%(project_id)s/tags\u0027 % {"},{"line_number":1484,"context_line":"                \u0027project_id\u0027: self.project_id},"},{"line_number":1485,"context_line":"            expected_status\u003dhttp_client.OK)"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_fca1b9f9","line":1482,"updated":"2017-07-26 15:54:11.000000000","message":"This also supports HEAD requests. We should make sure we test that path, too.","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"},{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"ad5d4c300d3c756b69cb93be058895c049bcd5c2","unresolved":false,"context_lines":[{"line_number":1479,"context_line":"        self.assertIn(tags[0], resp.result[\u0027tags\u0027])"},{"line_number":1480,"context_line":""},{"line_number":1481,"context_line":"    def test_list_project_tags_for_project_with_no_tags(self):"},{"line_number":1482,"context_line":"        resp \u003d self.get("},{"line_number":1483,"context_line":"            \u0027/projects/%(project_id)s/tags\u0027 % {"},{"line_number":1484,"context_line":"                \u0027project_id\u0027: self.project_id},"},{"line_number":1485,"context_line":"            expected_status\u003dhttp_client.OK)"}],"source_content_type":"text/x-python","patch_set":97,"id":"ff346bd7_acfadcb9","line":1482,"in_reply_to":"ff346bd7_fca1b9f9","updated":"2017-07-26 17:03:39.000000000","message":"sounds good. do you think a separate test is better or all in one?","commit_id":"89bb80df15928c0f818787656eaa55e2fd1ee417"}],"keystone/tests/unit/test_versions.py":[{"author":{"_account_id":23659,"name":"Jaewoo Park","email":"jaewoopark91@gmail.com","username":"aselius"},"change_message_id":"6d3f10631caf8360e218182a28c052e22d1363b4","unresolved":false,"context_lines":[{"line_number":300,"context_line":"        \u0027href-vars\u0027: {"},{"line_number":301,"context_line":"            \u0027group_id\u0027: json_home.Parameters.GROUP_ID,"},{"line_number":302,"context_line":"            \u0027project_id\u0027: json_home.Parameters.PROJECT_ID, }},"},{"line_number":303,"context_line":"    json_home.build_v3_resource_relation(\u0027project_tags\u0027): {"},{"line_number":304,"context_line":"        \u0027href-template\u0027: \u0027/projects/{project_id}/tags/{value}\u0027,"},{"line_number":305,"context_line":"        \u0027href-vars\u0027: {"},{"line_number":306,"context_line":"            \u0027project_id\u0027: json_home.Parameters.PROJECT_ID,"}],"source_content_type":"text/x-python","patch_set":70,"id":"1f1a1f67_b10d19ea","line":303,"range":{"start_line":303,"start_character":4,"end_line":303,"end_character":13},"updated":"2017-07-20 16:32:12.000000000","message":"thanks for adding this.. this was one of the things that were lost during rebase :D","commit_id":"f0d1a3025ef7fde767113779f4af4b172cd7d882"}]}
