)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"52f25f9a769fd8d1a4c5b7b921eec65d01d97d43","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Support multiple uuids and names for RP list"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"In case we want to get a list of ResourceProviders using more than one name"},{"line_number":10,"context_line":"or uuid, we need to add to the REST API the possibility by adding an \u0027in:\u0027"},{"line_number":11,"context_line":"prefix to the attribute."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"3a71b18c_4f02a00a","line":9,"updated":"2016-12-09 17:15:03.000000000","message":"What\u0027s the use case for this as uuid/name are unique per resource provider?","commit_id":"6cdb41587bcf11dc32c654e1317467a5efe7d0b9"}],"nova/api/openstack/placement/handlers/resource_provider.py":[{"author":{"_account_id":2750,"name":"Sean Dague","email":"sean@dague.net","username":"sdague"},"change_message_id":"29f9b797775604050d3650cc242745a6eebde609","unresolved":false,"context_lines":[{"line_number":178,"context_line":"            if req.GET[attr].startswith(\u0027in:\u0027):"},{"line_number":179,"context_line":"                filters[attr] \u003d req.GET[attr][3:].split(\u0027,\u0027)"},{"line_number":180,"context_line":"            else:"},{"line_number":181,"context_line":"                filters[attr] \u003d [req.GET[attr]]"},{"line_number":182,"context_line":"    for uuid in filters.get(\u0027uuid\u0027, []):"},{"line_number":183,"context_line":"        if not uuidutils.is_uuid_like(uuid):"},{"line_number":184,"context_line":"            raise webob.exc.HTTPBadRequest("}],"source_content_type":"text/x-python","patch_set":5,"id":"3a71b18c_5b81be4c","line":181,"updated":"2016-12-08 14:20:12.000000000","message":"as this potentially gets more complicated, it seems like we should move the validation into a dedicated function to make it easier to directly test with odd stuff.","commit_id":"6e12f0cb9c16023c1c330da9d8a89bbcdaaf0b54"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"52f25f9a769fd8d1a4c5b7b921eec65d01d97d43","unresolved":false,"context_lines":[{"line_number":173,"context_line":"            json_formatter\u003dutil.json_error_formatter)"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"    filters \u003d {}"},{"line_number":176,"context_line":"    for attr in [\u0027uuid\u0027, \u0027name\u0027]:"},{"line_number":177,"context_line":"        if attr in req.GET:"},{"line_number":178,"context_line":"            if req.GET[attr].startswith(\u0027in:\u0027):"},{"line_number":179,"context_line":"                filters[attr] \u003d req.GET[attr][3:].split(\u0027,\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a71b18c_7c12b863","line":176,"range":{"start_line":176,"start_character":16,"end_line":176,"end_character":32},"updated":"2016-12-09 17:15:03.000000000","message":"Why don\u0027t we just use objects.ResourceProviderList.allowed_filters here?","commit_id":"6cdb41587bcf11dc32c654e1317467a5efe7d0b9"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2dc6f341d6bc55e0e1241b57a91a973d1d19230c","unresolved":false,"context_lines":[{"line_number":173,"context_line":"            json_formatter\u003dutil.json_error_formatter)"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"    filters \u003d {}"},{"line_number":176,"context_line":"    for attr in [\u0027uuid\u0027, \u0027name\u0027]:"},{"line_number":177,"context_line":"        if attr in req.GET:"},{"line_number":178,"context_line":"            if req.GET[attr].startswith(\u0027in:\u0027):"},{"line_number":179,"context_line":"                filters[attr] \u003d req.GET[attr][3:].split(\u0027,\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a71b18c_720c9f94","line":176,"range":{"start_line":176,"start_character":16,"end_line":176,"end_character":32},"in_reply_to":"3a71b18c_7c12b863","updated":"2016-12-09 17:36:56.000000000","message":"I guess this goes away in the next patch so nevermind.","commit_id":"6cdb41587bcf11dc32c654e1317467a5efe7d0b9"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"52f25f9a769fd8d1a4c5b7b921eec65d01d97d43","unresolved":false,"context_lines":[{"line_number":175,"context_line":"    filters \u003d {}"},{"line_number":176,"context_line":"    for attr in [\u0027uuid\u0027, \u0027name\u0027]:"},{"line_number":177,"context_line":"        if attr in req.GET:"},{"line_number":178,"context_line":"            if req.GET[attr].startswith(\u0027in:\u0027):"},{"line_number":179,"context_line":"                filters[attr] \u003d req.GET[attr][3:].split(\u0027,\u0027)"},{"line_number":180,"context_line":"            else:"},{"line_number":181,"context_line":"                filters[attr] \u003d [req.GET[attr]]"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a71b18c_fc816890","line":178,"updated":"2016-12-09 17:15:03.000000000","message":"geh we really need to start documenting the query language on this route.","commit_id":"6cdb41587bcf11dc32c654e1317467a5efe7d0b9"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"52f25f9a769fd8d1a4c5b7b921eec65d01d97d43","unresolved":false,"context_lines":[{"line_number":176,"context_line":"    for attr in [\u0027uuid\u0027, \u0027name\u0027]:"},{"line_number":177,"context_line":"        if attr in req.GET:"},{"line_number":178,"context_line":"            if req.GET[attr].startswith(\u0027in:\u0027):"},{"line_number":179,"context_line":"                filters[attr] \u003d req.GET[attr][3:].split(\u0027,\u0027)"},{"line_number":180,"context_line":"            else:"},{"line_number":181,"context_line":"                filters[attr] \u003d [req.GET[attr]]"},{"line_number":182,"context_line":"    for uuid in filters.get(\u0027uuid\u0027, []):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a71b18c_2fd3a439","line":179,"range":{"start_line":179,"start_character":50,"end_line":179,"end_character":60},"updated":"2016-12-09 17:15:03.000000000","message":"What if my RP name has commas in it?\n\nI\u0027m looking at the glance v2 images query language which is similar for in: and they have some special cases for filtering on names:\n\nhttp://developer.openstack.org/api-ref/image/v2/?expanded\u003dshow-images-detail#show-images\n\nAnd they talk about this issue:\n\n--\n\nUsing the in operator with the name property of images can be a bit trickier, depending upon how creatively you have named your images. The general rule is that if an image name contains a comma (,), you must enclose the entire name in quotation marks (\"). As usual, you must URL encode any characters that require it.\n\nFor example, to find images named glass, darkly or share me, you would use the following filter specification:\n\nGET v2/images?name\u003din:\"glass,%20darkly\",share%20me\n\nAs with regular filtering by name, you must specify the complete name you are looking for. Thus, for example, the query string name\u003din:glass,share will only match images with the exact name glass or the exact name share. It will not find an image named glass, darkly or an image named share me.","commit_id":"6cdb41587bcf11dc32c654e1317467a5efe7d0b9"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2dc6f341d6bc55e0e1241b57a91a973d1d19230c","unresolved":false,"context_lines":[{"line_number":176,"context_line":"    for attr in [\u0027uuid\u0027, \u0027name\u0027]:"},{"line_number":177,"context_line":"        if attr in req.GET:"},{"line_number":178,"context_line":"            if req.GET[attr].startswith(\u0027in:\u0027):"},{"line_number":179,"context_line":"                filters[attr] \u003d req.GET[attr][3:].split(\u0027,\u0027)"},{"line_number":180,"context_line":"            else:"},{"line_number":181,"context_line":"                filters[attr] \u003d [req.GET[attr]]"},{"line_number":182,"context_line":"    for uuid in filters.get(\u0027uuid\u0027, []):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a71b18c_124a8bac","line":179,"range":{"start_line":179,"start_character":50,"end_line":179,"end_character":60},"in_reply_to":"3a71b18c_2fd3a439","updated":"2016-12-09 17:36:56.000000000","message":"I guess for now if the name has commas in it, this just won\u0027t work and you won\u0027t get anything back. So you\u0027d have to use the non-in: form to list resource providers by name if they had a comma in them, but given it\u0027s going to be mostly robots using this at first (nova-scheduler?) it seems we wouldn\u0027t know that and it would just be a bug that would have to be dealt with later.","commit_id":"6cdb41587bcf11dc32c654e1317467a5efe7d0b9"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"90be7d96d81437cb56e11f4fb6006456eaa6f3aa","unresolved":false,"context_lines":[{"line_number":176,"context_line":"    for attr in [\u0027uuid\u0027, \u0027name\u0027]:"},{"line_number":177,"context_line":"        if attr in req.GET:"},{"line_number":178,"context_line":"            if req.GET[attr].startswith(\u0027in:\u0027):"},{"line_number":179,"context_line":"                filters[attr] \u003d req.GET[attr][3:].split(\u0027,\u0027)"},{"line_number":180,"context_line":"            else:"},{"line_number":181,"context_line":"                filters[attr] \u003d [req.GET[attr]]"},{"line_number":182,"context_line":"    for uuid in filters.get(\u0027uuid\u0027, []):"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a71b18c_72ec71bb","line":179,"range":{"start_line":179,"start_character":57,"end_line":179,"end_character":58},"updated":"2016-12-12 09:00:20.000000000","message":"So we can\u0027t use \u0027,\u0027 in the resource provider name.\n\nWe didn\u0027t have limit for the RP name https://github.com/openstack/nova/blob/master/nova/api/openstack/placement/handlers/resource_provider.py#L30\n\nBut I think we should fix it in the API of create resource provider.","commit_id":"7c479886b0eb3fd965acc609a8d107f15d1f566f"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"14d07025b822a447fbd4f76ba23fd73051e1eb50","unresolved":false,"context_lines":[{"line_number":176,"context_line":"    for attr in [\u0027uuid\u0027, \u0027name\u0027]:"},{"line_number":177,"context_line":"        if attr in req.GET:"},{"line_number":178,"context_line":"            if req.GET[attr].startswith(\u0027in:\u0027):"},{"line_number":179,"context_line":"                filters[attr] \u003d req.GET[attr][3:].split(\u0027,\u0027)"},{"line_number":180,"context_line":"            else:"},{"line_number":181,"context_line":"                filters[attr] \u003d [req.GET[attr]]"},{"line_number":182,"context_line":"    for uuid in filters.get(\u0027uuid\u0027, []):"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a6eadb0_93e66613","line":179,"range":{"start_line":179,"start_character":57,"end_line":179,"end_character":58},"in_reply_to":"3a71b18c_72ec71bb","updated":"2016-12-15 17:17:08.000000000","message":"Right, I think we should just modify the above schema to not accept commas in the name.","commit_id":"7c479886b0eb3fd965acc609a8d107f15d1f566f"}],"nova/objects/resource_provider.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"63868cb3bfa73b8128281b20dd93960ed7038c4a","unresolved":false,"context_lines":[{"line_number":569,"context_line":"        query \u003d context.session.query(models.ResourceProvider)"},{"line_number":570,"context_line":"        if name and isinstance(name, (list, tuple)):"},{"line_number":571,"context_line":"            query \u003d query.filter(models.ResourceProvider.name.in_(name))"},{"line_number":572,"context_line":"        if name and isinstance(name, six.string_types):"},{"line_number":573,"context_line":"            query \u003d query.filter(models.ResourceProvider.name \u003d\u003d name)"},{"line_number":574,"context_line":"        if uuid and isinstance(uuid, (list, tuple)):"},{"line_number":575,"context_line":"            query \u003d query.filter(models.ResourceProvider.uuid.in_(uuid))"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a71b18c_605a7752","line":572,"updated":"2016-12-07 16:51:33.000000000","message":"I would prefer that instead of branching on the type of name and uuid, we always assume that they are a list (even if just a list of one).\n\nThis will sometimes result in in_ queries with just one item, but a) that\u0027s not going to be a huge deal, b) worrying about that is early optimization.\n\nI think having an unambiguous interface is important.","commit_id":"b01e91c476e2a8a91d66f9fc2e10dabf51d72829"}],"nova/tests/functional/api/openstack/placement/gabbits/resource-provider.yaml":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"63868cb3bfa73b8128281b20dd93960ed7038c4a","unresolved":false,"context_lines":[{"line_number":130,"context_line":"  response_json_paths:"},{"line_number":131,"context_line":"      $.resource_providers.`len`: 1"},{"line_number":132,"context_line":"      $.resource_providers[0].uuid: $ENVIRON[\u0027RP_UUID\u0027]"},{"line_number":133,"context_line":"      $.resource_providers[0].name: $ENVIRON[\u0027RP_NAME\u0027]"},{"line_number":134,"context_line":"      $.resource_providers[0].links[?rel \u003d \"self\"].href: /resource_providers/$ENVIRON[\u0027RP_UUID\u0027]"},{"line_number":135,"context_line":"      $.resource_providers[0].links[?rel \u003d \"inventories\"].href: /resource_providers/$ENVIRON[\u0027RP_UUID\u0027]/inventories"},{"line_number":136,"context_line":"      $.resource_providers[0].links[?rel \u003d \"aggregates\"].href: /resource_providers/$ENVIRON[\u0027RP_UUID\u0027]/aggregates"}],"source_content_type":"text/x-yaml","patch_set":3,"id":"3a71b18c_4672f4ae","line":133,"updated":"2016-12-07 16:51:33.000000000","message":"Since the content of a GET /rp is already validated elsewhere, there\u0027s no requirement to repeat the validation of the links in this and the other test. Checking the length and the name (or uuid) of the first item is sufficient.","commit_id":"b01e91c476e2a8a91d66f9fc2e10dabf51d72829"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"b7536da2771d01a5f5a32695207063fc315f7939","unresolved":false,"context_lines":[{"line_number":131,"context_line":"      $.resource_providers.`len`: 1"},{"line_number":132,"context_line":"      $.resource_providers[0].name: $ENVIRON[\u0027RP_NAME\u0027]"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"- name: list resource providers filtering by invalid uuid"},{"line_number":135,"context_line":"  GET: /resource_providers?uuid\u003dspameggs"},{"line_number":136,"context_line":"  status: 400"},{"line_number":137,"context_line":"  response_strings:"},{"line_number":138,"context_line":"      - \u0027Invalid uuid value: spameggs\u0027"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"- name: list resource providers providing an invalid filter"},{"line_number":141,"context_line":"  GET: /resource_providers?spam\u003deggs"}],"source_content_type":"text/x-yaml","patch_set":8,"id":"1a6eadb0_ceb6c789","line":138,"range":{"start_line":134,"start_character":0,"end_line":138,"end_character":38},"updated":"2016-12-20 15:02:48.000000000","message":"Does this still get checked in the uuid\u003din: case?","commit_id":"a11b4c112e308cae72e7c25320f825041b854a7d"}],"nova/tests/functional/db/test_resource_provider.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"63868cb3bfa73b8128281b20dd93960ed7038c4a","unresolved":false,"context_lines":[{"line_number":545,"context_line":"        self.assertEqual(2, len(resource_providers))"},{"line_number":546,"context_line":"        resource_providers \u003d objects.ResourceProviderList.get_all_by_filters("},{"line_number":547,"context_line":"            self.context,"},{"line_number":548,"context_line":"            filters\u003d{\u0027uuid\u0027: [getattr(uuidsentinel, \u0027rp_uuid_2\u0027),"},{"line_number":549,"context_line":"                              getattr(uuidsentinel, \u0027rp_uuid_1\u0027)]})"},{"line_number":550,"context_line":"        self.assertEqual(2, len(resource_providers))"},{"line_number":551,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a71b18c_e680604c","line":548,"updated":"2016-12-07 16:51:33.000000000","message":"Since you\u0027re not constructing the uuid name here you can skip the getattr and do \u0027uuidsentinel.rp_uuid_2\u0027 and \u0027uuidsentinel.rp_uuid_1\u0027.","commit_id":"b01e91c476e2a8a91d66f9fc2e10dabf51d72829"}]}
