)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"e7b4a56bc5cece89f9664bb439f627b18c0945b1","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Added API extension for CRUD operations on the instance tags"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Added API extension which allow following:"},{"line_number":10,"context_line":"- add tag to the instance"},{"line_number":11,"context_line":"- replace set of instance tags with new set of tags"},{"line_number":12,"context_line":"- get information about instance, including list of tags for instance"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"3a961159_a735ea47","line":9,"updated":"2014-12-08 09:06:00.000000000","message":"/s/allow/allows the following","commit_id":"11791ee735ae9bfc094ff8133bb9219658a5a261"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"3bc78f5aa5c78f90bc63c09fd5f3465f6fde0e53","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Added API extension for CRUD operations on the instance tags"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Added API extension which allow following:"},{"line_number":10,"context_line":"- add tag to the instance"},{"line_number":11,"context_line":"- replace set of instance tags with new set of tags"},{"line_number":12,"context_line":"- get information about instance, including list of tags for instance"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"3a961159_c5b02be0","line":9,"in_reply_to":"3a961159_a735ea47","updated":"2014-12-08 11:57:59.000000000","message":"thanks","commit_id":"11791ee735ae9bfc094ff8133bb9219658a5a261"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e06cebed25d60b642af03cad7d4247707ff23995","unresolved":false,"context_lines":[{"line_number":11,"context_line":"- replace set of instance tags with new set of tags"},{"line_number":12,"context_line":"- get information about instance, including list of tags for instance"},{"line_number":13,"context_line":"- remove specified tag from instance"},{"line_number":14,"context_line":"- remove all tags from instance"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Implements: blueprint tag-instances"},{"line_number":17,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":35,"id":"ba7be1f8_19745398","line":14,"updated":"2015-02-20 18:32:33.000000000","message":"Needs DocImpact and APIImpact tags in the commit message, please.","commit_id":"3d1a3daffc9ee0f5ee9cbf2b00227ebf79ed0ac5"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9ea95fb631e0bd1f55cdd924fafc1de87ddc9dfa","unresolved":false,"context_lines":[{"line_number":15,"context_line":"- remove specified tag from server"},{"line_number":16,"context_line":"- remove all tags from server"},{"line_number":17,"context_line":"- search servers by tags"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"DocImpact"},{"line_number":20,"context_line":"APIImpact"},{"line_number":21,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":92,"id":"5a710552_0b60a2cd","line":18,"updated":"2015-12-15 14:50:03.000000000","message":"This is a long list of features which is also makes the patch big. I know that if you split this to smaller pieces then it needs more than one microversion but I still feel it is too big as a single commit.","commit_id":"89e3586b16b8d787c9385ce7d2bc0674de2812f4"},{"author":{"_account_id":12175,"name":"Eli Qiao","email":"qiaoliyong@gmail.com","username":"Eli"},"change_message_id":"8ba91319bc178ab24fce434b26492babef994cd6","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Added server tags support in nova-api"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Added v2.13 API microversion which allows the following:"},{"line_number":10,"context_line":"- add tag to the server"},{"line_number":11,"context_line":"- replace set of server tags with new set of tags"},{"line_number":12,"context_line":"- get information about server, including list of tags for server"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":96,"id":"1a7b0d38_d5e4950e","line":9,"range":{"start_line":9,"start_character":9,"end_line":9,"end_character":11},"updated":"2015-12-23 05:41:49.000000000","message":"s/2.13/2.15","commit_id":"87f7be976b49d2791203d0d2a4d83c1c5e01365a"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"37800ae37726a0a5a09ac7428204062d6c00b07a","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Added server tags support in nova-api"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Added v2.13 API microversion which allows the following:"},{"line_number":10,"context_line":"- add tag to the server"},{"line_number":11,"context_line":"- replace set of server tags with new set of tags"},{"line_number":12,"context_line":"- get information about server, including list of tags for server"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":96,"id":"1a7b0d38_704e0fc3","line":9,"range":{"start_line":9,"start_character":9,"end_line":9,"end_character":11},"in_reply_to":"1a7b0d38_d5e4950e","updated":"2015-12-23 06:49:23.000000000","message":"yep","commit_id":"87f7be976b49d2791203d0d2a4d83c1c5e01365a"}],"doc/api_samples/os-instance-tags/instance-tags-post-req.json":[{"author":{"_account_id":13071,"name":"Pasquale Porreca","email":"pasquale.porreca@dektech.com.au","username":"pasquale-porreca"},"change_message_id":"12ad96e5ad83fe28f8802783622c9926bf3b4a7a","unresolved":false,"context_lines":[{"line_number":1,"context_line":"{"},{"line_number":2,"context_line":"    \"tass\": ["},{"line_number":3,"context_line":"        \"sometag\""},{"line_number":4,"context_line":"    ]"},{"line_number":5,"context_line":"}"}],"source_content_type":"application/json","patch_set":24,"id":"3a961159_9bd5e51d","line":2,"updated":"2014-12-23 11:20:40.000000000","message":"Should not it be \"tags\"?","commit_id":"9439e79ad23449cfbae0a0bb3f6af6a38f2e6825"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"c864de0ad54d19afed8b5e258dbf88ce303caa4a","unresolved":false,"context_lines":[{"line_number":1,"context_line":"{"},{"line_number":2,"context_line":"    \"tass\": ["},{"line_number":3,"context_line":"        \"sometag\""},{"line_number":4,"context_line":"    ]"},{"line_number":5,"context_line":"}"}],"source_content_type":"application/json","patch_set":24,"id":"3a961159_4dd3c403","line":2,"in_reply_to":"3a961159_9bd5e51d","updated":"2014-12-23 11:41:18.000000000","message":":D Thank you! nice catch!","commit_id":"9439e79ad23449cfbae0a0bb3f6af6a38f2e6825"}],"doc/v3/api_samples/all_extensions/extensions-list-resp.json":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"244bb7c187fbd5e9670f6407b5dc6685761c64d3","unresolved":false,"context_lines":[{"line_number":807,"context_line":"            \"name\": \"ServerTags\","},{"line_number":808,"context_line":"            \"namespace\": \"http://docs.openstack.org/compute/ext/fake_xml\","},{"line_number":809,"context_line":"            \"updated\": \"2014-12-03T00:00:00Z\""},{"line_number":810,"context_line":"        }"},{"line_number":811,"context_line":"    ]"},{"line_number":812,"context_line":"}"}],"source_content_type":"application/json","patch_set":61,"id":"3a50d1a3_51d39b5f","line":810,"updated":"2015-07-25 20:14:24.000000000","message":"There should be no new API extension added at all for this.","commit_id":"73d3d2bf93a5e8271330b175b476b3fb3bb6ec13"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"0b72d2d20ffa0292a684f94e265a0788a9b988a8","unresolved":false,"context_lines":[{"line_number":801,"context_line":"            \"updated\": \"2014-12-03T00:00:00Z\""},{"line_number":802,"context_line":"        },"},{"line_number":803,"context_line":"        {"},{"line_number":804,"context_line":"            \"alias\": \"os-server-tags\","},{"line_number":805,"context_line":"            \"description\": \"Server tags support.\","},{"line_number":806,"context_line":"            \"links\": [],"},{"line_number":807,"context_line":"            \"name\": \"ServerTags\","}],"source_content_type":"application/json","patch_set":65,"id":"1a4dcd0f_c7dc1149","line":804,"updated":"2015-08-03 16:07:29.000000000","message":"I don\u0027t get why you have added this here? There are no more extensions with microversions.","commit_id":"6ff8e08a683d7dd3b6b691ae5d2c5f360a5f1a9b"}],"doc/v3/api_samples/os-server-tags/v2.4/server-tags-post-req.json":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"68f28c92f6b3a593fab8852a85bb9733b78be6ae","unresolved":false,"context_lines":[{"line_number":1,"context_line":"{"},{"line_number":2,"context_line":"    \"tags\": ["},{"line_number":3,"context_line":"        \"sometag\""},{"line_number":4,"context_line":"    ]"},{"line_number":5,"context_line":"}"}],"source_content_type":"application/json","patch_set":45,"id":"bab921fb_e708badb","line":2,"updated":"2015-04-24 08:28:04.000000000","message":"this is correct, but the spec needs updating.","commit_id":"2c7ccfce35f147c994e7b9270b581d4f9fd49ec8"}],"doc/v3/api_samples/os-server-tags/v2.4/server-tags-show-resp.json":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"68f28c92f6b3a593fab8852a85bb9733b78be6ae","unresolved":false,"context_lines":[{"line_number":1,"context_line":"{"},{"line_number":2,"context_line":"    \"server\": {"},{"line_number":3,"context_line":"        \"os-server-tags:tags\": ["},{"line_number":4,"context_line":"            \"sometag\""},{"line_number":5,"context_line":"        ],"},{"line_number":6,"context_line":"        \"addresses\": {"}],"source_content_type":"application/json","patch_set":45,"id":"bab921fb_2768f286","line":3,"updated":"2015-04-24 08:28:04.000000000","message":"I think this can just be \"tags\" now, with the new versioning system.","commit_id":"2c7ccfce35f147c994e7b9270b581d4f9fd49ec8"}],"doc/v3/api_samples/servers_v21/v2.12/server-post-resp.json":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"1631ae5c87b9670f41141188a8554213eeae6e64","unresolved":false,"context_lines":[{"line_number":12,"context_line":"                \"rel\": \"bookmark\""},{"line_number":13,"context_line":"            }"},{"line_number":14,"context_line":"        ]"},{"line_number":15,"context_line":"    }"},{"line_number":16,"context_line":"}"}],"source_content_type":"application/json","patch_set":71,"id":"1a4dcd0f_a144acb6","line":15,"updated":"2015-08-06 10:17:12.000000000","message":"Why do we not have tags in here?","commit_id":"bbd0253f0a227270420e6632349945e72e3ae98f"}],"etc/nova/policy.json":[{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"b9e2dfb9d39e3c3a0955ce676c5444303f03637b","unresolved":false,"context_lines":[{"line_number":190,"context_line":"    \"compute_extension:image_size\": \"\","},{"line_number":191,"context_line":"    \"compute_extension:v3:images:discoverable\": \"\","},{"line_number":192,"context_line":"    \"compute_extension:v3:image-size\": \"\","},{"line_number":193,"context_line":"    \"compute_extension:v3:os-instance-tags\": \"\","},{"line_number":194,"context_line":"    \"compute_extension:v3:image-size:discoverable\": \"\","},{"line_number":195,"context_line":"    \"compute_extension:instance_actions\": \"\","},{"line_number":196,"context_line":"    \"compute_extension:v3:os-instance-actions\": \"\","}],"source_content_type":"application/json","patch_set":36,"id":"ba7be1f8_168ae769","line":193,"updated":"2015-02-24 23:30:40.000000000","message":"also needs compute_extension:v3:os-instance-tags:discoverable\": \"\"\n\nSome doco developing here: https://review.openstack.org/156882 on v2.1 plugins","commit_id":"e2e2cee3069b422add897a1e203f7079ad7ed6b4"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"19f817c03a06fbde80b8d09c3743bb6b863408f5","unresolved":false,"context_lines":[{"line_number":351,"context_line":"    \"os_compute_api:os-server-diagnostics:discoverable\": \"\","},{"line_number":352,"context_line":"    \"os_compute_api:os-server-password\": \"\","},{"line_number":353,"context_line":"    \"os_compute_api:os-server-password:discoverable\": \"\","},{"line_number":354,"context_line":"    \"os_compute_api:os-server-tags\": \"\","},{"line_number":355,"context_line":"    \"os_compute_api:os-server-tags:discoverable\": \"\","},{"line_number":356,"context_line":"    \"os_compute_api:os-server-usage\": \"\","},{"line_number":357,"context_line":"    \"os_compute_api:os-server-usage:discoverable\": \"\","}],"source_content_type":"application/json","patch_set":56,"id":"3a50d1a3_8cffb366","line":354,"updated":"2015-07-21 13:14:02.000000000","message":"I prefer we have each rule for one action.\n\nlike:\n\"os_compute_api:os-server-tags:index\": \"\",\n\n\"os_compute_api:os-server-tags:show\": \"\",\n\n...\n\nThis provide more fine granularity for user.","commit_id":"604050ae30c71fbb04626ba822960d969e0ed37b"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"068d93c7042fe34aeb16749e8fa9ebe267122726","unresolved":false,"context_lines":[{"line_number":351,"context_line":"    \"os_compute_api:os-server-diagnostics:discoverable\": \"\","},{"line_number":352,"context_line":"    \"os_compute_api:os-server-password\": \"\","},{"line_number":353,"context_line":"    \"os_compute_api:os-server-password:discoverable\": \"\","},{"line_number":354,"context_line":"    \"os_compute_api:os-server-tags\": \"\","},{"line_number":355,"context_line":"    \"os_compute_api:os-server-tags:discoverable\": \"\","},{"line_number":356,"context_line":"    \"os_compute_api:os-server-usage\": \"\","},{"line_number":357,"context_line":"    \"os_compute_api:os-server-usage:discoverable\": \"\","}],"source_content_type":"application/json","patch_set":56,"id":"3a50d1a3_071cdc10","line":354,"in_reply_to":"3a50d1a3_8cffb366","updated":"2015-07-21 13:28:53.000000000","message":"ok. will add","commit_id":"604050ae30c71fbb04626ba822960d969e0ed37b"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"597fdb2130c7ea06ab6b555500adc7f3c801deeb","unresolved":false,"context_lines":[{"line_number":354,"context_line":"    \"os_compute_api:os-server-tags:discoverable\": \"\","},{"line_number":355,"context_line":"    \"os_compute_api:os-server-tags:index\": \"\","},{"line_number":356,"context_line":"    \"os_compute_api:os-server-tags:show\": \"\","},{"line_number":357,"context_line":"    \"os_compute_api:os-server-tags:show_details\": \"\","},{"line_number":358,"context_line":"    \"os_compute_api:os-server-tags:update\": \"\","},{"line_number":359,"context_line":"    \"os_compute_api:os-server-tags:update_all\": \"\","},{"line_number":360,"context_line":"    \"os_compute_api:os-server-tags:delete\": \"\","}],"source_content_type":"application/json","patch_set":58,"id":"3a50d1a3_73b96dcb","line":357,"updated":"2015-07-23 09:20:38.000000000","message":"emm...this is confused. But looks like we didn\u0027t have consistent rule name for extend method.  In most of case, we just use \"os_compute_api:os-server-tags\" for extend method. I think this will be better after we move the policy to match the URL.","commit_id":"aed9fd362b0f11ff9500665e8e7959189db3846b"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"244bb7c187fbd5e9670f6407b5dc6685761c64d3","unresolved":false,"context_lines":[{"line_number":188,"context_line":"    \"os_compute_api:servers:detail:get_all_tenants\": \"is_admin:True\","},{"line_number":189,"context_line":"    \"os_compute_api:servers:index:get_all_tenants\": \"is_admin:True\","},{"line_number":190,"context_line":"    \"os_compute_api:servers:create_image:allow_volume_backed\": \"\","},{"line_number":191,"context_line":"    \"os_compute_api:servers:start\": \"rule:admin_or_owner\","},{"line_number":192,"context_line":"    \"os_compute_api:servers:stop\": \"rule:admin_or_owner\","},{"line_number":193,"context_line":"    \"os_compute_api:os-access-ips:discoverable\": \"\","},{"line_number":194,"context_line":"    \"os_compute_api:os-access-ips\": \"\","}],"source_content_type":"application/json","patch_set":61,"id":"3a50d1a3_f1c987ad","line":191,"updated":"2015-07-25 20:14:24.000000000","message":"These tag rules should be added up here directly to the os_compute_api:servers section.","commit_id":"73d3d2bf93a5e8271330b175b476b3fb3bb6ec13"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"244bb7c187fbd5e9670f6407b5dc6685761c64d3","unresolved":false,"context_lines":[{"line_number":351,"context_line":"    \"os_compute_api:os-server-diagnostics:discoverable\": \"\","},{"line_number":352,"context_line":"    \"os_compute_api:os-server-password\": \"\","},{"line_number":353,"context_line":"    \"os_compute_api:os-server-password:discoverable\": \"\","},{"line_number":354,"context_line":"    \"os_compute_api:os-server-tags:discoverable\": \"\","},{"line_number":355,"context_line":"    \"os_compute_api:os-server-tags:index\": \"\","},{"line_number":356,"context_line":"    \"os_compute_api:os-server-tags:show\": \"\","},{"line_number":357,"context_line":"    \"os_compute_api:os-server-tags:update\": \"\","}],"source_content_type":"application/json","patch_set":61,"id":"3a50d1a3_71bed700","line":354,"updated":"2015-07-25 20:14:24.000000000","message":"Remove the above. No API extensions please.","commit_id":"73d3d2bf93a5e8271330b175b476b3fb3bb6ec13"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"244bb7c187fbd5e9670f6407b5dc6685761c64d3","unresolved":false,"context_lines":[{"line_number":358,"context_line":"    \"os_compute_api:os-server-tags:update_all\": \"\","},{"line_number":359,"context_line":"    \"os_compute_api:os-server-tags:delete\": \"\","},{"line_number":360,"context_line":"    \"os_compute_api:os-server-tags:delete_all\": \"\","},{"line_number":361,"context_line":"    \"os_compute_api:os-server-tags\": \"\","},{"line_number":362,"context_line":"    \"os_compute_api:os-server-usage\": \"\","},{"line_number":363,"context_line":"    \"os_compute_api:os-server-usage:discoverable\": \"\","},{"line_number":364,"context_line":"    \"os_compute_api:os-server-groups\": \"\","}],"source_content_type":"application/json","patch_set":61,"id":"3a50d1a3_d1bfabfa","line":361,"updated":"2015-07-25 20:14:24.000000000","message":"No API extension, please. Add to the os_compute_api:servers section as:\n\n os_compute_api:servers:tags:index\n os_compute_api:servers:tags:show\n\netc.","commit_id":"73d3d2bf93a5e8271330b175b476b3fb3bb6ec13"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"be19ed68e5630869cbcbd343dfa0ada4c6d6c78b","unresolved":false,"context_lines":[{"line_number":434,"context_line":"    \"os_compute_api:os-server-diagnostics:discoverable\": \"\","},{"line_number":435,"context_line":"    \"os_compute_api:os-server-password\": \"\","},{"line_number":436,"context_line":"    \"os_compute_api:os-server-password:discoverable\": \"\","},{"line_number":437,"context_line":"    \"os_compute_api:os-server-tags:discoverable\": \"\","},{"line_number":438,"context_line":"    \"os_compute_api:os-server-tags:index\": \"\","},{"line_number":439,"context_line":"    \"os_compute_api:os-server-tags:show\": \"\","},{"line_number":440,"context_line":"    \"os_compute_api:os-server-tags:update\": \"\","}],"source_content_type":"application/json","patch_set":105,"id":"ba63e191_95f93150","line":437,"range":{"start_line":437,"start_character":4,"end_line":437,"end_character":50},"updated":"2016-01-19 06:18:04.000000000","message":"we needn\u0027t this entry. this is used to control whether expose this extension to the extension info api.","commit_id":"d3b90a83d163c8a9cb14bc7042c40bc54b046010"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"66667f7eaebf80d64afbf2f5cc0095e053f0ec05","unresolved":false,"context_lines":[{"line_number":434,"context_line":"    \"os_compute_api:os-server-diagnostics:discoverable\": \"\","},{"line_number":435,"context_line":"    \"os_compute_api:os-server-password\": \"\","},{"line_number":436,"context_line":"    \"os_compute_api:os-server-password:discoverable\": \"\","},{"line_number":437,"context_line":"    \"os_compute_api:os-server-tags:discoverable\": \"\","},{"line_number":438,"context_line":"    \"os_compute_api:os-server-tags:index\": \"\","},{"line_number":439,"context_line":"    \"os_compute_api:os-server-tags:show\": \"\","},{"line_number":440,"context_line":"    \"os_compute_api:os-server-tags:update\": \"\","}],"source_content_type":"application/json","patch_set":105,"id":"ba63e191_8bf26a99","line":437,"range":{"start_line":437,"start_character":4,"end_line":437,"end_character":50},"in_reply_to":"ba63e191_95f93150","updated":"2016-01-19 09:59:01.000000000","message":"Done","commit_id":"d3b90a83d163c8a9cb14bc7042c40bc54b046010"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"38e9a32774261727e7cc3c6277976e33e5680c96","unresolved":false,"context_lines":[{"line_number":444,"context_line":"    \"os_compute_api:os-server-usage:discoverable\": \"@\","},{"line_number":445,"context_line":"    \"os_compute_api:os-server-groups\": \"rule:admin_or_owner\","},{"line_number":446,"context_line":"    \"os_compute_api:os-server-groups:discoverable\": \"@\","},{"line_number":447,"context_line":"    \"os_compute_api:os-server-tags:index\": \"\","},{"line_number":448,"context_line":"    \"os_compute_api:os-server-tags:show\": \"\","},{"line_number":449,"context_line":"    \"os_compute_api:os-server-tags:update\": \"\","},{"line_number":450,"context_line":"    \"os_compute_api:os-server-tags:update_all\": \"\","}],"source_content_type":"application/json","patch_set":125,"id":"9a061dce_b7dc7be5","line":447,"updated":"2016-04-05 13:10:36.000000000","message":"Sorry to jump in at the last minute here, but please do not use \"\" policies. It\u0027s equivalent to \"@\" but is easily confused with being the same as the default rule.","commit_id":"347f8e42553f8ef4d258aadbb7c8268f8dde6a15"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"3a2de0091b12d3d128fea9e2f0036eef3554df01","unresolved":false,"context_lines":[{"line_number":444,"context_line":"    \"os_compute_api:os-server-usage:discoverable\": \"@\","},{"line_number":445,"context_line":"    \"os_compute_api:os-server-groups\": \"rule:admin_or_owner\","},{"line_number":446,"context_line":"    \"os_compute_api:os-server-groups:discoverable\": \"@\","},{"line_number":447,"context_line":"    \"os_compute_api:os-server-tags:index\": \"\","},{"line_number":448,"context_line":"    \"os_compute_api:os-server-tags:show\": \"\","},{"line_number":449,"context_line":"    \"os_compute_api:os-server-tags:update\": \"\","},{"line_number":450,"context_line":"    \"os_compute_api:os-server-tags:update_all\": \"\","}],"source_content_type":"application/json","patch_set":125,"id":"9a061dce_f263a1da","line":447,"in_reply_to":"9a061dce_b7dc7be5","updated":"2016-04-05 13:16:51.000000000","message":"There\u0027s a test that\u0027s supposed to catch this in fact.","commit_id":"347f8e42553f8ef4d258aadbb7c8268f8dde6a15"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"26da6a43215a12135cf5e471bb7cbafb735acbf1","unresolved":false,"context_lines":[{"line_number":450,"context_line":"    \"os_compute_api:os-server-tags:update_all\": \"\","},{"line_number":451,"context_line":"    \"os_compute_api:os-server-tags:delete\": \"\","},{"line_number":452,"context_line":"    \"os_compute_api:os-server-tags:delete_all\": \"\","},{"line_number":453,"context_line":"    \"os_compute_api:os-server-tags\": \"\","},{"line_number":454,"context_line":"    \"os_compute_api:os-services\": \"rule:admin_api\","},{"line_number":455,"context_line":"    \"os_compute_api:os-services:discoverable\": \"@\","},{"line_number":456,"context_line":"    \"os_compute_api:server-metadata:discoverable\": \"@\","}],"source_content_type":"application/json","patch_set":125,"id":"9a061dce_7cf488f1","line":453,"range":{"start_line":453,"start_character":4,"end_line":453,"end_character":40},"updated":"2016-04-05 12:45:54.000000000","message":"This rule looks like useless","commit_id":"347f8e42553f8ef4d258aadbb7c8268f8dde6a15"}],"nova/api/openstack/api_version_request.py":[{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"b9e2dfb9d39e3c3a0955ce676c5444303f03637b","unresolved":false,"context_lines":[{"line_number":40,"context_line":"    * 2.1 - Initial version. Equivalent to v2.0 code"},{"line_number":41,"context_line":"    * 2.2 - Adds (keypair) type parameter for os-keypairs plugin"},{"line_number":42,"context_line":"            Fixes success status code for create a keypair method"},{"line_number":43,"context_line":"    * 2.3 - Adds support of instance tags"},{"line_number":44,"context_line":"\"\"\""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"# The minimum and maximum versions of the API supported"}],"source_content_type":"text/x-python","patch_set":36,"id":"ba7be1f8_56ce1fb5","line":43,"updated":"2015-02-24 23:30:40.000000000","message":"so I\u0027m pretty sure we\u0027re meant to refer to them as servers rather than instances now. Otherwise we end up with the current state where sometimes its an instance and sometimes a server and everyone gets confused. Sorry I missed that before but hopefully just a big search/replace (instance_usage_audit_log and instance_actions was a naming mistake)","commit_id":"e2e2cee3069b422add897a1e203f7079ad7ed6b4"}],"nova/api/openstack/compute/contrib/instance_tags.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"53ccb580436ec60aa5ce10c3d4ddee9a056da2b1","unresolved":false,"context_lines":[{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def update(self, req, server_id, id, body):"},{"line_number":50,"context_line":"        context \u003d req.environ[\"nova.context\"]"},{"line_number":51,"context_line":"        authorize(context)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"        try:"},{"line_number":54,"context_line":"            tags \u003d objects.ResourceTagList.get_by_resource_id(context,"}],"source_content_type":"text/x-python","patch_set":8,"id":"5a890539_164a8283","line":51,"updated":"2014-11-08 02:00:03.000000000","message":"we should only use soft_extension_authorizer for server extend api. other APIs should use \u0027extension_authorizer\u0027, otherwise \u0027authorize(context)\u0027 only return True/False at here, it won\u0027t raise any exception when permission check failed.","commit_id":"030bfe81137a556b6465cd0c600b4ab48f4e9576"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"97fb6df3648a3ecdd0b271ec7dad647838394d1c","unresolved":false,"context_lines":[{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def update(self, req, server_id, id, body):"},{"line_number":50,"context_line":"        context \u003d req.environ[\"nova.context\"]"},{"line_number":51,"context_line":"        authorize(context)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"        try:"},{"line_number":54,"context_line":"            tags \u003d objects.ResourceTagList.get_by_resource_id(context,"}],"source_content_type":"text/x-python","patch_set":8,"id":"5a890539_e441930c","line":51,"in_reply_to":"5a890539_0fc4133f","updated":"2014-11-11 13:17:02.000000000","message":"soft_extension_authorizer shouldn\u0027t raise exception but extension_authorizer should","commit_id":"030bfe81137a556b6465cd0c600b4ab48f4e9576"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"6d9a8b072761b1a399ff774b4e0fe549e2279ebc","unresolved":false,"context_lines":[{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def update(self, req, server_id, id, body):"},{"line_number":50,"context_line":"        context \u003d req.environ[\"nova.context\"]"},{"line_number":51,"context_line":"        authorize(context)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"        try:"},{"line_number":54,"context_line":"            tags \u003d objects.ResourceTagList.get_by_resource_id(context,"}],"source_content_type":"text/x-python","patch_set":8,"id":"5a890539_0fc4133f","line":51,"in_reply_to":"5a890539_164a8283","updated":"2014-11-10 13:21:37.000000000","message":"ok. I will fix","commit_id":"030bfe81137a556b6465cd0c600b4ab48f4e9576"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"53ccb580436ec60aa5ce10c3d4ddee9a056da2b1","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            objects.ResourceTagList.create(context, server_id, body[\u0027tags\u0027])"},{"line_number":79,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":80,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":81,"context_line":"        return exc.HTTPOk()"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    def delete(self, req, server_id, id):"},{"line_number":84,"context_line":"        authorize(req.environ[\u0027nova.context\u0027])"}],"source_content_type":"text/x-python","patch_set":8,"id":"5a890539_f67df6b2","line":81,"updated":"2014-11-08 02:00:03.000000000","message":"should return 201 for create","commit_id":"030bfe81137a556b6465cd0c600b4ab48f4e9576"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"6d9a8b072761b1a399ff774b4e0fe549e2279ebc","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            objects.ResourceTagList.create(context, server_id, body[\u0027tags\u0027])"},{"line_number":79,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":80,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":81,"context_line":"        return exc.HTTPOk()"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    def delete(self, req, server_id, id):"},{"line_number":84,"context_line":"        authorize(req.environ[\u0027nova.context\u0027])"}],"source_content_type":"text/x-python","patch_set":8,"id":"5a890539_efc6e748","line":81,"in_reply_to":"5a890539_f67df6b2","updated":"2014-11-10 13:21:37.000000000","message":"Sorry, but accordance with approved specification this method should return 200 OK","commit_id":"030bfe81137a556b6465cd0c600b4ab48f4e9576"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"3cf46f099f1ab45937eaa9774f8588ce2d4c0e7c","unresolved":false,"context_lines":[{"line_number":58,"context_line":"        if len(tags) \u003e\u003d inst_obj.MAX_TAG_COUNT:"},{"line_number":59,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit %d\")"},{"line_number":60,"context_line":"                   % inst_obj.MAX_TAG_COUNT)"},{"line_number":61,"context_line":"            raise exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        tag \u003d objects.Tag(resource_id\u003dserver_id, tag\u003did)"},{"line_number":64,"context_line":"        tag.create(context)"}],"source_content_type":"text/x-python","patch_set":30,"id":"1a930d6b_ba010807","line":61,"updated":"2015-01-24 00:20:54.000000000","message":"This should be HTTPBadRequest (see below)","commit_id":"008845b30faa71d74b1bd8d2841696f642b24d87"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"3cf46f099f1ab45937eaa9774f8588ce2d4c0e7c","unresolved":false,"context_lines":[{"line_number":73,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":74,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":75,"context_line":"                   % {\u0027max\u0027: inst_obj.MAX_TAG_COUNT, \u0027count\u0027: tag_count})"},{"line_number":76,"context_line":"            raise exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":77,"context_line":"        tags \u003d body[\u0027tags\u0027]"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        if not isinstance(tags, list):"}],"source_content_type":"text/x-python","patch_set":30,"id":"1a930d6b_c7336112","line":76,"updated":"2015-01-24 00:20:54.000000000","message":"This really should be HTTPBadRequest. HTTPForbidden is reserved for when a user is not allowed to access a resource.","commit_id":"008845b30faa71d74b1bd8d2841696f642b24d87"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"7f33768b2735df74329341b76f32487a9dc31fb0","unresolved":false,"context_lines":[{"line_number":73,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":74,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":75,"context_line":"                   % {\u0027max\u0027: inst_obj.MAX_TAG_COUNT, \u0027count\u0027: tag_count})"},{"line_number":76,"context_line":"            raise exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":77,"context_line":"        tags \u003d body[\u0027tags\u0027]"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        if not isinstance(tags, list):"}],"source_content_type":"text/x-python","patch_set":30,"id":"1a930d6b_80df6d68","line":76,"in_reply_to":"1a930d6b_c7336112","updated":"2015-01-26 07:15:19.000000000","message":"I\u0027m totally agree with you that here should be HTTPBadRequets. I use here HTTPForbiden just becouse it was written in the spec.\n\nhttps://review.openstack.org/#/c/127281/2/specs/kilo/approved/tag-instances.rst Line 177, 189","commit_id":"008845b30faa71d74b1bd8d2841696f642b24d87"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"3cf46f099f1ab45937eaa9774f8588ce2d4c0e7c","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        if not isinstance(tags, list):"},{"line_number":80,"context_line":"            msg \u003d _(\"Invalid type of tag list. \u0027%s\u0027 is not a list\") % tags"},{"line_number":81,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"        for tag in tags:"},{"line_number":84,"context_line":"            if not isinstance(tag, six.string_types):"}],"source_content_type":"text/x-python","patch_set":30,"id":"1a930d6b_47605101","line":81,"updated":"2015-01-24 00:20:54.000000000","message":"This should go before the check on line 71. Otherwise, if a string is sent for body[\u0027tags\u0027], and that string is \u003e MAX_TAG_COUNT length, then the HTTPForbidden exception on line 76 will be raised instead of the correct HTTPBadRequest exception...","commit_id":"008845b30faa71d74b1bd8d2841696f642b24d87"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"3cf46f099f1ab45937eaa9774f8588ce2d4c0e7c","unresolved":false,"context_lines":[{"line_number":88,"context_line":"                msg \u003d (_(\"Tag \u0027%(tag)s\u0027 is too long. Maximum length of a tag \""},{"line_number":89,"context_line":"                         \"is %(length)d\") % {\u0027tag\u0027: tag,"},{"line_number":90,"context_line":"                                             \u0027length\u0027: tag_obj.MAX_TAG_LENGTH})"},{"line_number":91,"context_line":"                raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        try:"},{"line_number":94,"context_line":"            objects.TagList.create(context, server_id, tags)"}],"source_content_type":"text/x-python","patch_set":30,"id":"1a930d6b_872dd9aa","line":91,"updated":"2015-01-24 00:20:54.000000000","message":"You got it correct here :)","commit_id":"008845b30faa71d74b1bd8d2841696f642b24d87"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3f9b9630f855146309f391e65db10d40b8b0d47b","unresolved":false,"context_lines":[{"line_number":21,"context_line":"from nova.objects import instance as inst_obj"},{"line_number":22,"context_line":"from nova.objects import tag as tag_obj"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"authorize \u003d extensions.extension_authorizer(\u0027compute\u0027, \u0027instance_tags\u0027)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"class InstanceTagsController(wsgi.Controller):"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_6e3dd82a","line":24,"updated":"2015-01-27 12:00:42.000000000","message":"there should use the ALIAS as the extension name.","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3f9b9630f855146309f391e65db10d40b8b0d47b","unresolved":false,"context_lines":[{"line_number":27,"context_line":"class InstanceTagsController(wsgi.Controller):"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    def __init__(self):"},{"line_number":30,"context_line":"        super(InstanceTagsController, self).__init__()"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    def _extend_instance(self, instance, tags):"},{"line_number":33,"context_line":"        key \u003d \"%s:tags\" % Instance_tags.alias"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_0e0c5493","line":30,"updated":"2015-01-27 12:00:42.000000000","message":"__init__ do nothing at here, so we can just remove it.","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"b08cf9adc20daf91f106c033ca13f78e7e4502a4","unresolved":false,"context_lines":[{"line_number":27,"context_line":"class InstanceTagsController(wsgi.Controller):"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    def __init__(self):"},{"line_number":30,"context_line":"        super(InstanceTagsController, self).__init__()"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    def _extend_instance(self, instance, tags):"},{"line_number":33,"context_line":"        key \u003d \"%s:tags\" % Instance_tags.alias"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_e2e399d6","line":30,"in_reply_to":"1a930d6b_0e0c5493","updated":"2015-01-27 16:31:41.000000000","message":"agree","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3f9b9630f855146309f391e65db10d40b8b0d47b","unresolved":false,"context_lines":[{"line_number":60,"context_line":"                   % inst_obj.MAX_TAG_COUNT)"},{"line_number":61,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        tag \u003d objects.Tag(resource_id\u003dserver_id, tag\u003did)"},{"line_number":64,"context_line":"        tag.create(context)"},{"line_number":65,"context_line":"        return exc.HTTPNoContent()"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_317171a8","line":63,"updated":"2015-01-27 12:00:42.000000000","message":"we should validate the id i\u003c tag_obj.MAX_TAG_LENGTH","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"b08cf9adc20daf91f106c033ca13f78e7e4502a4","unresolved":false,"context_lines":[{"line_number":60,"context_line":"                   % inst_obj.MAX_TAG_COUNT)"},{"line_number":61,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        tag \u003d objects.Tag(resource_id\u003dserver_id, tag\u003did)"},{"line_number":64,"context_line":"        tag.create(context)"},{"line_number":65,"context_line":"        return exc.HTTPNoContent()"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_22ea01ac","line":63,"in_reply_to":"1a930d6b_317171a8","updated":"2015-01-27 16:31:41.000000000","message":"yep. I missed it","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3f9b9630f855146309f391e65db10d40b8b0d47b","unresolved":false,"context_lines":[{"line_number":61,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        tag \u003d objects.Tag(resource_id\u003dserver_id, tag\u003did)"},{"line_number":64,"context_line":"        tag.create(context)"},{"line_number":65,"context_line":"        return exc.HTTPNoContent()"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    def create(self, req, server_id, body):"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_8e576425","line":64,"updated":"2015-01-27 12:00:42.000000000","message":"there should catch InstanceNotFound","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"b08cf9adc20daf91f106c033ca13f78e7e4502a4","unresolved":false,"context_lines":[{"line_number":61,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        tag \u003d objects.Tag(resource_id\u003dserver_id, tag\u003did)"},{"line_number":64,"context_line":"        tag.create(context)"},{"line_number":65,"context_line":"        return exc.HTTPNoContent()"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    def create(self, req, server_id, body):"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_4270ed0a","line":64,"in_reply_to":"1a930d6b_8e576425","updated":"2015-01-27 16:31:41.000000000","message":"actually, if such instance doesn\u0027t exist HTTPNotFound will be raised in line 56. \n\nBut i think instance can be deleted during line 57-63 by another user. So I think it\u0027s a good Idea to add try ... expect ... here.","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"}],"nova/api/openstack/compute/plugins/v3/extension_info.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e190cd1ad55387b8943a59121413a59edfc775de","unresolved":false,"context_lines":[{"line_number":77,"context_line":"                    \u0027alias\u0027: \u0027os-server-group-quotas\u0027}],"},{"line_number":78,"context_line":"}"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"# v2.1 plugins which should never appear in the v2 extension list"},{"line_number":81,"context_line":"# This should be the v2.1 alias, not the V2.0 alias"},{"line_number":82,"context_line":"v2_extension_suppress_list \u003d [\u0027servers\u0027, \u0027images\u0027, \u0027versions\u0027, \u0027flavors\u0027,"},{"line_number":83,"context_line":"                              \u0027os-block-device-mapping-v1\u0027, \u0027os-consoles\u0027,"}],"source_content_type":"text/x-python","patch_set":70,"id":"1a4dcd0f_a82d9296","line":80,"updated":"2015-08-05 16:18:26.000000000","message":"According to this, you shouldn\u0027t be adding this here.","commit_id":"ff8aa80e5ff72d7dd31cb37ef8fcb52330ec250f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"8edb62ad1a387507a4e411d4b5bea07fdb9168de","unresolved":false,"context_lines":[{"line_number":77,"context_line":"                    \u0027alias\u0027: \u0027os-server-group-quotas\u0027}],"},{"line_number":78,"context_line":"}"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"# v2.1 plugins which should never appear in the v2 extension list"},{"line_number":81,"context_line":"# This should be the v2.1 alias, not the V2.0 alias"},{"line_number":82,"context_line":"v2_extension_suppress_list \u003d [\u0027servers\u0027, \u0027images\u0027, \u0027versions\u0027, \u0027flavors\u0027,"},{"line_number":83,"context_line":"                              \u0027os-block-device-mapping-v1\u0027, \u0027os-consoles\u0027,"}],"source_content_type":"text/x-python","patch_set":70,"id":"1a4dcd0f_e13954d8","line":80,"in_reply_to":"1a4dcd0f_a82d9296","updated":"2015-08-06 10:00:54.000000000","message":"This is a v2.1 plugin that should never appear in the v2 extension list, right?","commit_id":"ff8aa80e5ff72d7dd31cb37ef8fcb52330ec250f"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"71bc65f5f6a84f260050e39b62e90a5a5e5baafb","unresolved":false,"context_lines":[{"line_number":77,"context_line":"                    \u0027alias\u0027: \u0027os-server-group-quotas\u0027}],"},{"line_number":78,"context_line":"}"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"# v2.1 plugins which should never appear in the v2 extension list"},{"line_number":81,"context_line":"# This should be the v2.1 alias, not the V2.0 alias"},{"line_number":82,"context_line":"v2_extension_suppress_list \u003d [\u0027servers\u0027, \u0027images\u0027, \u0027versions\u0027, \u0027flavors\u0027,"},{"line_number":83,"context_line":"                              \u0027os-block-device-mapping-v1\u0027, \u0027os-consoles\u0027,"}],"source_content_type":"text/x-python","patch_set":70,"id":"1a4dcd0f_a1b4ac34","line":80,"in_reply_to":"1a4dcd0f_e13954d8","updated":"2015-08-06 10:04:32.000000000","message":"I wanted to ask same question right now)","commit_id":"ff8aa80e5ff72d7dd31cb37ef8fcb52330ec250f"}],"nova/api/openstack/compute/plugins/v3/instance_tags.py":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"3cf46f099f1ab45937eaa9774f8588ce2d4c0e7c","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        if len(tags) \u003e\u003d instance.MAX_TAG_COUNT:"},{"line_number":57,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit %d\")"},{"line_number":58,"context_line":"                   % instance.MAX_TAG_COUNT)"},{"line_number":59,"context_line":"            raise exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"        tag \u003d objects.Tag(resource_id\u003dserver_id, tag\u003did)"},{"line_number":62,"context_line":"        tag.create(context)"}],"source_content_type":"text/x-python","patch_set":30,"id":"1a930d6b_da06d41c","line":59,"updated":"2015-01-24 00:20:54.000000000","message":"Should be HTTPBadRequest","commit_id":"008845b30faa71d74b1bd8d2841696f642b24d87"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"3cf46f099f1ab45937eaa9774f8588ce2d4c0e7c","unresolved":false,"context_lines":[{"line_number":72,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":73,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":74,"context_line":"                   % {\u0027max\u0027: instance.MAX_TAG_COUNT, \u0027count\u0027: tag_count})"},{"line_number":75,"context_line":"            raise exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":76,"context_line":"        try:"},{"line_number":77,"context_line":"            objects.TagList.create(context, server_id, body[\u0027tags\u0027])"},{"line_number":78,"context_line":"        except exception.InstanceNotFound as e:"}],"source_content_type":"text/x-python","patch_set":30,"id":"1a930d6b_1a0dbc37","line":75,"updated":"2015-01-24 00:20:54.000000000","message":"HTTPBadRequest","commit_id":"008845b30faa71d74b1bd8d2841696f642b24d87"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3f9b9630f855146309f391e65db10d40b8b0d47b","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        tags \u003d [t.tag for t in tags]"},{"line_number":45,"context_line":"        self._extend_instance(instance_resp, tags)"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"    def update(self, req, server_id, id, body):"},{"line_number":48,"context_line":"        context \u003d req.environ[\"nova.context\"]"},{"line_number":49,"context_line":"        authorize(context)"},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_513d1dc3","line":47,"updated":"2015-01-27 12:00:42.000000000","message":"How about add a json-schema just make this body is empty?","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"b08cf9adc20daf91f106c033ca13f78e7e4502a4","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        tags \u003d [t.tag for t in tags]"},{"line_number":45,"context_line":"        self._extend_instance(instance_resp, tags)"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"    def update(self, req, server_id, id, body):"},{"line_number":48,"context_line":"        context \u003d req.environ[\"nova.context\"]"},{"line_number":49,"context_line":"        authorize(context)"},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_c263fd3f","line":47,"in_reply_to":"1a930d6b_513d1dc3","updated":"2015-01-27 16:31:41.000000000","message":"ok","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3f9b9630f855146309f391e65db10d40b8b0d47b","unresolved":false,"context_lines":[{"line_number":58,"context_line":"                   % instance.MAX_TAG_COUNT)"},{"line_number":59,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"        tag \u003d objects.Tag(resource_id\u003dserver_id, tag\u003did)"},{"line_number":62,"context_line":"        tag.create(context)"},{"line_number":63,"context_line":"        return exc.HTTPNoContent()"},{"line_number":64,"context_line":""}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_b15c811a","line":61,"updated":"2015-01-27 12:00:42.000000000","message":"we should validate the id i\u003c tag_obj.MAX_TAG_LENGTH","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"b08cf9adc20daf91f106c033ca13f78e7e4502a4","unresolved":false,"context_lines":[{"line_number":58,"context_line":"                   % instance.MAX_TAG_COUNT)"},{"line_number":59,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"        tag \u003d objects.Tag(resource_id\u003dserver_id, tag\u003did)"},{"line_number":62,"context_line":"        tag.create(context)"},{"line_number":63,"context_line":"        return exc.HTTPNoContent()"},{"line_number":64,"context_line":""}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_025a6582","line":61,"in_reply_to":"1a930d6b_b15c811a","updated":"2015-01-27 16:31:41.000000000","message":"ok","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3f9b9630f855146309f391e65db10d40b8b0d47b","unresolved":false,"context_lines":[{"line_number":59,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"        tag \u003d objects.Tag(resource_id\u003dserver_id, tag\u003did)"},{"line_number":62,"context_line":"        tag.create(context)"},{"line_number":63,"context_line":"        return exc.HTTPNoContent()"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    @validation.schema(schema.create)"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_f1052911","line":62,"updated":"2015-01-27 12:00:42.000000000","message":"there should catch InstanceNotFound","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"b08cf9adc20daf91f106c033ca13f78e7e4502a4","unresolved":false,"context_lines":[{"line_number":59,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"        tag \u003d objects.Tag(resource_id\u003dserver_id, tag\u003did)"},{"line_number":62,"context_line":"        tag.create(context)"},{"line_number":63,"context_line":"        return exc.HTTPNoContent()"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    @validation.schema(schema.create)"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_42570d58","line":62,"in_reply_to":"1a930d6b_f1052911","updated":"2015-01-27 16:31:41.000000000","message":"ok","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3f9b9630f855146309f391e65db10d40b8b0d47b","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        authorize(context)"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"        tag_count \u003d len(body[\u0027tags\u0027])"},{"line_number":71,"context_line":"        if tag_count \u003e instance.MAX_TAG_COUNT:"},{"line_number":72,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":73,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":74,"context_line":"                   % {\u0027max\u0027: instance.MAX_TAG_COUNT, \u0027count\u0027: tag_count})"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_31f6d1f9","line":71,"updated":"2015-01-27 12:00:42.000000000","message":"this also can be validated by json-schema I guess","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"b08cf9adc20daf91f106c033ca13f78e7e4502a4","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        authorize(context)"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"        tag_count \u003d len(body[\u0027tags\u0027])"},{"line_number":71,"context_line":"        if tag_count \u003e instance.MAX_TAG_COUNT:"},{"line_number":72,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":73,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":74,"context_line":"                   % {\u0027max\u0027: instance.MAX_TAG_COUNT, \u0027count\u0027: tag_count})"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_82e495ac","line":71,"in_reply_to":"1a930d6b_31f6d1f9","updated":"2015-01-27 16:31:41.000000000","message":"Yes, it can be. But I validate it by this check because I want to return good exception message.\n\nYou can find my explanation in comments for patch set 29:\n\n\"I think validation by schema is worse than validation by \"if tag_cont \u003c max_tag_count\" because in second case we can customize error message.\n\nFor example error message of schema validation is \" Invalid input for field/attribute tags. Value: [\u00271\u0027, \u00272\u0027, \u00273\u0027 ...... \u002750\u0027] is too long.\u0027\"\n\nHere we have no information about maximum tag count and current tag count in request body.\n\nIf we use \"if tag_cont \u003c max_tag_count\" validation we got message \"The number of tags exceeded the per-server limit 50. Tag count it request body is 60.\"\n\nSo I think we shouldn\u0027t use schema to validate tag count.\"","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"b9e2dfb9d39e3c3a0955ce676c5444303f03637b","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from nova.objects import tag as tag_obj"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"ALIAS \u003d \"os-instance-tags\""},{"line_number":27,"context_line":"authorize \u003d extensions.extension_authorizer(\u0027compute\u0027, \u0027v3:\u0027 + ALIAS)"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"ba7be1f8_36afeb7e","line":26,"updated":"2015-02-24 23:30:40.000000000","message":"os-server-tags instead","commit_id":"e2e2cee3069b422add897a1e203f7079ad7ed6b4"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"b9e2dfb9d39e3c3a0955ce676c5444303f03637b","unresolved":false,"context_lines":[{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"class InstanceTagsController(wsgi.Controller):"},{"line_number":31,"context_line":"    def _extend_instance(self, instance, tags):"},{"line_number":32,"context_line":"        key \u003d \"%s:tags\" % InstanceTags.alias"},{"line_number":33,"context_line":"        instance[key] \u003d tags"},{"line_number":34,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"ba7be1f8_968897c6","line":31,"updated":"2015-02-24 23:30:40.000000000","message":"maybe I just missed it, but I don\u0027t see extend_instance called from anywhere?","commit_id":"e2e2cee3069b422add897a1e203f7079ad7ed6b4"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"b9e2dfb9d39e3c3a0955ce676c5444303f03637b","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @wsgi.Controller.api_version(\"2.3\")"},{"line_number":36,"context_line":"    @validation.schema(schema.update)"},{"line_number":37,"context_line":"    def update(self, req, server_id, id, body):"},{"line_number":38,"context_line":"        context \u003d req.environ[\"nova.context\"]"},{"line_number":39,"context_line":"        authorize(context)"},{"line_number":40,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"ba7be1f8_764163a8","line":37,"updated":"2015-02-24 23:30:40.000000000","message":"on each api method you\u0027ll also need to use the expected_errors decorator (http error status codes that could occur during normal operation)","commit_id":"e2e2cee3069b422add897a1e203f7079ad7ed6b4"}],"nova/api/openstack/compute/plugins/v3/server_tags.py":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"68f28c92f6b3a593fab8852a85bb9733b78be6ae","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    @wsgi.Controller.api_version(\"2.4\")"},{"line_number":36,"context_line":"    @extensions.expected_errors(404)"},{"line_number":37,"context_line":"    @wsgi.extends"},{"line_number":38,"context_line":"    def show(self, req, resp_obj, id):"},{"line_number":39,"context_line":"        context \u003d req.environ[\"nova.context\"]"},{"line_number":40,"context_line":"        authorize(context)"},{"line_number":41,"context_line":""}],"source_content_type":"text/x-python","patch_set":45,"id":"bab921fb_c7ddb643","line":38,"updated":"2015-04-24 08:28:04.000000000","message":"So, I was expecting to see just a list of tags for this URL:\n/servers/{uuid}/tags\n\nDo we not have this implemented here.","commit_id":"2c7ccfce35f147c994e7b9270b581d4f9fd49ec8"},{"author":{"_account_id":12175,"name":"Eli Qiao","email":"qiaoliyong@gmail.com","username":"Eli"},"change_message_id":"6fc1ffb6f2b34a9537859f8ac5d5342785e6d705","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        else:"},{"line_number":49,"context_line":"            msg \u003d (_(\"Server %(server_id)s has no tag \u0027%(tag)s\u0027\")"},{"line_number":50,"context_line":"                   % {\u0027server_id\u0027: server_id, \u0027tag\u0027: id})"},{"line_number":51,"context_line":"            raise exc.HTTPNotFound(explanation\u003dmsg)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    @wsgi.Controller.api_version(\"2.7\")"},{"line_number":54,"context_line":"    @extensions.expected_errors(404)"}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_44245bae","line":51,"updated":"2015-07-17 07:42:31.000000000","message":"how about this?\n\n@wsgi.Controller.api_version(\"2.7\")\n@wsgi.response(204)\n@extensions.expected_errors(404)\ndef show(self, req, server_id, id):\n...\nif not if exists:\n...\n raise exc.HTTPNotFound(explanation\u003dmsg)\n\nthen you don\u0027t need to call return exc.HTTPNoContent() explicitly.","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"20245033c58ca33b6e0751039b3f6702a13bcb85","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            tag.create()"},{"line_number":92,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":93,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":94,"context_line":"        except exception.InstanceTagExists:"},{"line_number":95,"context_line":"            return exc.HTTPNoContent()"},{"line_number":96,"context_line":"        return exc.HTTPCreated()"},{"line_number":97,"context_line":""}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_3e195722","line":94,"updated":"2015-07-16 11:17:44.000000000","message":"How about we check \"id in tags\", then we can save one extra db call.","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"68b5dcf78f75078e26ae14c6ec747737a16bcb94","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            tag.create()"},{"line_number":92,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":93,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":94,"context_line":"        except exception.InstanceTagExists:"},{"line_number":95,"context_line":"            return exc.HTTPNoContent()"},{"line_number":96,"context_line":"        return exc.HTTPCreated()"},{"line_number":97,"context_line":""}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_9fb2d305","line":94,"in_reply_to":"9a41bdd9_3e195722","updated":"2015-07-16 14:11:09.000000000","message":"Hi, Alex! Thank you for comment!\n\nTag has no id field. So we can\u0027t use it.\n\nWe do not use here any extra db call. We just raise exeption on db layer if tag existed and catch this exception here.\n\nhttps://review.openstack.org/#/c/201521/2/nova/db/sqlalchemy/api.py\n\nwhat kind of extra db call do you mean?","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"cdd19426e30d8115274ad740348f20882fb7bef1","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            tag.create()"},{"line_number":92,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":93,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":94,"context_line":"        except exception.InstanceTagExists:"},{"line_number":95,"context_line":"            return exc.HTTPNoContent()"},{"line_number":96,"context_line":"        return exc.HTTPCreated()"},{"line_number":97,"context_line":""}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_c25ac42a","line":94,"in_reply_to":"9a41bdd9_9fb2d305","updated":"2015-07-16 14:18:33.000000000","message":"the \u0027id\u0027 isn\u0027t tag\u0027s id, I mean the parameter of update method.\n\nThat exception is raised one add same data for unique key, that is returned from db. Correct me if I understand wrong.","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"be45be24b1630c0c7eb6f3fb939be5d7b8d0454e","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            tag.create()"},{"line_number":92,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":93,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":94,"context_line":"        except exception.InstanceTagExists:"},{"line_number":95,"context_line":"            return exc.HTTPNoContent()"},{"line_number":96,"context_line":"        return exc.HTTPCreated()"},{"line_number":97,"context_line":""}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_28758f31","line":94,"in_reply_to":"9a41bdd9_c25ac42a","updated":"2015-07-16 14:48:04.000000000","message":"Oh, I understood what you mean! Very good idea","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":12175,"name":"Eli Qiao","email":"qiaoliyong@gmail.com","username":"Eli"},"change_message_id":"6fc1ffb6f2b34a9537859f8ac5d5342785e6d705","unresolved":false,"context_lines":[{"line_number":93,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":94,"context_line":"        except exception.InstanceTagExists:"},{"line_number":95,"context_line":"            return exc.HTTPNoContent()"},{"line_number":96,"context_line":"        return exc.HTTPCreated()"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    @wsgi.Controller.api_version(\"2.7\")"},{"line_number":99,"context_line":"    @extensions.expected_errors((400, 404))"}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_0465f3df","line":96,"updated":"2015-07-17 07:42:31.000000000","message":"you may use\n@wsgi.response(201)","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":12175,"name":"Eli Qiao","email":"qiaoliyong@gmail.com","username":"Eli"},"change_message_id":"d53529b942bafa9ce677852f2e01ce0aebba903d","unresolved":false,"context_lines":[{"line_number":93,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":94,"context_line":"        except exception.InstanceTagExists:"},{"line_number":95,"context_line":"            return exc.HTTPNoContent()"},{"line_number":96,"context_line":"        return exc.HTTPCreated()"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    @wsgi.Controller.api_version(\"2.7\")"},{"line_number":99,"context_line":"    @extensions.expected_errors((400, 404))"}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_2498376a","line":96,"in_reply_to":"9a41bdd9_0465f3df","updated":"2015-07-17 07:49:53.000000000","message":"oh, ignore this, you got another return at line 95.","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"20245033c58ca33b6e0751039b3f6702a13bcb85","unresolved":false,"context_lines":[{"line_number":103,"context_line":"        authorize(context)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"        tag_count \u003d len(body[\u0027tags\u0027])"},{"line_number":106,"context_line":"        if tag_count \u003e inst_obj.MAX_TAG_COUNT:"},{"line_number":107,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":108,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":109,"context_line":"                   % {\u0027max\u0027: inst_obj.MAX_TAG_COUNT, \u0027count\u0027: tag_count})"}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_09d69f4e","line":106,"updated":"2015-07-16 11:17:44.000000000","message":"we also need check each tag\u0027s length like line 83","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"68b5dcf78f75078e26ae14c6ec747737a16bcb94","unresolved":false,"context_lines":[{"line_number":103,"context_line":"        authorize(context)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"        tag_count \u003d len(body[\u0027tags\u0027])"},{"line_number":106,"context_line":"        if tag_count \u003e inst_obj.MAX_TAG_COUNT:"},{"line_number":107,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":108,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":109,"context_line":"                   % {\u0027max\u0027: inst_obj.MAX_TAG_COUNT, \u0027count\u0027: tag_count})"}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_3f72a74a","line":106,"in_reply_to":"9a41bdd9_09d69f4e","updated":"2015-07-16 14:11:09.000000000","message":"Good idea, Thanks!","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":12175,"name":"Eli Qiao","email":"qiaoliyong@gmail.com","username":"Eli"},"change_message_id":"6fc1ffb6f2b34a9537859f8ac5d5342785e6d705","unresolved":false,"context_lines":[{"line_number":127,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":128,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":129,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":130,"context_line":"        return exc.HTTPNoContent()"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    @wsgi.Controller.api_version(\"2.7\")"},{"line_number":133,"context_line":"    @extensions.expected_errors(404)"}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_a461a7d5","line":130,"updated":"2015-07-17 07:42:31.000000000","message":"you may use @wsgi.response(204)","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":12175,"name":"Eli Qiao","email":"qiaoliyong@gmail.com","username":"Eli"},"change_message_id":"6fc1ffb6f2b34a9537859f8ac5d5342785e6d705","unresolved":false,"context_lines":[{"line_number":139,"context_line":"            objects.TagList.destroy(context, server_id)"},{"line_number":140,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":141,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":142,"context_line":"        return exc.HTTPNoContent()"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"class ServerTagsExtendedController(wsgi.Controller):"}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_c45e2b12","line":142,"updated":"2015-07-17 07:42:31.000000000","message":"you may use @wsgi.response(204)","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"20245033c58ca33b6e0751039b3f6702a13bcb85","unresolved":false,"context_lines":[{"line_number":178,"context_line":"                                               collection_name\u003d\u0027servers\u0027),"},{"line_number":179,"context_line":"                                           collection_actions\u003d{"},{"line_number":180,"context_line":"                                               \u0027delete_all\u0027: \u0027DELETE\u0027,"},{"line_number":181,"context_line":"                                               \u0027create\u0027: \u0027PUT\u0027})"},{"line_number":182,"context_line":"        return [res]"}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_09a1bff7","line":181,"updated":"2015-07-16 11:17:44.000000000","message":"I prefer to call this as update_all, otherwise it is a little confused. Because in normally we think create equal to POST","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"19f817c03a06fbde80b8d09c3743bb6b863408f5","unresolved":false,"context_lines":[{"line_number":85,"context_line":"                                         \u0027length\u0027: tag_obj.MAX_TAG_LENGTH})"},{"line_number":86,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        if id in _convert_tags_from_db_object(tags):"},{"line_number":89,"context_line":"            # NOTE(snikitin): server already has specified tag"},{"line_number":90,"context_line":"            return exc.HTTPNoContent()"},{"line_number":91,"context_line":""}],"source_content_type":"text/x-python","patch_set":56,"id":"3a50d1a3_2146a8bf","line":88,"updated":"2015-07-21 13:14:02.000000000","message":"tags isn\u0027t db object. It is nova object.","commit_id":"604050ae30c71fbb04626ba822960d969e0ed37b"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"068d93c7042fe34aeb16749e8fa9ebe267122726","unresolved":false,"context_lines":[{"line_number":85,"context_line":"                                         \u0027length\u0027: tag_obj.MAX_TAG_LENGTH})"},{"line_number":86,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        if id in _convert_tags_from_db_object(tags):"},{"line_number":89,"context_line":"            # NOTE(snikitin): server already has specified tag"},{"line_number":90,"context_line":"            return exc.HTTPNoContent()"},{"line_number":91,"context_line":""}],"source_content_type":"text/x-python","patch_set":56,"id":"3a50d1a3_274b18b2","line":88,"in_reply_to":"3a50d1a3_2146a8bf","updated":"2015-07-21 13:28:53.000000000","message":"ok. I will rename","commit_id":"604050ae30c71fbb04626ba822960d969e0ed37b"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"19f817c03a06fbde80b8d09c3743bb6b863408f5","unresolved":false,"context_lines":[{"line_number":117,"context_line":"            msg \u003d (_(\"Tags %(tags)s are too long. Maximum length of a tag \""},{"line_number":118,"context_line":"                     \"is %(length)d\") % {\u0027tags\u0027: long_tags,"},{"line_number":119,"context_line":"                                         \u0027length\u0027: tag_obj.MAX_TAG_LENGTH})"},{"line_number":120,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"        try:"},{"line_number":123,"context_line":"            tags \u003d objects.TagList.create(context, server_id, body[\u0027tags\u0027])"}],"source_content_type":"text/x-python","patch_set":56,"id":"3a50d1a3_21a78850","line":120,"updated":"2015-07-21 13:14:02.000000000","message":"oops, sorry, this is my fault. We can just put this in the json-schema, and I totally miss that you already put in the schema in the previous patch.","commit_id":"604050ae30c71fbb04626ba822960d969e0ed37b"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"068d93c7042fe34aeb16749e8fa9ebe267122726","unresolved":false,"context_lines":[{"line_number":117,"context_line":"            msg \u003d (_(\"Tags %(tags)s are too long. Maximum length of a tag \""},{"line_number":118,"context_line":"                     \"is %(length)d\") % {\u0027tags\u0027: long_tags,"},{"line_number":119,"context_line":"                                         \u0027length\u0027: tag_obj.MAX_TAG_LENGTH})"},{"line_number":120,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"        try:"},{"line_number":123,"context_line":"            tags \u003d objects.TagList.create(context, server_id, body[\u0027tags\u0027])"}],"source_content_type":"text/x-python","patch_set":56,"id":"3a50d1a3_277eb8ae","line":120,"in_reply_to":"3a50d1a3_21a78850","updated":"2015-07-21 13:28:53.000000000","message":"But I think that this catching is better, because here we can create informative error message and put all \"bad\" tags to this message.","commit_id":"604050ae30c71fbb04626ba822960d969e0ed37b"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"244bb7c187fbd5e9670f6407b5dc6685761c64d3","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":2,"context_line":"#    not use this file except in compliance with the License. You may obtain"},{"line_number":3,"context_line":"#    a copy of the License at"},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":61,"id":"3a50d1a3_d1f32b9e","line":1,"updated":"2015-07-25 20:14:24.000000000","message":"This file should be:\n\n /nova/api/openstack/compute/server_tags.py","commit_id":"73d3d2bf93a5e8271330b175b476b3fb3bb6ec13"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"244bb7c187fbd5e9670f6407b5dc6685761c64d3","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"ALIAS \u003d \"os-server-tags\""},{"line_number":27,"context_line":"authorize \u003d extensions.os_compute_authorizer(ALIAS)"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"def _get_tags_names(tags):"}],"source_content_type":"text/x-python","patch_set":61,"id":"3a50d1a3_71f2579c","line":27,"updated":"2015-07-25 20:14:24.000000000","message":"No API extensions. This file should be modeled after the server metadata Controller:\n\nhttps://github.com/openstack/nova/blob/master/nova/api/openstack/compute/server_metadata.py\n\nNOT an API extension.","commit_id":"73d3d2bf93a5e8271330b175b476b3fb3bb6ec13"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"81e81b2988cab8dc1a179ad76a23991d9ce3c3c3","unresolved":false,"context_lines":[{"line_number":153,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"class ServerTagsExtendedController(wsgi.Controller):"},{"line_number":157,"context_line":"    @wsgi.Controller.api_version(\"2.11\")"},{"line_number":158,"context_line":"    @extensions.expected_errors(404)"},{"line_number":159,"context_line":"    @wsgi.extends"}],"source_content_type":"text/x-python","patch_set":70,"id":"1a4dcd0f_2a109a58","line":156,"range":{"start_line":156,"start_character":6,"end_line":156,"end_character":34},"updated":"2015-08-05 16:03:02.000000000","message":"I  think this is the bit that shouldn\u0027t be done here, it should go into the main API controller classes as a new microversion, I think.","commit_id":"ff8aa80e5ff72d7dd31cb37ef8fcb52330ec250f"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"71bc65f5f6a84f260050e39b62e90a5a5e5baafb","unresolved":false,"context_lines":[{"line_number":153,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"class ServerTagsExtendedController(wsgi.Controller):"},{"line_number":157,"context_line":"    @wsgi.Controller.api_version(\"2.11\")"},{"line_number":158,"context_line":"    @extensions.expected_errors(404)"},{"line_number":159,"context_line":"    @wsgi.extends"}],"source_content_type":"text/x-python","patch_set":70,"id":"1a4dcd0f_816090d0","line":156,"in_reply_to":"1a4dcd0f_2a109a58","updated":"2015-08-06 10:04:32.000000000","message":"agree","commit_id":"ff8aa80e5ff72d7dd31cb37ef8fcb52330ec250f"}],"nova/api/openstack/compute/plugins/v3/servers.py":[{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"b9e2dfb9d39e3c3a0955ce676c5444303f03637b","unresolved":false,"context_lines":[{"line_number":470,"context_line":"        except TypeError:"},{"line_number":471,"context_line":"            return None"},{"line_number":472,"context_line":""},{"line_number":473,"context_line":"    @wsgi.Controller.api_version(\"2.3\")"},{"line_number":474,"context_line":"    @extensions.expected_errors(404)"},{"line_number":475,"context_line":"    def show(self, req, id):"},{"line_number":476,"context_line":"        \"\"\"Returns server details by server id.\"\"\""}],"source_content_type":"text/x-python","patch_set":36,"id":"ba7be1f8_f448ec5d","line":473,"updated":"2015-02-24 23:30:40.000000000","message":"So this shouldn\u0027t be necessary. I think you can leave the show as it was originally except you\u0027ll need to cache the extra data. You\u0027re just adding things to the output aren;t you?\n\nin the instance_tags.py you can use @wsgi.extends decorator on a show method. You get passed a response object and a db cache of the data you need to add, See some of the extended_*.py files in the plugins directeory for examples.  \n\nThere currently is a bug when using wsgi_extends and api_version decorator on the same method at this time (hopefully fix will be up today). If you do hit, you can instead not use the api_version decorator for show and instead do a manual comparison (see doc I referred to elsewhere in this changeset) where you can decided whether or not to add the extra info to the output depending on the version requested.","commit_id":"e2e2cee3069b422add897a1e203f7079ad7ed6b4"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"87f5789f3133fe07a205b7179485feca2208a5a0","unresolved":false,"context_lines":[{"line_number":470,"context_line":"        except TypeError:"},{"line_number":471,"context_line":"            return None"},{"line_number":472,"context_line":""},{"line_number":473,"context_line":"    @wsgi.Controller.api_version(\"2.3\")"},{"line_number":474,"context_line":"    @extensions.expected_errors(404)"},{"line_number":475,"context_line":"    def show(self, req, id):"},{"line_number":476,"context_line":"        \"\"\"Returns server details by server id.\"\"\""}],"source_content_type":"text/x-python","patch_set":36,"id":"ba7be1f8_7d82cdc8","line":473,"in_reply_to":"ba7be1f8_f448ec5d","updated":"2015-02-26 15:39:35.000000000","message":"actually I did it because of wsgi.extends bug. I will wait for your fix","commit_id":"e2e2cee3069b422add897a1e203f7079ad7ed6b4"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"c730f2311f5b6513fa685159dec26a29715df57d","unresolved":false,"context_lines":[{"line_number":386,"context_line":""},{"line_number":387,"context_line":"        if is_detail:"},{"line_number":388,"context_line":"            instance_list.fill_faults()"},{"line_number":389,"context_line":"            response \u003d self._view_builder.detail(req, instance_list)"},{"line_number":390,"context_line":"        else:"},{"line_number":391,"context_line":"            response \u003d self._view_builder.index(req, instance_list)"},{"line_number":392,"context_line":"        req.cache_db_instances(instance_list)"}],"source_content_type":"text/x-python","patch_set":71,"id":"1a4dcd0f_41dfe80c","line":389,"updated":"2015-08-06 10:14:20.000000000","message":"I wonder if tags should be here as well, or did we say to exclude that in the spec?","commit_id":"bbd0253f0a227270420e6632349945e72e3ae98f"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"9dadc5faa845c7458736ade96f2324686f7a66c2","unresolved":false,"context_lines":[{"line_number":386,"context_line":""},{"line_number":387,"context_line":"        if is_detail:"},{"line_number":388,"context_line":"            instance_list.fill_faults()"},{"line_number":389,"context_line":"            response \u003d self._view_builder.detail(req, instance_list)"},{"line_number":390,"context_line":"        else:"},{"line_number":391,"context_line":"            response \u003d self._view_builder.index(req, instance_list)"},{"line_number":392,"context_line":"        req.cache_db_instances(instance_list)"}],"source_content_type":"text/x-python","patch_set":71,"id":"1a4dcd0f_24442a19","line":389,"in_reply_to":"1a4dcd0f_41dfe80c","updated":"2015-08-06 10:29:11.000000000","message":"strictly speaking, there is no information about this case in the spec. But we could add tags here. Do we need it?","commit_id":"bbd0253f0a227270420e6632349945e72e3ae98f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"331ba7c86aaeaaf400ad8d353261fddf6faf4ff4","unresolved":false,"context_lines":[{"line_number":499,"context_line":"                tags \u003d objects.TagList.get_by_resource_id(context, id)"},{"line_number":500,"context_line":"            except exception.InstanceNotFound as e:"},{"line_number":501,"context_line":"                raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":502,"context_line":"            server[\u0027server\u0027][\u0027tags\u0027] \u003d [t.tag for t in tags]"},{"line_number":503,"context_line":"        return server"},{"line_number":504,"context_line":""},{"line_number":505,"context_line":"    @wsgi.response(202)"}],"source_content_type":"text/x-python","patch_set":71,"id":"1a4dcd0f_41be0866","line":502,"updated":"2015-08-06 10:17:42.000000000","message":"this is good, I think, I just can\u0027t find what is testing it.","commit_id":"bbd0253f0a227270420e6632349945e72e3ae98f"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"9dadc5faa845c7458736ade96f2324686f7a66c2","unresolved":false,"context_lines":[{"line_number":499,"context_line":"                tags \u003d objects.TagList.get_by_resource_id(context, id)"},{"line_number":500,"context_line":"            except exception.InstanceNotFound as e:"},{"line_number":501,"context_line":"                raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":502,"context_line":"            server[\u0027server\u0027][\u0027tags\u0027] \u003d [t.tag for t in tags]"},{"line_number":503,"context_line":"        return server"},{"line_number":504,"context_line":""},{"line_number":505,"context_line":"    @wsgi.response(202)"}],"source_content_type":"text/x-python","patch_set":71,"id":"1a4dcd0f_c4df8667","line":502,"in_reply_to":"1a4dcd0f_41be0866","updated":"2015-08-06 10:29:11.000000000","message":"here. \n\nhttps://review.openstack.org/#/c/128940/71/nova/tests/unit/api/openstack/compute/contrib/test_server_tags.py\n\nBut I could duplicate this test in test_servers. Do we need it?","commit_id":"bbd0253f0a227270420e6632349945e72e3ae98f"}],"nova/api/openstack/compute/schemas/server_tags.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"be19ed68e5630869cbcbd343dfa0ada4c6d6c78b","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"update \u003d {"},{"line_number":34,"context_line":"    \"title\": \"Server tag\","},{"line_number":35,"context_line":"    \"type\": \"object\","},{"line_number":36,"context_line":"    \u0027required\u0027: [],"},{"line_number":37,"context_line":"    \u0027additionalProperties\u0027: False"},{"line_number":38,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":105,"id":"ba63e191_8be4b43b","line":35,"range":{"start_line":35,"start_character":4,"end_line":35,"end_character":20},"updated":"2016-01-19 06:18:04.000000000","message":"as api-wg guideline, there isn\u0027t body. I think we can write \"type\": \"null\" at here.","commit_id":"d3b90a83d163c8a9cb14bc7042c40bc54b046010"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"66667f7eaebf80d64afbf2f5cc0095e053f0ec05","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"update \u003d {"},{"line_number":34,"context_line":"    \"title\": \"Server tag\","},{"line_number":35,"context_line":"    \"type\": \"object\","},{"line_number":36,"context_line":"    \u0027required\u0027: [],"},{"line_number":37,"context_line":"    \u0027additionalProperties\u0027: False"},{"line_number":38,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":105,"id":"ba63e191_2b3a5e37","line":35,"range":{"start_line":35,"start_character":4,"end_line":35,"end_character":20},"in_reply_to":"ba63e191_8be4b43b","updated":"2016-01-19 09:59:01.000000000","message":"yep, you are right","commit_id":"d3b90a83d163c8a9cb14bc7042c40bc54b046010"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"b1e73a35266538269eae186cfe79b85ad1548567","unresolved":false,"context_lines":[{"line_number":13,"context_line":"update_all \u003d {"},{"line_number":14,"context_line":"    \"definitions\": {"},{"line_number":15,"context_line":"        \"tag\": {"},{"line_number":16,"context_line":"            \"type\": \"string\""},{"line_number":17,"context_line":"        }"},{"line_number":18,"context_line":"    },"},{"line_number":19,"context_line":"    \"title\": \"Server tags\","}],"source_content_type":"text/x-python","patch_set":106,"id":"ba63e191_a0162e53","line":16,"range":{"start_line":16,"start_character":12,"end_line":16,"end_character":28},"updated":"2016-01-20 06:31:32.000000000","message":"This isn\u0027t enough. As the description at https://github.com/openstack/api-wg/blob/master/guidelines/tags.rst#tags-representation\n\nThere are some limit for tag name: \"the comma character is not allowed to be in a tag name.\"\n\nBut I think api-wg guideline didn\u0027t have enough definition also.\n\nLike we may have request like this \"GET /servers/1234567890/tags/abc\". So the tag will be used in the URL, there should be a limited character set allowed in the tag name. We probably need more clear definition about this.","commit_id":"10b33353efdf7a883309a3825cd61d1e57d959ca"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"57f42eca21857f98f91717210951a9d6fefc54fb","unresolved":false,"context_lines":[{"line_number":13,"context_line":"update_all \u003d {"},{"line_number":14,"context_line":"    \"definitions\": {"},{"line_number":15,"context_line":"        \"tag\": {"},{"line_number":16,"context_line":"            \"type\": \"string\""},{"line_number":17,"context_line":"        }"},{"line_number":18,"context_line":"    },"},{"line_number":19,"context_line":"    \"title\": \"Server tags\","}],"source_content_type":"text/x-python","patch_set":106,"id":"9a68dd71_f0bbf173","line":16,"range":{"start_line":16,"start_character":12,"end_line":16,"end_character":28},"in_reply_to":"ba63e191_a0162e53","updated":"2016-01-20 14:23:59.000000000","message":"good catch. As I understand commas will break filter request. But I don\u0027t want to check it in this schema because:\n\n1) in this case a user will get a error message like:\n\n  \u0027tag,1\u0027 does not match \u0027^[^.]*$\u0027\n\nI this is a very uninformative message because it contains regular expression. I think a user should not see difficult regexes.\n\n2) If body contains several invalid tags, we will get a error message about first invalid tag. I think it would be better to collect all invalid tags and say \"These tags are invalid: ****\" \n\nSo I think it would be better to validate it manually in controller","commit_id":"10b33353efdf7a883309a3825cd61d1e57d959ca"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"b3d798e229e9dcd3fd8be327c2a05375ce6f6e0a","unresolved":false,"context_lines":[{"line_number":38,"context_line":"update \u003d {"},{"line_number":39,"context_line":"    \"title\": \"Server tag\","},{"line_number":40,"context_line":"    \"type\": \"null\","},{"line_number":41,"context_line":"    \u0027required\u0027: [],"},{"line_number":42,"context_line":"    \u0027additionalProperties\u0027: False"},{"line_number":43,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":126,"id":"9a061dce_50734e4d","line":41,"updated":"2016-04-05 19:46:39.000000000","message":"Shouldn\u0027t something be required for the update call? What would be the purpose of an update call with no body?","commit_id":"6699ca36855feb53fa41ac85d1ba912bf151d0aa"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"6d6d5f7d89d979c8739a1dcabda0f37b03d8ef4a","unresolved":false,"context_lines":[{"line_number":38,"context_line":"update \u003d {"},{"line_number":39,"context_line":"    \"title\": \"Server tag\","},{"line_number":40,"context_line":"    \"type\": \"null\","},{"line_number":41,"context_line":"    \u0027required\u0027: [],"},{"line_number":42,"context_line":"    \u0027additionalProperties\u0027: False"},{"line_number":43,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":126,"id":"9a061dce_d89625ef","line":41,"in_reply_to":"9a061dce_1afb8c48","updated":"2016-04-06 20:04:15.000000000","message":"That makes sense. Thanks.","commit_id":"6699ca36855feb53fa41ac85d1ba912bf151d0aa"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"5ae10fdb93f43cec719288db9dea1d74915beef0","unresolved":false,"context_lines":[{"line_number":38,"context_line":"update \u003d {"},{"line_number":39,"context_line":"    \"title\": \"Server tag\","},{"line_number":40,"context_line":"    \"type\": \"null\","},{"line_number":41,"context_line":"    \u0027required\u0027: [],"},{"line_number":42,"context_line":"    \u0027additionalProperties\u0027: False"},{"line_number":43,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":126,"id":"9a061dce_1afb8c48","line":41,"in_reply_to":"9a061dce_50734e4d","updated":"2016-04-06 13:41:06.000000000","message":"The purpose is to add a single tag (\u0027tag1\u0027 for example) by the following request:\n\nPUT http://127.0.0.1:8774/v2.1/servers/12345/tags/tag1\n\nIn this case URL contains the name of new tag and UUID of server. That is why we need not body in this PUT request. URL has all needed information.","commit_id":"6699ca36855feb53fa41ac85d1ba912bf151d0aa"}],"nova/api/openstack/compute/schemas/v3/instance_tags.py":[{"author":{"_account_id":5638,"name":"Davanum Srinivas","email":"davanum@gmail.com","username":"dims-v"},"change_message_id":"3df74da5e1b5e3cc59c4cd97d16dd0512eeb0220","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    \"properties\": {"},{"line_number":26,"context_line":"        \"tags\": {"},{"line_number":27,"context_line":"            \"type\": \"array\","},{"line_number":28,"context_line":"            \"items\": {"},{"line_number":29,"context_line":"                \"$ref\": \"#/definitions/tag\""},{"line_number":30,"context_line":"            }"},{"line_number":31,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":29,"id":"1a930d6b_c74aaaab","line":28,"updated":"2015-01-23 03:09:01.000000000","message":"Can we validate the max number of items? (looks like 50 from the constant defined in the other file)","commit_id":"f0135dacb061a75dc588a187aa0c65188d44b529"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"2f64f3f1f006c3d7b4afb16092dda9769f95fb8a","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    \"properties\": {"},{"line_number":26,"context_line":"        \"tags\": {"},{"line_number":27,"context_line":"            \"type\": \"array\","},{"line_number":28,"context_line":"            \"items\": {"},{"line_number":29,"context_line":"                \"$ref\": \"#/definitions/tag\""},{"line_number":30,"context_line":"            }"},{"line_number":31,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":29,"id":"1a930d6b_c48ffbca","line":28,"in_reply_to":"1a930d6b_a6a67751","updated":"2015-01-23 11:15:23.000000000","message":"I tried to validate tag count by schema. I think validation by schema is worse than validation by \"if tag_cont \u003c max_tag_count\" because in second case we can customize error message. \n\nFor example error message of schema validation is \" Invalid input for field/attribute tags. Value: [\u00271\u0027, \u00272\u0027, \u00273\u0027 ...... \u002750\u0027] is too long.\u0027\" \nHere we have no information about maximum tag count and current tag count in request body.\n\nIf we use \"if tag_cont \u003c max_tag_count\" validation we got message \"The number of tags exceeded the per-server limit 50. Tag count it request body is 60.\"\n\nSo I think we shouldn\u0027t use schema to validate tag count.","commit_id":"f0135dacb061a75dc588a187aa0c65188d44b529"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"8bf3140dedd98b47f7bba157cf1db40e263cf97c","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    \"properties\": {"},{"line_number":26,"context_line":"        \"tags\": {"},{"line_number":27,"context_line":"            \"type\": \"array\","},{"line_number":28,"context_line":"            \"items\": {"},{"line_number":29,"context_line":"                \"$ref\": \"#/definitions/tag\""},{"line_number":30,"context_line":"            }"},{"line_number":31,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":29,"id":"1a930d6b_a6a67751","line":28,"in_reply_to":"1a930d6b_c74aaaab","updated":"2015-01-23 10:21:26.000000000","message":"We validate it here https://review.openstack.org/#/c/128940/29/nova/api/openstack/compute/plugins/v3/instance_tags.py Line 71. But if we will validate tag count in schemas, code became easier. Thank you for advice :)","commit_id":"f0135dacb061a75dc588a187aa0c65188d44b529"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3f9b9630f855146309f391e65db10d40b8b0d47b","unresolved":false,"context_lines":[{"line_number":29,"context_line":"                \"$ref\": \"#/definitions/tag\""},{"line_number":30,"context_line":"            }"},{"line_number":31,"context_line":"        }"},{"line_number":32,"context_line":"    }"},{"line_number":33,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_117c7571","line":32,"updated":"2015-01-27 12:00:42.000000000","message":"also need add:\n\n        \u0027required\u0027: [\u0027tags\u0027],\n        \u0027additionalProperties\u0027: False,","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"b08cf9adc20daf91f106c033ca13f78e7e4502a4","unresolved":false,"context_lines":[{"line_number":29,"context_line":"                \"$ref\": \"#/definitions/tag\""},{"line_number":30,"context_line":"            }"},{"line_number":31,"context_line":"        }"},{"line_number":32,"context_line":"    }"},{"line_number":33,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_02126561","line":32,"in_reply_to":"1a930d6b_117c7571","updated":"2015-01-27 16:31:41.000000000","message":"yep","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"}],"nova/api/openstack/compute/server_tags.py":[{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"14e96bd0a99e36ea567f93039417a72d7917e18c","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova import exception"},{"line_number":20,"context_line":"from nova.i18n import _"},{"line_number":21,"context_line":"from nova import objects"},{"line_number":22,"context_line":"from nova.objects import instance as inst_obj"},{"line_number":23,"context_line":"from nova.objects import tag as tag_obj"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""}],"source_content_type":"text/x-python","patch_set":80,"id":"7a2fa921_16055c13","line":22,"updated":"2015-10-11 16:49:01.000000000","message":"why do we need lines 22 and 23. Why not use:\nfrom nova import objects\n\nthen just use objects.instance and objects.tags...","commit_id":"e2f7ed67cf2b27f3d155621a15636c071c4d0a98"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9ea95fb631e0bd1f55cdd924fafc1de87ddc9dfa","unresolved":false,"context_lines":[{"line_number":110,"context_line":"                      \u0027count\u0027: tag_count})"},{"line_number":111,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"        long_tags \u003d ["},{"line_number":114,"context_line":"            t for t in body[\u0027tags\u0027] if len(t) \u003e objects.tag.MAX_TAG_LENGTH]"},{"line_number":115,"context_line":"        if long_tags:"},{"line_number":116,"context_line":"            msg \u003d (_(\"Tags %(tags)s are too long. Maximum length of a tag \""},{"line_number":117,"context_line":"                     \"is %(length)d\") % {\u0027tags\u0027: long_tags,"},{"line_number":118,"context_line":"                                         \u0027length\u0027: objects.tag.MAX_TAG_LENGTH})"},{"line_number":119,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        try:"},{"line_number":122,"context_line":"            tags \u003d objects.TagList.create(context, server_id, body[\u0027tags\u0027])"},{"line_number":123,"context_line":"        except exception.InstanceNotFound as e:"}],"source_content_type":"text/x-python","patch_set":92,"id":"5a710552_cb093a97","line":120,"range":{"start_line":113,"start_character":7,"end_line":120,"end_character":0},"updated":"2015-12-15 14:50:03.000000000","message":"Can this be checked with the maxLength of the string in the jsonschema?","commit_id":"89e3586b16b8d787c9385ce7d2bc0674de2812f4"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"14037e4646d48b1224a462d52644e798f35a0026","unresolved":false,"context_lines":[{"line_number":117,"context_line":"                     \"is %(length)d\") % {\u0027tags\u0027: long_tags,"},{"line_number":118,"context_line":"                                         \u0027length\u0027: objects.tag.MAX_TAG_LENGTH})"},{"line_number":119,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        try:"},{"line_number":122,"context_line":"            tags \u003d objects.TagList.create(context, server_id, body[\u0027tags\u0027])"},{"line_number":123,"context_line":"        except exception.InstanceNotFound as e:"}],"source_content_type":"text/x-python","patch_set":92,"id":"5a710552_f6ca9f6d","line":120,"in_reply_to":"5a710552_cb093a97","updated":"2015-12-16 14:18:39.000000000","message":"If it will be checked in schema in case of error we will get something like \"string is to long.\" It\u0027s not informative message.\n\nHere we collect *all* long tags and create informative message.","commit_id":"89e3586b16b8d787c9385ce7d2bc0674de2812f4"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"ee15d958e3b1903b6896c0d82c4d11a9c5889c1d","unresolved":false,"context_lines":[{"line_number":117,"context_line":"                     \"is %(length)d\") % {\u0027tags\u0027: long_tags,"},{"line_number":118,"context_line":"                                         \u0027length\u0027: objects.tag.MAX_TAG_LENGTH})"},{"line_number":119,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        try:"},{"line_number":122,"context_line":"            tags \u003d objects.TagList.create(context, server_id, body[\u0027tags\u0027])"},{"line_number":123,"context_line":"        except exception.InstanceNotFound as e:"}],"source_content_type":"text/x-python","patch_set":92,"id":"3a7e1126_cc4f1691","line":120,"in_reply_to":"5a710552_f6ca9f6d","updated":"2015-12-17 12:42:21.000000000","message":"OK, I got it.","commit_id":"89e3586b16b8d787c9385ce7d2bc0674de2812f4"},{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"1491b40e5f3e135501a7e6105b6c17075d0423e5","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"class ServerTagsController(wsgi.Controller):"},{"line_number":33,"context_line":"    @wsgi.response(204)"},{"line_number":34,"context_line":"    @extensions.expected_errors(404)"},{"line_number":35,"context_line":"    def show(self, req, server_id, id):"},{"line_number":36,"context_line":"        context \u003d req.environ[\"nova.context\"]"}],"source_content_type":"text/x-python","patch_set":106,"id":"ba63e191_45c21287","line":33,"range":{"start_line":33,"start_character":19,"end_line":33,"end_character":22},"updated":"2016-01-19 13:44:28.000000000","message":"sorry history too long so can\u0027t find this \n\nhttps://www.w3.org/Protocols/HTTP/HTRESP.html\nseems 204 is not correct for \u0027show\u0027 command?\n\nseems GET most time return 200?","commit_id":"10b33353efdf7a883309a3825cd61d1e57d959ca"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"e38304d6d1492317f45329f36b0740699f75288a","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"class ServerTagsController(wsgi.Controller):"},{"line_number":33,"context_line":"    @wsgi.response(204)"},{"line_number":34,"context_line":"    @extensions.expected_errors(404)"},{"line_number":35,"context_line":"    def show(self, req, server_id, id):"},{"line_number":36,"context_line":"        context \u003d req.environ[\"nova.context\"]"}],"source_content_type":"text/x-python","patch_set":106,"id":"ba63e191_b0eeaa89","line":33,"range":{"start_line":33,"start_character":19,"end_line":33,"end_character":22},"in_reply_to":"ba63e191_45c21287","updated":"2016-01-19 13:58:42.000000000","message":"yes, history is very long :)\n\nhere is a spec for this patch:\nhttps://specs.openstack.org/openstack/nova-specs/specs/mitaka/approved/tag-instances.html#rest-api-impact\n\nThis method should check if a tag exists or not on a server\nReturns 204 No Content if tag exist on a server.\nReturns 404 Not Found if tag doesn’t exist on a server.\n\nHonestly name \u0027show\u0027 is not quite right for this method. But I named it \u0027show\u0027 because \u0027show\u0027 is a default name for GET request which gets some resource by id. In this case I get resource \u0027tag\u0027 by id.","commit_id":"10b33353efdf7a883309a3825cd61d1e57d959ca"},{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"0d0c7a568b07128097d8cf260b9d628e6fa0eb86","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"class ServerTagsController(wsgi.Controller):"},{"line_number":33,"context_line":"    @wsgi.response(204)"},{"line_number":34,"context_line":"    @extensions.expected_errors(404)"},{"line_number":35,"context_line":"    def show(self, req, server_id, id):"},{"line_number":36,"context_line":"        context \u003d req.environ[\"nova.context\"]"}],"source_content_type":"text/x-python","patch_set":106,"id":"9a68dd71_6fc58a8c","line":33,"range":{"start_line":33,"start_character":19,"end_line":33,"end_character":22},"in_reply_to":"ba63e191_60a03691","updated":"2016-01-21 20:38:27.000000000","message":"ok, thanks for the sharing ,good to know it","commit_id":"10b33353efdf7a883309a3825cd61d1e57d959ca"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"b1e73a35266538269eae186cfe79b85ad1548567","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"class ServerTagsController(wsgi.Controller):"},{"line_number":33,"context_line":"    @wsgi.response(204)"},{"line_number":34,"context_line":"    @extensions.expected_errors(404)"},{"line_number":35,"context_line":"    def show(self, req, server_id, id):"},{"line_number":36,"context_line":"        context \u003d req.environ[\"nova.context\"]"}],"source_content_type":"text/x-python","patch_set":106,"id":"ba63e191_60a03691","line":33,"range":{"start_line":33,"start_character":19,"end_line":33,"end_character":22},"in_reply_to":"ba63e191_b0eeaa89","updated":"2016-01-20 06:31:32.000000000","message":"@jichenjc, yea, actually the api-wg guideline have definition for this also you can find it at https://github.com/openstack/api-wg/blob/master/guidelines/tags.rst#addressing-individual-tags\n\n\"To check if a tag exists or not, the client should send a GET request to the individual tag URL. If the tag exists, the server responds with a status code 204 and no response body. If the tag does not exist, the server responds with a status code 404.\"","commit_id":"10b33353efdf7a883309a3825cd61d1e57d959ca"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"b1e73a35266538269eae186cfe79b85ad1548567","unresolved":false,"context_lines":[{"line_number":90,"context_line":"            tag.create()"},{"line_number":91,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":92,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":93,"context_line":"        return exc.HTTPCreated()"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    @extensions.expected_errors((400, 404))"},{"line_number":96,"context_line":"    @validation.schema(schema.update_all)"}],"source_content_type":"text/x-python","patch_set":106,"id":"ba63e191_402892e2","line":93,"range":{"start_line":93,"start_character":8,"end_line":93,"end_character":32},"updated":"2016-01-20 06:31:32.000000000","message":"jichenjc\u0027s comment let me notice this in the api-wg guideline\nhttps://github.com/openstack/api-wg/blob/master/guidelines/tags.rst#addressing-individual-tags\n\nThere is Location header will return. But there isn\u0027t it.\nShould we add it?\n\n\"Location: http://example.com:8774/servers/1234567890/tags/qux\"","commit_id":"10b33353efdf7a883309a3825cd61d1e57d959ca"},{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"0d0c7a568b07128097d8cf260b9d628e6fa0eb86","unresolved":false,"context_lines":[{"line_number":90,"context_line":"            tag.create()"},{"line_number":91,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":92,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":93,"context_line":"        return exc.HTTPCreated()"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    @extensions.expected_errors((400, 404))"},{"line_number":96,"context_line":"    @validation.schema(schema.update_all)"}],"source_content_type":"text/x-python","patch_set":106,"id":"9a68dd71_2b430544","line":93,"range":{"start_line":93,"start_character":8,"end_line":93,"end_character":32},"in_reply_to":"ba63e191_402892e2","updated":"2016-01-21 20:38:27.000000000","message":"+1, good point","commit_id":"10b33353efdf7a883309a3825cd61d1e57d959ca"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"57f42eca21857f98f91717210951a9d6fefc54fb","unresolved":false,"context_lines":[{"line_number":90,"context_line":"            tag.create()"},{"line_number":91,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":92,"context_line":"            raise exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":93,"context_line":"        return exc.HTTPCreated()"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    @extensions.expected_errors((400, 404))"},{"line_number":96,"context_line":"    @validation.schema(schema.update_all)"}],"source_content_type":"text/x-python","patch_set":106,"id":"9a68dd71_1cdb411d","line":93,"range":{"start_line":93,"start_character":8,"end_line":93,"end_character":32},"in_reply_to":"ba63e191_402892e2","updated":"2016-01-20 14:23:59.000000000","message":"good point","commit_id":"10b33353efdf7a883309a3825cd61d1e57d959ca"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"b3d798e229e9dcd3fd8be327c2a05375ce6f6e0a","unresolved":false,"context_lines":[{"line_number":86,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        try:"},{"line_number":89,"context_line":"            jsonschema.validate(id, schema.tag)"},{"line_number":90,"context_line":"        except jsonschema.ValidationError as e:"},{"line_number":91,"context_line":"            msg \u003d (_(\"Tag \u0027%(tag)s\u0027 is invalid. It must be a string without \""},{"line_number":92,"context_line":"                     \"characters \u0027/\u0027 and \u0027,\u0027. Validation error message: \""}],"source_content_type":"text/x-python","patch_set":126,"id":"9a061dce_705772ce","line":89,"updated":"2016-04-05 19:46:39.000000000","message":"It seems like this should be the first check.","commit_id":"6699ca36855feb53fa41ac85d1ba912bf151d0aa"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"5ae10fdb93f43cec719288db9dea1d74915beef0","unresolved":false,"context_lines":[{"line_number":86,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        try:"},{"line_number":89,"context_line":"            jsonschema.validate(id, schema.tag)"},{"line_number":90,"context_line":"        except jsonschema.ValidationError as e:"},{"line_number":91,"context_line":"            msg \u003d (_(\"Tag \u0027%(tag)s\u0027 is invalid. It must be a string without \""},{"line_number":92,"context_line":"                     \"characters \u0027/\u0027 and \u0027,\u0027. Validation error message: \""}],"source_content_type":"text/x-python","patch_set":126,"id":"9a061dce_158fdf75","line":89,"in_reply_to":"9a061dce_705772ce","updated":"2016-04-06 13:41:06.000000000","message":"Done","commit_id":"6699ca36855feb53fa41ac85d1ba912bf151d0aa"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"b3d798e229e9dcd3fd8be327c2a05375ce6f6e0a","unresolved":false,"context_lines":[{"line_number":134,"context_line":"        invalid_tags \u003d []"},{"line_number":135,"context_line":"        for tag in body[\u0027tags\u0027]:"},{"line_number":136,"context_line":"            try:"},{"line_number":137,"context_line":"                jsonschema.validate(tag, schema.tag)"},{"line_number":138,"context_line":"            except jsonschema.ValidationError:"},{"line_number":139,"context_line":"                invalid_tags.append(tag)"},{"line_number":140,"context_line":"        if invalid_tags:"}],"source_content_type":"text/x-python","patch_set":126,"id":"9a061dce_b0062acc","line":137,"updated":"2016-04-05 19:46:39.000000000","message":"Same here. Invalid input to the API seems like the first thing that should be checked.","commit_id":"6699ca36855feb53fa41ac85d1ba912bf151d0aa"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"5ae10fdb93f43cec719288db9dea1d74915beef0","unresolved":false,"context_lines":[{"line_number":134,"context_line":"        invalid_tags \u003d []"},{"line_number":135,"context_line":"        for tag in body[\u0027tags\u0027]:"},{"line_number":136,"context_line":"            try:"},{"line_number":137,"context_line":"                jsonschema.validate(tag, schema.tag)"},{"line_number":138,"context_line":"            except jsonschema.ValidationError:"},{"line_number":139,"context_line":"                invalid_tags.append(tag)"},{"line_number":140,"context_line":"        if invalid_tags:"}],"source_content_type":"text/x-python","patch_set":126,"id":"9a061dce_b5955388","line":137,"in_reply_to":"9a061dce_b0062acc","updated":"2016-04-06 13:41:06.000000000","message":"Done","commit_id":"6699ca36855feb53fa41ac85d1ba912bf151d0aa"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"1390c271c83eac92c51828de750e03c8dc5eec0b","unresolved":false,"context_lines":[{"line_number":64,"context_line":"        return {\u0027tags\u0027: _get_tags_names(tags)}"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    @extensions.expected_errors((400, 404))"},{"line_number":67,"context_line":"    @validation.schema(schema.update)"},{"line_number":68,"context_line":"    def update(self, req, server_id, id, body):"},{"line_number":69,"context_line":"        context \u003d req.environ[\"nova.context\"]"},{"line_number":70,"context_line":"        authorize(context, action\u003d\u0027update\u0027)"}],"source_content_type":"text/x-python","patch_set":127,"id":"9a061dce_be8b4f67","line":67,"range":{"start_line":67,"start_character":4,"end_line":67,"end_character":37},"updated":"2016-04-07 02:44:28.000000000","message":"I did not get why we need to validate empty body? or we want to make sure that no request body in single tag update.","commit_id":"bfe8e7484da60242c6a35e0549e7a109c8fa38db"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"126d0b55189bbbd0beeaee8f0b1ebd81f03a401f","unresolved":false,"context_lines":[{"line_number":64,"context_line":"        return {\u0027tags\u0027: _get_tags_names(tags)}"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    @extensions.expected_errors((400, 404))"},{"line_number":67,"context_line":"    @validation.schema(schema.update)"},{"line_number":68,"context_line":"    def update(self, req, server_id, id, body):"},{"line_number":69,"context_line":"        context \u003d req.environ[\"nova.context\"]"},{"line_number":70,"context_line":"        authorize(context, action\u003d\u0027update\u0027)"}],"source_content_type":"text/x-python","patch_set":127,"id":"9a061dce_cffacf42","line":67,"range":{"start_line":67,"start_character":4,"end_line":67,"end_character":37},"in_reply_to":"9a061dce_be8b4f67","updated":"2016-04-07 05:40:31.000000000","message":"yes, we want to make sure that no request body in single tag update.","commit_id":"bfe8e7484da60242c6a35e0549e7a109c8fa38db"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"1390c271c83eac92c51828de750e03c8dc5eec0b","unresolved":false,"context_lines":[{"line_number":115,"context_line":"        context \u003d req.environ[\"nova.context\"]"},{"line_number":116,"context_line":"        authorize(context, action\u003d\u0027update_all\u0027)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"        invalid_tags \u003d []"},{"line_number":119,"context_line":"        for tag in body[\u0027tags\u0027]:"},{"line_number":120,"context_line":"            try:"},{"line_number":121,"context_line":"                jsonschema.validate(tag, schema.tag)"},{"line_number":122,"context_line":"            except jsonschema.ValidationError:"},{"line_number":123,"context_line":"                invalid_tags.append(tag)"},{"line_number":124,"context_line":"        if invalid_tags:"},{"line_number":125,"context_line":"            msg \u003d (_(\"Tags \u0027%s\u0027 are invalid. Each tag must be a string \""},{"line_number":126,"context_line":"                     \"without characters \u0027/\u0027 and \u0027,\u0027.\") % invalid_tags)"},{"line_number":127,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        tag_count \u003d len(body[\u0027tags\u0027])"},{"line_number":130,"context_line":"        if tag_count \u003e objects.instance.MAX_TAG_COUNT:"}],"source_content_type":"text/x-python","patch_set":127,"id":"9a061dce_fed6674d","line":127,"range":{"start_line":118,"start_character":0,"end_line":127,"end_character":53},"updated":"2016-04-07 02:44:28.000000000","message":"This is not something done with @validation.schema ?\n\nI mean we are validating each tag twice?\n\nPlease let me know if I missed any discussion/rational behind it.","commit_id":"bfe8e7484da60242c6a35e0549e7a109c8fa38db"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"1390c271c83eac92c51828de750e03c8dc5eec0b","unresolved":false,"context_lines":[{"line_number":126,"context_line":"                     \"without characters \u0027/\u0027 and \u0027,\u0027.\") % invalid_tags)"},{"line_number":127,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        tag_count \u003d len(body[\u0027tags\u0027])"},{"line_number":130,"context_line":"        if tag_count \u003e objects.instance.MAX_TAG_COUNT:"},{"line_number":131,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":132,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":133,"context_line":"                   % {\u0027max\u0027: objects.instance.MAX_TAG_COUNT,"},{"line_number":134,"context_line":"                      \u0027count\u0027: tag_count})"},{"line_number":135,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        long_tags \u003d ["},{"line_number":138,"context_line":"            t for t in body[\u0027tags\u0027] if len(t) \u003e objects.tag.MAX_TAG_LENGTH]"}],"source_content_type":"text/x-python","patch_set":127,"id":"9a061dce_9e748b68","line":135,"range":{"start_line":129,"start_character":0,"end_line":135,"end_character":53},"updated":"2016-04-07 02:44:28.000000000","message":"This can be done at schema with \"maxItems\" on array type.","commit_id":"bfe8e7484da60242c6a35e0549e7a109c8fa38db"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"126d0b55189bbbd0beeaee8f0b1ebd81f03a401f","unresolved":false,"context_lines":[{"line_number":126,"context_line":"                     \"without characters \u0027/\u0027 and \u0027,\u0027.\") % invalid_tags)"},{"line_number":127,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        tag_count \u003d len(body[\u0027tags\u0027])"},{"line_number":130,"context_line":"        if tag_count \u003e objects.instance.MAX_TAG_COUNT:"},{"line_number":131,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":132,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":133,"context_line":"                   % {\u0027max\u0027: objects.instance.MAX_TAG_COUNT,"},{"line_number":134,"context_line":"                      \u0027count\u0027: tag_count})"},{"line_number":135,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        long_tags \u003d ["},{"line_number":138,"context_line":"            t for t in body[\u0027tags\u0027] if len(t) \u003e objects.tag.MAX_TAG_LENGTH]"}],"source_content_type":"text/x-python","patch_set":127,"id":"9a061dce_ea886173","line":135,"range":{"start_line":129,"start_character":0,"end_line":135,"end_character":53},"in_reply_to":"9a061dce_09068785","updated":"2016-04-07 05:40:31.000000000","message":"In L113 we have a schema.update_all. This schema validate *only* that in body we have an array of strings and this array named \u0027tags\u0027. \n\nAll other validation like max len, max count or symbols \u0027,\u0027 and \u0027/\u0027 I want to check manually for better error message because I think that error message like \"Validation error: string \u0027tag,1\u0027 is not like regular expression \u0027^[^,/]*$\u0027\" is awful. The end user may not know what it is.","commit_id":"bfe8e7484da60242c6a35e0549e7a109c8fa38db"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"d3620807436451339bca9a51797263980a15c767","unresolved":false,"context_lines":[{"line_number":126,"context_line":"                     \"without characters \u0027/\u0027 and \u0027,\u0027.\") % invalid_tags)"},{"line_number":127,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        tag_count \u003d len(body[\u0027tags\u0027])"},{"line_number":130,"context_line":"        if tag_count \u003e objects.instance.MAX_TAG_COUNT:"},{"line_number":131,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":132,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":133,"context_line":"                   % {\u0027max\u0027: objects.instance.MAX_TAG_COUNT,"},{"line_number":134,"context_line":"                      \u0027count\u0027: tag_count})"},{"line_number":135,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        long_tags \u003d ["},{"line_number":138,"context_line":"            t for t in body[\u0027tags\u0027] if len(t) \u003e objects.tag.MAX_TAG_LENGTH]"}],"source_content_type":"text/x-python","patch_set":127,"id":"9a061dce_d8cc498b","line":135,"range":{"start_line":129,"start_character":0,"end_line":135,"end_character":53},"in_reply_to":"9a061dce_55a764bc","updated":"2016-04-07 09:45:15.000000000","message":"Ok, I agree on that.","commit_id":"bfe8e7484da60242c6a35e0549e7a109c8fa38db"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"e13199ab1d7fdeff5448f68746859787d6332999","unresolved":false,"context_lines":[{"line_number":126,"context_line":"                     \"without characters \u0027/\u0027 and \u0027,\u0027.\") % invalid_tags)"},{"line_number":127,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        tag_count \u003d len(body[\u0027tags\u0027])"},{"line_number":130,"context_line":"        if tag_count \u003e objects.instance.MAX_TAG_COUNT:"},{"line_number":131,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":132,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":133,"context_line":"                   % {\u0027max\u0027: objects.instance.MAX_TAG_COUNT,"},{"line_number":134,"context_line":"                      \u0027count\u0027: tag_count})"},{"line_number":135,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        long_tags \u003d ["},{"line_number":138,"context_line":"            t for t in body[\u0027tags\u0027] if len(t) \u003e objects.tag.MAX_TAG_LENGTH]"}],"source_content_type":"text/x-python","patch_set":127,"id":"9a061dce_55a764bc","line":135,"range":{"start_line":129,"start_character":0,"end_line":135,"end_character":53},"in_reply_to":"9a061dce_946747b6","updated":"2016-04-07 09:30:26.000000000","message":"So I agree with gmann, we should probably add this into the validators, and instead fix the validators to have better error messages, doing something like this: https://review.openstack.org/#/c/288260/2/nova/api/validation/validators.py\n\nNow if were not on patchset 127, I would probably ask for us to move this to validation, and do a follow up to fix the error messages.\n\nEither way, lets fix this up in a follow up patch?","commit_id":"bfe8e7484da60242c6a35e0549e7a109c8fa38db"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"613876a36de72f6f85b494d97e0c80323ebf297e","unresolved":false,"context_lines":[{"line_number":126,"context_line":"                     \"without characters \u0027/\u0027 and \u0027,\u0027.\") % invalid_tags)"},{"line_number":127,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        tag_count \u003d len(body[\u0027tags\u0027])"},{"line_number":130,"context_line":"        if tag_count \u003e objects.instance.MAX_TAG_COUNT:"},{"line_number":131,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":132,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":133,"context_line":"                   % {\u0027max\u0027: objects.instance.MAX_TAG_COUNT,"},{"line_number":134,"context_line":"                      \u0027count\u0027: tag_count})"},{"line_number":135,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        long_tags \u003d ["},{"line_number":138,"context_line":"            t for t in body[\u0027tags\u0027] if len(t) \u003e objects.tag.MAX_TAG_LENGTH]"}],"source_content_type":"text/x-python","patch_set":127,"id":"9a061dce_09068785","line":135,"range":{"start_line":129,"start_character":0,"end_line":135,"end_character":53},"in_reply_to":"9a061dce_9e748b68","updated":"2016-04-07 04:46:13.000000000","message":"After discussion with Alex got to know that for better msg you want to validate here.\nBut L113 decorator does the validation and in case of invalid tag, I do not think it will come to this point.\nseems like dead code?","commit_id":"bfe8e7484da60242c6a35e0549e7a109c8fa38db"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"23eb6c1b14d47884d54aad0ca4881c7268f04a25","unresolved":false,"context_lines":[{"line_number":126,"context_line":"                     \"without characters \u0027/\u0027 and \u0027,\u0027.\") % invalid_tags)"},{"line_number":127,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        tag_count \u003d len(body[\u0027tags\u0027])"},{"line_number":130,"context_line":"        if tag_count \u003e objects.instance.MAX_TAG_COUNT:"},{"line_number":131,"context_line":"            msg \u003d (_(\"The number of tags exceeded the per-server limit \""},{"line_number":132,"context_line":"                     \"%(max)d. The number of tags in request is %(count)d.\")"},{"line_number":133,"context_line":"                   % {\u0027max\u0027: objects.instance.MAX_TAG_COUNT,"},{"line_number":134,"context_line":"                      \u0027count\u0027: tag_count})"},{"line_number":135,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        long_tags \u003d ["},{"line_number":138,"context_line":"            t for t in body[\u0027tags\u0027] if len(t) \u003e objects.tag.MAX_TAG_LENGTH]"}],"source_content_type":"text/x-python","patch_set":127,"id":"9a061dce_946747b6","line":135,"range":{"start_line":129,"start_character":0,"end_line":135,"end_character":53},"in_reply_to":"9a061dce_ea886173","updated":"2016-04-07 07:13:46.000000000","message":"Yea, I agree on error message. but that\u0027s something we have for all APIs doing validation by schema.\n\nCurrent way makes attribute validation back to python code from schema which we wanted to avoid for v2.1 (which was solved from v2-\u003ev2.1 using schema validation)\n\nI feel we should have these validation in schema only otherwise schema validation becomes very week and we endup having those back to python code.","commit_id":"bfe8e7484da60242c6a35e0549e7a109c8fa38db"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"1390c271c83eac92c51828de750e03c8dc5eec0b","unresolved":false,"context_lines":[{"line_number":134,"context_line":"                      \u0027count\u0027: tag_count})"},{"line_number":135,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        long_tags \u003d ["},{"line_number":138,"context_line":"            t for t in body[\u0027tags\u0027] if len(t) \u003e objects.tag.MAX_TAG_LENGTH]"},{"line_number":139,"context_line":"        if long_tags:"},{"line_number":140,"context_line":"            msg \u003d (_(\"Tags %(tags)s are too long. Maximum length of a tag \""},{"line_number":141,"context_line":"                     \"is %(length)d\") % {\u0027tags\u0027: long_tags,"},{"line_number":142,"context_line":"                                         \u0027length\u0027: objects.tag.MAX_TAG_LENGTH})"},{"line_number":143,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        try:"},{"line_number":146,"context_line":"            tags \u003d objects.TagList.create(context, server_id, body[\u0027tags\u0027])"}],"source_content_type":"text/x-python","patch_set":127,"id":"9a061dce_1e607ba4","line":143,"range":{"start_line":137,"start_character":0,"end_line":143,"end_character":53},"updated":"2016-04-07 02:44:28.000000000","message":"This can be done on schema with max length on string type?","commit_id":"bfe8e7484da60242c6a35e0549e7a109c8fa38db"}],"nova/api/openstack/rest_api_version_history.rst":[{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"b9e2dfb9d39e3c3a0955ce676c5444303f03637b","unresolved":false,"context_lines":[{"line_number":38,"context_line":""},{"line_number":39,"context_line":"- **2.3**"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"  Added support of instance tags."},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"  A user can create, update and delete simple string tags for instances"},{"line_number":44,"context_line":"  by the os-instance-tags plugin."}],"source_content_type":"text/x-rst","patch_set":36,"id":"ba7be1f8_b46914c0","line":41,"updated":"2015-02-24 23:30:40.000000000","message":"instance-\u003eserver","commit_id":"e2e2cee3069b422add897a1e203f7079ad7ed6b4"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"b9e2dfb9d39e3c3a0955ce676c5444303f03637b","unresolved":false,"context_lines":[{"line_number":41,"context_line":"  Added support of instance tags."},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"  A user can create, update and delete simple string tags for instances"},{"line_number":44,"context_line":"  by the os-instance-tags plugin."}],"source_content_type":"text/x-rst","patch_set":36,"id":"ba7be1f8_b4de746b","line":44,"updated":"2015-02-24 23:30:40.000000000","message":"might be worth also adding that the resource point would be /servers/server_id/tags\n\nIt is totally good to be very verbose here as documentation will be produced from it and those writing the documentation will likely not be an expert in this area.","commit_id":"e2e2cee3069b422add897a1e203f7079ad7ed6b4"}],"nova/db/sqlalchemy/api.py":[{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"b9e2dfb9d39e3c3a0955ce676c5444303f03637b","unresolved":false,"context_lines":[{"line_number":1560,"context_line":"def _check_instance_exists(context, session, instance_uuid):"},{"line_number":1561,"context_line":"    if not model_query(context, models.Instance, session\u003dsession,"},{"line_number":1562,"context_line":"                       read_deleted\u003d\"no\").filter_by("},{"line_number":1563,"context_line":"                       uuid\u003dinstance_uuid).first():"},{"line_number":1564,"context_line":"        raise exception.InstanceNotFound(instance_id\u003dinstance_uuid)"},{"line_number":1565,"context_line":""},{"line_number":1566,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"ba7be1f8_14b90015","line":1563,"updated":"2015-02-24 23:30:40.000000000","message":"This change seems unrelated or is it just a bug you cam across? If its a bug it should probably just be merged as a separate patch. oh and testcase too please :-)","commit_id":"e2e2cee3069b422add897a1e203f7079ad7ed6b4"}],"nova/objects/tag.py":[{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"14e96bd0a99e36ea567f93039417a72d7917e18c","unresolved":false,"context_lines":[{"line_number":15,"context_line":"from nova.objects import base"},{"line_number":16,"context_line":"from nova.objects import fields"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"MAX_TAG_LENGTH \u003d 60"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"@base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":80,"id":"7a2fa921_b90c9b3c","line":18,"updated":"2015-10-11 16:49:01.000000000","message":"out of interest why is this 60? is this a database limitation?","commit_id":"e2f7ed67cf2b27f3d155621a15636c071c4d0a98"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"9cdebcb0bfd579f36ca49e8deccd3aedc4272bb4","unresolved":false,"context_lines":[{"line_number":15,"context_line":"from nova.objects import base"},{"line_number":16,"context_line":"from nova.objects import fields"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"MAX_TAG_LENGTH \u003d 60"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"@base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":80,"id":"7a2fa921_5ebd1701","line":18,"in_reply_to":"7a2fa921_b90c9b3c","updated":"2015-10-12 13:57:09.000000000","message":"Because during the spec review other reviewers and I decided that this length will be enough.","commit_id":"e2f7ed67cf2b27f3d155621a15636c071c4d0a98"}],"nova/tests/functional/test_api_samples.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3f9b9630f855146309f391e65db10d40b8b0d47b","unresolved":false,"context_lines":[{"line_number":4024,"context_line":"        subs[\u0027hostid\u0027] \u003d \u0027[a-f0-9]+\u0027"},{"line_number":4025,"context_line":"        subs[\u0027tag\u0027] \u003d \u0027[0-9a-zA-Z]+\u0027"},{"line_number":4026,"context_line":"        self._verify_response(\u0027instance-tags-show-resp\u0027, subs,"},{"line_number":4027,"context_line":"                              response, 200)"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_51ea7ddb","line":4027,"updated":"2015-01-27 12:00:42.000000000","message":"we also need test delete/update/delete_all","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"698172e53a2e639cf18a9f7a6560ad15f3bbf623","unresolved":false,"context_lines":[{"line_number":4037,"context_line":""},{"line_number":4038,"context_line":"        response \u003d self._do_put(\u0027servers/%s/tags/tag1\u0027 % uuid,"},{"line_number":4039,"context_line":"                                \u0027instance-tags-put-req\u0027, {})"},{"line_number":4040,"context_line":"        self.assertEqual(response.status_code, 204)"},{"line_number":4041,"context_line":"        self.assertEqual(response.content, \u0027\u0027)"},{"line_number":4042,"context_line":""},{"line_number":4043,"context_line":"    @mock.patch(\u0027nova.db.instance_tag_delete\u0027)"}],"source_content_type":"text/x-python","patch_set":33,"id":"da86d52c_29c4f2f3","line":4040,"updated":"2015-02-04 13:57:01.000000000","message":"To provide better debug message if assert fails, it would be nice to swap arguments in assertEqual to:\n\n assertEqual(expected, actual)","commit_id":"8a7bef5e27cc1637354bd4ac95e1c80546613569"}],"nova/tests/functional/v3/api_samples/os-server-tags/v2.12/server-tags-show-details-resp.json.tpl":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"f6a719cec2e91fac6efaa5b064c8470882d49575","unresolved":false,"context_lines":[{"line_number":1,"context_line":"{"},{"line_number":2,"context_line":"    \"server\": {"},{"line_number":3,"context_line":"        \"tags\": ["},{"line_number":4,"context_line":"            \"%(tag)s\""},{"line_number":5,"context_line":"        ],"},{"line_number":6,"context_line":"        \"addresses\": {"},{"line_number":7,"context_line":"            \"private\": ["}],"source_content_type":"text/x-smarty","patch_set":71,"id":"1a4dcd0f_01424068","line":4,"updated":"2015-08-06 10:19:08.000000000","message":"Oh, its here...","commit_id":"bbd0253f0a227270420e6632349945e72e3ae98f"}],"nova/tests/functional/v3/api_samples/servers_v21/v2.12/server-post-resp.json.tpl":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"1631ae5c87b9670f41141188a8554213eeae6e64","unresolved":false,"context_lines":[{"line_number":11,"context_line":"                \"href\": \"%(host)s/servers/%(uuid)s\","},{"line_number":12,"context_line":"                \"rel\": \"bookmark\""},{"line_number":13,"context_line":"            }"},{"line_number":14,"context_line":"        ]"},{"line_number":15,"context_line":"    }"},{"line_number":16,"context_line":"}"}],"source_content_type":"text/x-smarty","patch_set":71,"id":"1a4dcd0f_c16f7829","line":14,"updated":"2015-08-06 10:17:12.000000000","message":"don\u0027t we need tags in here?","commit_id":"bbd0253f0a227270420e6632349945e72e3ae98f"}],"nova/tests/functional/v3/test_instance_tags.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3f9b9630f855146309f391e65db10d40b8b0d47b","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        subs[\u0027hostid\u0027] \u003d \u0027[a-f0-9]+\u0027"},{"line_number":41,"context_line":"        subs[\u0027tag\u0027] \u003d \u0027[0-9a-zA-Z]+\u0027"},{"line_number":42,"context_line":"        self._verify_response(\u0027instance-tags-show-resp\u0027, subs,"},{"line_number":43,"context_line":"                              response, 200)"}],"source_content_type":"text/x-python","patch_set":32,"id":"1a930d6b_910225b2","line":43,"updated":"2015-01-27 12:00:42.000000000","message":"we also need test delete/update/delete_all","commit_id":"bc97f343a57f51a3a70970bd6ce3785b094c17ca"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"698172e53a2e639cf18a9f7a6560ad15f3bbf623","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        response \u003d self._do_put(\u0027servers/%s/tags/tag1\u0027 % uuid,"},{"line_number":57,"context_line":"                                \u0027instance-tags-put-req\u0027, {})"},{"line_number":58,"context_line":"        self.assertEqual(response.status_code, 204)"},{"line_number":59,"context_line":"        self.assertEqual(response.content, \u0027\u0027)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    @mock.patch(\u0027nova.db.instance_tag_delete\u0027)"},{"line_number":62,"context_line":"    def test_instance_tags_delete(self, mock_delete):"}],"source_content_type":"text/x-python","patch_set":33,"id":"da86d52c_c97fd6a9","line":59,"updated":"2015-02-04 13:57:01.000000000","message":"the same","commit_id":"8a7bef5e27cc1637354bd4ac95e1c80546613569"}],"nova/tests/functional/v3/test_server_tags.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"20245033c58ca33b6e0751039b3f6702a13bcb85","unresolved":false,"context_lines":[{"line_number":19,"context_line":""},{"line_number":20,"context_line":"class ServerTagsJsonTest(test_servers.ServersSampleBase):"},{"line_number":21,"context_line":"    extension_name \u003d \u0027os-server-tags\u0027"},{"line_number":22,"context_line":"    request_api_version \u003d \u00272.7\u0027"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    def _get_create_subs(self):"},{"line_number":25,"context_line":"        return {\u0027tag\u0027: TAG}"}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_047f66e0","line":22,"updated":"2015-07-16 11:17:44.000000000","message":"you should add something like this https://github.com/openstack/nova/blob/master/nova/tests/functional/v3/test_keypairs.py#L119","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"68b5dcf78f75078e26ae14c6ec747737a16bcb94","unresolved":false,"context_lines":[{"line_number":19,"context_line":""},{"line_number":20,"context_line":"class ServerTagsJsonTest(test_servers.ServersSampleBase):"},{"line_number":21,"context_line":"    extension_name \u003d \u0027os-server-tags\u0027"},{"line_number":22,"context_line":"    request_api_version \u003d \u00272.7\u0027"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    def _get_create_subs(self):"},{"line_number":25,"context_line":"        return {\u0027tag\u0027: TAG}"}],"source_content_type":"text/x-python","patch_set":54,"id":"9a41bdd9_1fc3233a","line":22,"in_reply_to":"9a41bdd9_047f66e0","updated":"2015-07-16 14:11:09.000000000","message":"ok, I will add","commit_id":"0e41cd49d11a9af7d929bf704360b8a946c71edf"}],"nova/tests/unit/api/openstack/compute/contrib/test_instance_tags.py":[{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"e7b4a56bc5cece89f9664bb439f627b18c0945b1","unresolved":false,"context_lines":[{"line_number":65,"context_line":"        url \u003d \u0027/v2/fake/servers/%s\u0027 % UUID"},{"line_number":66,"context_line":"        res \u003d self._make_request(url)"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        self.assertEqual(res.status_int, 200)"},{"line_number":69,"context_line":"        self.assertEqual([TAG1, TAG2], jsonutils.loads(res.body).get("},{"line_number":70,"context_line":"            \u0027server\u0027).get(\u0027%stags\u0027 % self.prefix))"},{"line_number":71,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"3a961159_e7f7f28a","line":68,"updated":"2014-12-08 09:06:00.000000000","message":"It is better to swap arguments in assertEqual","commit_id":"11791ee735ae9bfc094ff8133bb9219658a5a261"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"3bc78f5aa5c78f90bc63c09fd5f3465f6fde0e53","unresolved":false,"context_lines":[{"line_number":65,"context_line":"        url \u003d \u0027/v2/fake/servers/%s\u0027 % UUID"},{"line_number":66,"context_line":"        res \u003d self._make_request(url)"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        self.assertEqual(res.status_int, 200)"},{"line_number":69,"context_line":"        self.assertEqual([TAG1, TAG2], jsonutils.loads(res.body).get("},{"line_number":70,"context_line":"            \u0027server\u0027).get(\u0027%stags\u0027 % self.prefix))"},{"line_number":71,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"3a961159_45ad1b88","line":68,"in_reply_to":"3a961159_e7f7f28a","updated":"2014-12-08 11:57:59.000000000","message":"Yep, you are right","commit_id":"11791ee735ae9bfc094ff8133bb9219658a5a261"}],"nova/tests/unit/api/openstack/compute/contrib/test_server_tags.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"19f817c03a06fbde80b8d09c3743bb6b863408f5","unresolved":false,"context_lines":[{"line_number":181,"context_line":"                                      (UUID, TAG2), version\u003dself.api_version)"},{"line_number":182,"context_line":"        req.method \u003d \u0027PUT\u0027"},{"line_number":183,"context_line":"        self.assertRaises(exc.HTTPBadRequest, self.controller.update,"},{"line_number":184,"context_line":"                          req, UUID, TAG2, body\u003d{})"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"    @mock.patch(\u0027nova.db.instance_tag_delete\u0027)"},{"line_number":187,"context_line":"    def test_delete(self, mock_db_delete_inst_tags):"}],"source_content_type":"text/x-python","patch_set":56,"id":"3a50d1a3_ccea9b0f","line":184,"updated":"2015-07-21 13:14:02.000000000","message":"missing one for test_update_too_long_tag.\n\nAnd all the method miss the case InstanceNotFound","commit_id":"604050ae30c71fbb04626ba822960d969e0ed37b"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"068d93c7042fe34aeb16749e8fa9ebe267122726","unresolved":false,"context_lines":[{"line_number":181,"context_line":"                                      (UUID, TAG2), version\u003dself.api_version)"},{"line_number":182,"context_line":"        req.method \u003d \u0027PUT\u0027"},{"line_number":183,"context_line":"        self.assertRaises(exc.HTTPBadRequest, self.controller.update,"},{"line_number":184,"context_line":"                          req, UUID, TAG2, body\u003d{})"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"    @mock.patch(\u0027nova.db.instance_tag_delete\u0027)"},{"line_number":187,"context_line":"    def test_delete(self, mock_db_delete_inst_tags):"}],"source_content_type":"text/x-python","patch_set":56,"id":"3a50d1a3_a73f28d5","line":184,"in_reply_to":"3a50d1a3_ccea9b0f","updated":"2015-07-21 13:28:53.000000000","message":"yep. You right","commit_id":"604050ae30c71fbb04626ba822960d969e0ed37b"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"9dadc5faa845c7458736ade96f2324686f7a66c2","unresolved":false,"context_lines":[{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    @mock.patch(\u0027nova.db.instance_get\u0027)"},{"line_number":67,"context_line":"    @mock.patch(\u0027nova.db.instance_tag_get_by_instance_uuid\u0027)"},{"line_number":68,"context_line":"    def test_show_with_details_information(self, mock_db_get_inst_tags,"},{"line_number":69,"context_line":"                                           mock_get_inst):"},{"line_number":70,"context_line":"        fake_tags \u003d [self._get_tag(TAG1), self._get_tag(TAG2)]"},{"line_number":71,"context_line":"        mock_db_get_inst_tags.return_value \u003d fake_tags"}],"source_content_type":"text/x-python","patch_set":71,"id":"1a4dcd0f_848e5e77","line":68,"updated":"2015-08-06 10:29:11.000000000","message":"test for server show.","commit_id":"bbd0253f0a227270420e6632349945e72e3ae98f"}],"nova/tests/unit/fake_policy.py":[{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"b9e2dfb9d39e3c3a0955ce676c5444303f03637b","unresolved":false,"context_lines":[{"line_number":226,"context_line":"    \"compute_extension:v3:os-fping\": \"\","},{"line_number":227,"context_line":"    \"compute_extension:v3:os-fping:all_tenants\": \"is_admin:True\","},{"line_number":228,"context_line":"    \"compute_extension:v3:os-instance-tags\": \"\","},{"line_number":229,"context_line":"    \"compute_extension:hide_server_addresses\": \"\","},{"line_number":230,"context_line":"    \"compute_extension:v3:os-hide-server-addresses\": \"\","},{"line_number":231,"context_line":"    \"compute_extension:hosts\": \"rule:admin_api\","},{"line_number":232,"context_line":"    \"compute_extension:v3:os-hosts\": \"rule:admin_api\","}],"source_content_type":"text/x-python","patch_set":36,"id":"ba7be1f8_14710044","line":229,"updated":"2015-02-24 23:30:40.000000000","message":"fyi don;t need the discoverable tag here that I mentioned in the real policy.py file because by default in tests all plugins are discoverable whereas its the reverse for the real policy file.","commit_id":"e2e2cee3069b422add897a1e203f7079ad7ed6b4"}]}
