)]}'
{"keystone/api/discovery.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"11a3f1027e4b155f559624787331025c89546c6d","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        [MimeTypes.JSON, MimeTypes.JSON_HOME])"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"@_DISCOVERY_BLUEPRINT.route(\u0027/\u0027)"},{"line_number":81,"context_line":"def get_versions():"},{"line_number":82,"context_line":"    if v3_mime_type_best_match() \u003d\u003d MimeTypes.JSON_HOME:"},{"line_number":83,"context_line":"        # RENDER JSON-Home form, we have a clever client who will"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f7c97a3_ac76d30b","line":80,"range":{"start_line":80,"start_character":0,"end_line":80,"end_character":32},"updated":"2018-06-18 21:29:16.000000000","message":"So - this is going to be the new way of routing things, instead of using something like routers.py?","commit_id":"a8863935be813955103172b0550ea77978618abe"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"1f7e50bfbff5c04ea51cece8753e08dfb8804d0b","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        [MimeTypes.JSON, MimeTypes.JSON_HOME])"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"@_DISCOVERY_BLUEPRINT.route(\u0027/\u0027)"},{"line_number":81,"context_line":"def get_versions():"},{"line_number":82,"context_line":"    if v3_mime_type_best_match() \u003d\u003d MimeTypes.JSON_HOME:"},{"line_number":83,"context_line":"        # RENDER JSON-Home form, we have a clever client who will"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f7c97a3_879cf66a","line":80,"range":{"start_line":80,"start_character":0,"end_line":80,"end_character":32},"in_reply_to":"5f7c97a3_ac76d30b","updated":"2018-06-19 20:01:46.000000000","message":"This is a special one-off case since we aren\u0027t using flask-restful. Discovery is so very special it has to be done via the normal \"flask\" mechanism(s) and can\u0027t lean on the resource object method flask-restful gives us.","commit_id":"a8863935be813955103172b0550ea77978618abe"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"11a3f1027e4b155f559624787331025c89546c6d","unresolved":false,"context_lines":[{"line_number":90,"context_line":"        # NOTE(morgan): wsgi.Application.base_url will eventually need to"},{"line_number":91,"context_line":"        # be moved to a better \"common\" location. For now, we\u0027ll just lean"},{"line_number":92,"context_line":"        # on it for the sake of leaning on common code where possible."},{"line_number":93,"context_line":"        identity_url \u003d \u0027%s/v3/\u0027 % wsgi.Application.base_url("},{"line_number":94,"context_line":"            context\u003d{\u0027environment\u0027: request.environ})"},{"line_number":95,"context_line":"        versions \u003d _get_versions_list(identity_url)"},{"line_number":96,"context_line":"        return flask.Response("}],"source_content_type":"text/x-python","patch_set":9,"id":"5f7c97a3_2cd883ee","line":93,"range":{"start_line":93,"start_character":34,"end_line":93,"end_character":59},"updated":"2018-06-18 21:29:16.000000000","message":"Does this properly handle / characters?","commit_id":"a8863935be813955103172b0550ea77978618abe"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"1f7e50bfbff5c04ea51cece8753e08dfb8804d0b","unresolved":false,"context_lines":[{"line_number":90,"context_line":"        # NOTE(morgan): wsgi.Application.base_url will eventually need to"},{"line_number":91,"context_line":"        # be moved to a better \"common\" location. For now, we\u0027ll just lean"},{"line_number":92,"context_line":"        # on it for the sake of leaning on common code where possible."},{"line_number":93,"context_line":"        identity_url \u003d \u0027%s/v3/\u0027 % wsgi.Application.base_url("},{"line_number":94,"context_line":"            context\u003d{\u0027environment\u0027: request.environ})"},{"line_number":95,"context_line":"        versions \u003d _get_versions_list(identity_url)"},{"line_number":96,"context_line":"        return flask.Response("}],"source_content_type":"text/x-python","patch_set":9,"id":"5f7c97a3_a7bed2ab","line":93,"range":{"start_line":93,"start_character":34,"end_line":93,"end_character":59},"in_reply_to":"5f7c97a3_2cd883ee","updated":"2018-06-19 20:01:46.000000000","message":"I am fairly certain it does. base_url is smart(ish):\n\n    @classmethod\n    def base_url(cls, context, endpoint_type\u003dNone):\n        url \u003d CONF[\u0027public_endpoint\u0027]\n\n        if url:\n            substitutions \u003d dict(\n                itertools.chain(CONF.items(), CONF.eventlet_server.items()))\n\n            url \u003d url % substitutions\n        elif \u0027environment\u0027 in context:\n            url \u003d wsgiref.util.application_uri(context[\u0027environment\u0027])\n            # remove version from the URL as it may be part of SCRIPT_NAME but\n            # it should not be part of base URL\n            url \u003d re.sub(r\u0027/v(3|(2\\.0))/*$\u0027, \u0027\u0027, url)\n\n            # now remove the standard port\n            url \u003d utils.remove_standard_port(url)\n        else:\n            # if we don\u0027t have enough information to come up with a base URL,\n            # then fall back to localhost. This should never happen in\n            # production environment.\n            url \u003d \u0027http://localhost:%d\u0027 % CONF.eventlet_server.public_port\n\n        return url.rstrip(\u0027/\u0027)\n\n\nand this is used to craft the path (get_versions_list) which references self as \"\u003cURI\u003e/v3/.","commit_id":"a8863935be813955103172b0550ea77978618abe"}],"keystone/server/flask/application.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"16936a14a5aa9ea095a145464067f3385ebf20fb","unresolved":false,"context_lines":[{"line_number":171,"context_line":"def application_factory(name\u003d\u0027public\u0027):"},{"line_number":172,"context_line":"    if name not in (\u0027admin\u0027, \u0027public\u0027):"},{"line_number":173,"context_line":"        raise RuntimeError(\u0027Application name (for base_url lookup) must be \u0027"},{"line_number":174,"context_line":"                           \u0027either `admin` or `public`.\u0027)"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    # NOTE(morgan): The Flask App actually dispatches nothing until we migrate"},{"line_number":177,"context_line":"    # some routers to Flask-Blueprints, it is simply a placeholder."}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_e5d8d97f","line":174,"updated":"2018-06-12 20:11:09.000000000","message":"Shouldn\u0027t the \u0027admin\u0027 part have been removed by a previous patch in the series?","commit_id":"ec96b79480062516be7d731b9d64ae60bd8024c8"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"4ec64a6a18829ed40598e59f8dd81145460ff5b4","unresolved":false,"context_lines":[{"line_number":171,"context_line":"def application_factory(name\u003d\u0027public\u0027):"},{"line_number":172,"context_line":"    if name not in (\u0027admin\u0027, \u0027public\u0027):"},{"line_number":173,"context_line":"        raise RuntimeError(\u0027Application name (for base_url lookup) must be \u0027"},{"line_number":174,"context_line":"                           \u0027either `admin` or `public`.\u0027)"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    # NOTE(morgan): The Flask App actually dispatches nothing until we migrate"},{"line_number":177,"context_line":"    # some routers to Flask-Blueprints, it is simply a placeholder."}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_0096233f","line":174,"in_reply_to":"5f7c97a3_e5d8d97f","updated":"2018-06-12 21:01:37.000000000","message":"This likely should be removed. It can be removed at any point, I think I just missed it (however, the passed-in-name bit will need to remain for ease of external consumption)","commit_id":"ec96b79480062516be7d731b9d64ae60bd8024c8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"16936a14a5aa9ea095a145464067f3385ebf20fb","unresolved":false,"context_lines":[{"line_number":204,"context_line":"        _routers.append(routers_instance)"},{"line_number":205,"context_line":"        routers_instance.append_v3_routers(mapper, sub_routers)"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    # TODO(morgan): Remove \"API version registration\". For now this is kept"},{"line_number":208,"context_line":"    # for ease of conversion (minimal changes)"},{"line_number":209,"context_line":"    keystone.api.discovery.register_version(\u0027v3\u0027)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"    # NOTE(morgan): We add in all the keystone.api blueprints here, this"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_05c955aa","line":208,"range":{"start_line":207,"start_character":4,"end_line":208,"end_character":46},"updated":"2018-06-12 20:11:09.000000000","message":"What is this going to change to?","commit_id":"ec96b79480062516be7d731b9d64ae60bd8024c8"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"4ec64a6a18829ed40598e59f8dd81145460ff5b4","unresolved":false,"context_lines":[{"line_number":204,"context_line":"        _routers.append(routers_instance)"},{"line_number":205,"context_line":"        routers_instance.append_v3_routers(mapper, sub_routers)"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    # TODO(morgan): Remove \"API version registration\". For now this is kept"},{"line_number":208,"context_line":"    # for ease of conversion (minimal changes)"},{"line_number":209,"context_line":"    keystone.api.discovery.register_version(\u0027v3\u0027)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"    # NOTE(morgan): We add in all the keystone.api blueprints here, this"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_e09e8752","line":208,"range":{"start_line":207,"start_character":4,"end_line":208,"end_character":46},"in_reply_to":"5f7c97a3_05c955aa","updated":"2018-06-12 21:01:37.000000000","message":"Always existing, V3 cannot be disabled/removed, we\u0027ll stop registering API versions and just hard-code which one(s) we support... erm... \"one\" we support (for now).","commit_id":"ec96b79480062516be7d731b9d64ae60bd8024c8"}],"keystone/tests/unit/test_versions.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"500ff1f9f5c671d1370fb4ed5e60c732e814ad59","unresolved":false,"context_lines":[{"line_number":861,"context_line":"    def test_extension_property_method_returns_none(self):"},{"line_number":862,"context_line":"        extension_obj \u003d controllers.Extensions()"},{"line_number":863,"context_line":"        extensions_property \u003d extension_obj.extensions"},{"line_number":864,"context_line":"        self.assertIsNone(extensions_property)"},{"line_number":865,"context_line":""},{"line_number":866,"context_line":""},{"line_number":867,"context_line":"class VersionSingleAppTestCase(unit.TestCase):"}],"source_content_type":"text/x-python","patch_set":13,"id":"5f7c97a3_e22a5d2d","side":"PARENT","line":864,"updated":"2018-07-03 18:31:16.000000000","message":"We\u0027re removing this because this is left over cruft from when we supported extensions, yeah?","commit_id":"ecf721a3c176daf67d00536c48e80e78bded1af6"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"9329ef5c3d3f3dc1c79369647990a7d5e9144d91","unresolved":false,"context_lines":[{"line_number":861,"context_line":"    def test_extension_property_method_returns_none(self):"},{"line_number":862,"context_line":"        extension_obj \u003d controllers.Extensions()"},{"line_number":863,"context_line":"        extensions_property \u003d extension_obj.extensions"},{"line_number":864,"context_line":"        self.assertIsNone(extensions_property)"},{"line_number":865,"context_line":""},{"line_number":866,"context_line":""},{"line_number":867,"context_line":"class VersionSingleAppTestCase(unit.TestCase):"}],"source_content_type":"text/x-python","patch_set":13,"id":"5f7c97a3_256e1e64","side":"PARENT","line":864,"in_reply_to":"5f7c97a3_e22a5d2d","updated":"2018-07-03 20:17:48.000000000","message":"Yep!","commit_id":"ecf721a3c176daf67d00536c48e80e78bded1af6"}]}
