)]}'
{"doc/source/contributor/webapi-version-history.rst":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":8,"context_line":"Added new endpoints for retrieving conductors information:"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"* ``GET /v1/conductors`` for listing conductor resources"},{"line_number":11,"context_line":"* ``GET /v1/conductors/{hostname}`` for showing a conductor"},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Added a ``conductor`` field to node object, which will be returned in"},{"line_number":14,"context_line":"following endpoints:"}],"source_content_type":"text/x-rst","patch_set":3,"id":"3f79a3b5_eed2c360","line":11,"updated":"2018-11-29 08:45:50.000000000","message":"This is too detailed for this file. It\u0027s not a release note, you just need a summary of the changes (essentially, the first sentence).","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"18843c7e0fa11f22ec5812c8a391bfdb892387d5","unresolved":false,"context_lines":[{"line_number":8,"context_line":"Added new endpoints for retrieving conductors information:"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"* ``GET /v1/conductors`` for listing conductor resources"},{"line_number":11,"context_line":"* ``GET /v1/conductors/{hostname}`` for showing a conductor"},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Added a ``conductor`` field to node object, which will be returned in"},{"line_number":14,"context_line":"following endpoints:"}],"source_content_type":"text/x-rst","patch_set":3,"id":"3f79a3b5_61c46f3a","line":11,"in_reply_to":"3f79a3b5_eed2c360","updated":"2018-11-30 08:55:17.000000000","message":"Done\n\nWell, the file itself is not very consistent on this point, see 1.37, 1.32, 1.30 below..\nBut I am happy to remove that tedious stuff :P","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"}],"ironic/api/controllers/v1/conductor.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def get_next(self, limit, url\u003dNone, **kwargs):"},{"line_number":134,"context_line":"        # Override collection.Collection because there is no uuid for"},{"line_number":135,"context_line":"        # conductor."},{"line_number":136,"context_line":"        if not self.has_next(limit):"},{"line_number":137,"context_line":"            return wtypes.Unset"},{"line_number":138,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_ce84a75a","line":135,"updated":"2018-11-29 08:45:50.000000000","message":"Rather than doing this, we can update Collection https://github.com/openstack/ironic/blob/master/ironic/api/controllers/v1/collection.py#L45 with e.g. key_field class-level variable defaulting to \u0027uuid\u0027.","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"91dd2d6c88cd162c40e855c801d62ff47408a50a","unresolved":false,"context_lines":[{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def get_next(self, limit, url\u003dNone, **kwargs):"},{"line_number":134,"context_line":"        # Override collection.Collection because there is no uuid for"},{"line_number":135,"context_line":"        # conductor."},{"line_number":136,"context_line":"        if not self.has_next(limit):"},{"line_number":137,"context_line":"            return wtypes.Unset"},{"line_number":138,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_6e855302","line":135,"in_reply_to":"3f79a3b5_ce84a75a","updated":"2018-11-29 09:30:10.000000000","message":"Good idea!","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"18843c7e0fa11f22ec5812c8a391bfdb892387d5","unresolved":false,"context_lines":[{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def get_next(self, limit, url\u003dNone, **kwargs):"},{"line_number":134,"context_line":"        # Override collection.Collection because there is no uuid for"},{"line_number":135,"context_line":"        # conductor."},{"line_number":136,"context_line":"        if not self.has_next(limit):"},{"line_number":137,"context_line":"            return wtypes.Unset"},{"line_number":138,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_a19a870f","line":135,"in_reply_to":"3f79a3b5_ce84a75a","updated":"2018-11-30 08:55:17.000000000","message":"There could be a problem by using a variable, because it will be exposed or be set to Unset, I have created a class method to do the same thing, not sure if it\u0027s the right solution, just let me know if there is a better way.","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":182,"context_line":"            marker_obj \u003d objects.Conductor.get_by_hostname("},{"line_number":183,"context_line":"                pecan.request.context, marker, online\u003dNone)"},{"line_number":184,"context_line":""},{"line_number":185,"context_line":"        if sort_key in self.invalid_sort_key_list:"},{"line_number":186,"context_line":"            raise exception.InvalidParameterValue("},{"line_number":187,"context_line":"                _(\"The sort_key value %(key)s is an invalid field for \""},{"line_number":188,"context_line":"                  \"sorting\") % {\u0027key\u0027: sort_key})"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_6edf936d","line":185,"updated":"2018-11-29 08:45:50.000000000","message":"nit: I think this should go before fetching marker_obj for efficiency","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"18843c7e0fa11f22ec5812c8a391bfdb892387d5","unresolved":false,"context_lines":[{"line_number":182,"context_line":"            marker_obj \u003d objects.Conductor.get_by_hostname("},{"line_number":183,"context_line":"                pecan.request.context, marker, online\u003dNone)"},{"line_number":184,"context_line":""},{"line_number":185,"context_line":"        if sort_key in self.invalid_sort_key_list:"},{"line_number":186,"context_line":"            raise exception.InvalidParameterValue("},{"line_number":187,"context_line":"                _(\"The sort_key value %(key)s is an invalid field for \""},{"line_number":188,"context_line":"                  \"sorting\") % {\u0027key\u0027: sort_key})"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_411e13be","line":185,"in_reply_to":"3f79a3b5_6edf936d","updated":"2018-11-30 08:55:17.000000000","message":"Done\n\nAgreed, this piece was (shamelessly) stolen from Node, so the the same issue exists there, have done the same thing in the node.py","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"}],"ironic/api/controllers/v1/node.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":1163,"context_line":"                host \u003d pecan.request.rpcapi.get_conductor_for(rpc_node)"},{"line_number":1164,"context_line":"                node.conductor \u003d host"},{"line_number":1165,"context_line":"            except (exception.NoValidHost, exception.TemporaryFailure):"},{"line_number":1166,"context_line":"                LOG.info(\u0027Currently no conductor is servicing node %(uuid)s.\u0027,"},{"line_number":1167,"context_line":"                         {\u0027node\u0027: rpc_node.uuid})"},{"line_number":1168,"context_line":"                node.conductor \u003d None"},{"line_number":1169,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_8ee46f43","line":1166,"updated":"2018-11-29 08:45:50.000000000","message":"s/info/debug/ I think","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"18843c7e0fa11f22ec5812c8a391bfdb892387d5","unresolved":false,"context_lines":[{"line_number":1163,"context_line":"                host \u003d pecan.request.rpcapi.get_conductor_for(rpc_node)"},{"line_number":1164,"context_line":"                node.conductor \u003d host"},{"line_number":1165,"context_line":"            except (exception.NoValidHost, exception.TemporaryFailure):"},{"line_number":1166,"context_line":"                LOG.info(\u0027Currently no conductor is servicing node %(uuid)s.\u0027,"},{"line_number":1167,"context_line":"                         {\u0027node\u0027: rpc_node.uuid})"},{"line_number":1168,"context_line":"                node.conductor \u003d None"},{"line_number":1169,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_216af717","line":1166,"in_reply_to":"3f79a3b5_8ee46f43","updated":"2018-11-30 08:55:17.000000000","message":"Done","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":1585,"context_line":"    def _filter_by_conductor(self, nodes, conductor):"},{"line_number":1586,"context_line":"        filtered_nodes \u003d []"},{"line_number":1587,"context_line":"        for n in nodes:"},{"line_number":1588,"context_line":"            host \u003d pecan.request.rpcapi.get_conductor_for(n)"},{"line_number":1589,"context_line":"            if host \u003d\u003d conductor:"},{"line_number":1590,"context_line":"                filtered_nodes.append(n)"},{"line_number":1591,"context_line":"        return filtered_nodes"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_2ee99b17","line":1588,"updated":"2018-11-29 08:45:50.000000000","message":"nit: This will be called twice for each node: here and in convert_with_links. Do you think we can somehow avoid it?","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"21db7bf0afb6d24de77773d222ed181a116734f7","unresolved":false,"context_lines":[{"line_number":1585,"context_line":"    def _filter_by_conductor(self, nodes, conductor):"},{"line_number":1586,"context_line":"        filtered_nodes \u003d []"},{"line_number":1587,"context_line":"        for n in nodes:"},{"line_number":1588,"context_line":"            host \u003d pecan.request.rpcapi.get_conductor_for(n)"},{"line_number":1589,"context_line":"            if host \u003d\u003d conductor:"},{"line_number":1590,"context_line":"                filtered_nodes.append(n)"},{"line_number":1591,"context_line":"        return filtered_nodes"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_778158fd","line":1588,"in_reply_to":"3f79a3b5_2ee99b17","updated":"2018-12-04 01:39:11.000000000","message":"One way is passing the conductor down through NodeCollection and Node, if the arg conductor is not None, we use it instead of reading hashring in the Node.convert_to_links.\n\nIt looks a bit ugly though, as there are caching there, I think reading it twice consecutively doesn\u0027t have much overhead. But if we are good with this approach, I could update the patch.","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"91dd2d6c88cd162c40e855c801d62ff47408a50a","unresolved":false,"context_lines":[{"line_number":1585,"context_line":"    def _filter_by_conductor(self, nodes, conductor):"},{"line_number":1586,"context_line":"        filtered_nodes \u003d []"},{"line_number":1587,"context_line":"        for n in nodes:"},{"line_number":1588,"context_line":"            host \u003d pecan.request.rpcapi.get_conductor_for(n)"},{"line_number":1589,"context_line":"            if host \u003d\u003d conductor:"},{"line_number":1590,"context_line":"                filtered_nodes.append(n)"},{"line_number":1591,"context_line":"        return filtered_nodes"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_ce7347e5","line":1588,"in_reply_to":"3f79a3b5_2ee99b17","updated":"2018-11-29 09:30:10.000000000","message":"Really, so we can move the conductor filtering into the convert_with_links, with some conditional tuning I think it will do, wdyt?","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"18843c7e0fa11f22ec5812c8a391bfdb892387d5","unresolved":false,"context_lines":[{"line_number":1585,"context_line":"    def _filter_by_conductor(self, nodes, conductor):"},{"line_number":1586,"context_line":"        filtered_nodes \u003d []"},{"line_number":1587,"context_line":"        for n in nodes:"},{"line_number":1588,"context_line":"            host \u003d pecan.request.rpcapi.get_conductor_for(n)"},{"line_number":1589,"context_line":"            if host \u003d\u003d conductor:"},{"line_number":1590,"context_line":"                filtered_nodes.append(n)"},{"line_number":1591,"context_line":"        return filtered_nodes"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_d248af62","line":1588,"in_reply_to":"3f79a3b5_2ee99b17","updated":"2018-11-30 08:55:17.000000000","message":"urh, not so simple as I thought of, the filtering happens before api object is created, and it\u0027s accessed by two different endpoints, will take a look if there is any way to avoid that.","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":1594,"context_line":"                             maintenance\u003dNone, provision_state\u003dNone,"},{"line_number":1595,"context_line":"                             driver\u003dNone, resource_class\u003dNone, fault\u003dNone,"},{"line_number":1596,"context_line":"                             conductor_group\u003dNone):"},{"line_number":1597,"context_line":"        # This method is introduced to avoid C901 complexity issue."},{"line_number":1598,"context_line":"        filters \u003d {}"},{"line_number":1599,"context_line":"        if chassis_uuid:"},{"line_number":1600,"context_line":"            filters[\u0027chassis_uuid\u0027] \u003d chassis_uuid"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_4eee5721","line":1597,"updated":"2018-11-29 08:45:50.000000000","message":"nit: I don\u0027t the comment is required here","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"18843c7e0fa11f22ec5812c8a391bfdb892387d5","unresolved":false,"context_lines":[{"line_number":1594,"context_line":"                             maintenance\u003dNone, provision_state\u003dNone,"},{"line_number":1595,"context_line":"                             driver\u003dNone, resource_class\u003dNone, fault\u003dNone,"},{"line_number":1596,"context_line":"                             conductor_group\u003dNone):"},{"line_number":1597,"context_line":"        # This method is introduced to avoid C901 complexity issue."},{"line_number":1598,"context_line":"        filters \u003d {}"},{"line_number":1599,"context_line":"        if chassis_uuid:"},{"line_number":1600,"context_line":"            filters[\u0027chassis_uuid\u0027] \u003d chassis_uuid"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_81798bfb","line":1597,"in_reply_to":"3f79a3b5_4eee5721","updated":"2018-11-30 08:55:17.000000000","message":"Done","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3c977430181e12fc99bf0c76eb9b73aba38236a1","unresolved":false,"context_lines":[{"line_number":1164,"context_line":"                node.conductor \u003d host"},{"line_number":1165,"context_line":"            except (exception.NoValidHost, exception.TemporaryFailure):"},{"line_number":1166,"context_line":"                LOG.debug(\u0027Currently there is no conductor servicing node \u0027"},{"line_number":1167,"context_line":"                          \u0027%(uuid)s.\u0027, {\u0027node\u0027: rpc_node.uuid})"},{"line_number":1168,"context_line":"                node.conductor \u003d None"},{"line_number":1169,"context_line":""},{"line_number":1170,"context_line":"        if fields is not None:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_5669ccf2","line":1167,"updated":"2018-12-03 13:27:37.000000000","message":"s/uuid/node/ the in formatting pattern","commit_id":"8129e252ad39974bae69d8485759e148090a9ead"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"21db7bf0afb6d24de77773d222ed181a116734f7","unresolved":false,"context_lines":[{"line_number":1164,"context_line":"                node.conductor \u003d host"},{"line_number":1165,"context_line":"            except (exception.NoValidHost, exception.TemporaryFailure):"},{"line_number":1166,"context_line":"                LOG.debug(\u0027Currently there is no conductor servicing node \u0027"},{"line_number":1167,"context_line":"                          \u0027%(uuid)s.\u0027, {\u0027node\u0027: rpc_node.uuid})"},{"line_number":1168,"context_line":"                node.conductor \u003d None"},{"line_number":1169,"context_line":""},{"line_number":1170,"context_line":"        if fields is not None:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_573bfc98","line":1167,"in_reply_to":"3f79a3b5_5669ccf2","updated":"2018-12-04 01:39:11.000000000","message":"Done, thanks!","commit_id":"8129e252ad39974bae69d8485759e148090a9ead"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"4adc300e54cadbbc5a024c66d1c9d0d5d65c548d","unresolved":false,"context_lines":[{"line_number":1159,"context_line":"            # NOTE(kaifeng) It is possible a node gets orphaned in certain"},{"line_number":1160,"context_line":"            # circumstances, set conductor to None in such case."},{"line_number":1161,"context_line":"            try:"},{"line_number":1162,"context_line":"                host \u003d pecan.request.rpcapi.get_conductor_for(rpc_node)"},{"line_number":1163,"context_line":"                node.conductor \u003d host"},{"line_number":1164,"context_line":"            except (exception.NoValidHost, exception.TemporaryFailure):"},{"line_number":1165,"context_line":"                LOG.debug(\u0027Currently there is no conductor servicing node \u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_e0058b69","line":1162,"updated":"2018-12-04 17:35:59.000000000","message":"I\u0027m not sure how I feel about hitting the RPC bus an additional time for each node returned. I guess semi-required for this to work though since we didn\u0027t want to use/touch the affinity field :\\","commit_id":"7c7744dfb3ef617537f584478d7fd2cffb2481f4"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"8fe3984808f03261c999a5c4dc9d73c88f0403d4","unresolved":false,"context_lines":[{"line_number":1159,"context_line":"            # NOTE(kaifeng) It is possible a node gets orphaned in certain"},{"line_number":1160,"context_line":"            # circumstances, set conductor to None in such case."},{"line_number":1161,"context_line":"            try:"},{"line_number":1162,"context_line":"                host \u003d pecan.request.rpcapi.get_conductor_for(rpc_node)"},{"line_number":1163,"context_line":"                node.conductor \u003d host"},{"line_number":1164,"context_line":"            except (exception.NoValidHost, exception.TemporaryFailure):"},{"line_number":1165,"context_line":"                LOG.debug(\u0027Currently there is no conductor servicing node \u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_a67b24ce","line":1162,"in_reply_to":"3f79a3b5_5b5b10f7","updated":"2018-12-05 00:27:41.000000000","message":"OH! yeah... We have too much code. :(","commit_id":"7c7744dfb3ef617537f584478d7fd2cffb2481f4"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"6bd3f3d50c7cd4f471f6c5ed164521b6c73dfe7e","unresolved":false,"context_lines":[{"line_number":1159,"context_line":"            # NOTE(kaifeng) It is possible a node gets orphaned in certain"},{"line_number":1160,"context_line":"            # circumstances, set conductor to None in such case."},{"line_number":1161,"context_line":"            try:"},{"line_number":1162,"context_line":"                host \u003d pecan.request.rpcapi.get_conductor_for(rpc_node)"},{"line_number":1163,"context_line":"                node.conductor \u003d host"},{"line_number":1164,"context_line":"            except (exception.NoValidHost, exception.TemporaryFailure):"},{"line_number":1165,"context_line":"                LOG.debug(\u0027Currently there is no conductor servicing node \u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_32de676b","line":1162,"in_reply_to":"3f79a3b5_a67b24ce","updated":"2018-12-05 05:27:04.000000000","message":"And even more needs to learn :)","commit_id":"7c7744dfb3ef617537f584478d7fd2cffb2481f4"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f10604fbfc6638a4580c26883c24436bc85f0057","unresolved":false,"context_lines":[{"line_number":1159,"context_line":"            # NOTE(kaifeng) It is possible a node gets orphaned in certain"},{"line_number":1160,"context_line":"            # circumstances, set conductor to None in such case."},{"line_number":1161,"context_line":"            try:"},{"line_number":1162,"context_line":"                host \u003d pecan.request.rpcapi.get_conductor_for(rpc_node)"},{"line_number":1163,"context_line":"                node.conductor \u003d host"},{"line_number":1164,"context_line":"            except (exception.NoValidHost, exception.TemporaryFailure):"},{"line_number":1165,"context_line":"                LOG.debug(\u0027Currently there is no conductor servicing node \u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_5b5b10f7","line":1162,"in_reply_to":"3f79a3b5_e0058b69","updated":"2018-12-04 17:52:05.000000000","message":"I was about to -1 for it the last time, and then I realized that get_conductor_for does NOT hit RPC, only the hash ring.","commit_id":"7c7744dfb3ef617537f584478d7fd2cffb2481f4"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"6ecd5ec34eef6c6beb86344af7436418870c3448","unresolved":false,"context_lines":[{"line_number":1585,"context_line":"        filtered_nodes \u003d []"},{"line_number":1586,"context_line":"        for n in nodes:"},{"line_number":1587,"context_line":"            host \u003d pecan.request.rpcapi.get_conductor_for(n)"},{"line_number":1588,"context_line":"            if host \u003d\u003d conductor:"},{"line_number":1589,"context_line":"                filtered_nodes.append(n)"},{"line_number":1590,"context_line":"        return filtered_nodes"},{"line_number":1591,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_12c24b02","line":1588,"range":{"start_line":1588,"start_character":12,"end_line":1588,"end_character":33},"updated":"2018-12-05 05:48:52.000000000","message":"I am writing api-ref, wondering if we should handle character case here? conductor group is case-insensitive, which I think also applies to hostname.","commit_id":"7c7744dfb3ef617537f584478d7fd2cffb2481f4"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"c10b914f473a46e89de6b6d3b63482d5970673e5","unresolved":false,"context_lines":[{"line_number":1585,"context_line":"        filtered_nodes \u003d []"},{"line_number":1586,"context_line":"        for n in nodes:"},{"line_number":1587,"context_line":"            host \u003d pecan.request.rpcapi.get_conductor_for(n)"},{"line_number":1588,"context_line":"            if host \u003d\u003d conductor:"},{"line_number":1589,"context_line":"                filtered_nodes.append(n)"},{"line_number":1590,"context_line":"        return filtered_nodes"},{"line_number":1591,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_98167546","line":1588,"range":{"start_line":1588,"start_character":12,"end_line":1588,"end_character":33},"in_reply_to":"3f79a3b5_12c24b02","updated":"2018-12-05 12:17:56.000000000","message":"It seems to me that the hash ring is actually case-sensitive, and we don\u0027t seem to do anything with case when registering conductors. So I think this should stay case-sensitive as well, even though it\u0027s weird for host names.","commit_id":"7c7744dfb3ef617537f584478d7fd2cffb2481f4"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6b20b46049a26117501bbedafbfc76488ed59c75","unresolved":false,"context_lines":[{"line_number":1585,"context_line":"        filtered_nodes \u003d []"},{"line_number":1586,"context_line":"        for n in nodes:"},{"line_number":1587,"context_line":"            host \u003d pecan.request.rpcapi.get_conductor_for(n)"},{"line_number":1588,"context_line":"            if host \u003d\u003d conductor:"},{"line_number":1589,"context_line":"                filtered_nodes.append(n)"},{"line_number":1590,"context_line":"        return filtered_nodes"},{"line_number":1591,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_f399b5cd","line":1588,"range":{"start_line":1588,"start_character":12,"end_line":1588,"end_character":33},"in_reply_to":"3f79a3b5_3f613911","updated":"2018-12-06 09:44:10.000000000","message":"I\u0027m slightly leaning towards hostname, since it\u0027s still the essence of this field.","commit_id":"7c7744dfb3ef617537f584478d7fd2cffb2481f4"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"c2cc6e7f11621c8f9e60419cf1f3374443792455","unresolved":false,"context_lines":[{"line_number":1585,"context_line":"        filtered_nodes \u003d []"},{"line_number":1586,"context_line":"        for n in nodes:"},{"line_number":1587,"context_line":"            host \u003d pecan.request.rpcapi.get_conductor_for(n)"},{"line_number":1588,"context_line":"            if host \u003d\u003d conductor:"},{"line_number":1589,"context_line":"                filtered_nodes.append(n)"},{"line_number":1590,"context_line":"        return filtered_nodes"},{"line_number":1591,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_3f613911","line":1588,"range":{"start_line":1588,"start_character":12,"end_line":1588,"end_character":33},"in_reply_to":"3f79a3b5_98167546","updated":"2018-12-06 01:23:08.000000000","message":"Ah, and the host can be changed per conductor, maybe there is a conductor named \"Foo\" and the other named \"foo\". It makes sense to not limit the range to host names.\nAccording to that, it seems \"host\" is a more suitable name than \"hostname\" in the Conductor object, wdyt?","commit_id":"7c7744dfb3ef617537f584478d7fd2cffb2481f4"}],"ironic/api/controllers/v1/utils.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":942,"context_line":"    Version 1.48 of the API allows filtering nodes by conductor."},{"line_number":943,"context_line":"    \"\"\""},{"line_number":944,"context_line":"    if (conductor is not None and pecan.request.version.minor"},{"line_number":945,"context_line":"            \u003c versions.MINOR_49_CONDUCTORS):"},{"line_number":946,"context_line":"        raise exception.NotAcceptable(_("},{"line_number":947,"context_line":"            \"Request not acceptable. The minimal required API version \""},{"line_number":948,"context_line":"            \"should be %(base)s.%(opr)s\") %"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_aedccb72","line":945,"updated":"2018-11-29 08:45:50.000000000","message":"nit: conductor is not None and not allow_expect_conductors","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"18843c7e0fa11f22ec5812c8a391bfdb892387d5","unresolved":false,"context_lines":[{"line_number":942,"context_line":"    Version 1.48 of the API allows filtering nodes by conductor."},{"line_number":943,"context_line":"    \"\"\""},{"line_number":944,"context_line":"    if (conductor is not None and pecan.request.version.minor"},{"line_number":945,"context_line":"            \u003c versions.MINOR_49_CONDUCTORS):"},{"line_number":946,"context_line":"        raise exception.NotAcceptable(_("},{"line_number":947,"context_line":"            \"Request not acceptable. The minimal required API version \""},{"line_number":948,"context_line":"            \"should be %(base)s.%(opr)s\") %"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_e1263f22","line":945,"in_reply_to":"3f79a3b5_aedccb72","updated":"2018-11-30 08:55:17.000000000","message":"Done","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"4adc300e54cadbbc5a024c66d1c9d0d5d65c548d","unresolved":false,"context_lines":[{"line_number":933,"context_line":"    Version 1.48 of the API exposed conductor endpoints and conductor field"},{"line_number":934,"context_line":"    for the node."},{"line_number":935,"context_line":"    \"\"\""},{"line_number":936,"context_line":"    return pecan.request.version.minor \u003e\u003d versions.MINOR_49_CONDUCTORS"},{"line_number":937,"context_line":""},{"line_number":938,"context_line":""},{"line_number":939,"context_line":"def check_allow_filter_by_conductor(conductor):"}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_60a41ba5","line":936,"updated":"2018-12-04 17:35:59.000000000","message":"I don\u0027t think we should be doing this anymore since dmitry refactored the api version to field checking logic.\n\ndisregard, I see why since it is not in the object model.","commit_id":"7c7744dfb3ef617537f584478d7fd2cffb2481f4"}],"ironic/tests/unit/api/base.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        self.mock_get_conductor_for \u003d self.useFixture("},{"line_number":58,"context_line":"            fixtures.MockPatchObject(rpcapi.ConductorAPI, \u0027get_conductor_for\u0027,"},{"line_number":59,"context_line":"                                     autospec\u003dTrue)).mock"},{"line_number":60,"context_line":"        self.mock_get_conductor_for.return_value \u003d \u0027fake.conductor\u0027"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"        def reset_pecan():"},{"line_number":63,"context_line":"            pecan.set_config({}, overwrite\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_ae87eb5c","line":60,"updated":"2018-11-29 08:45:50.000000000","message":"I don\u0027t think we need this here, we can move it to Node unit tests.","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"91dd2d6c88cd162c40e855c801d62ff47408a50a","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        self.mock_get_conductor_for \u003d self.useFixture("},{"line_number":58,"context_line":"            fixtures.MockPatchObject(rpcapi.ConductorAPI, \u0027get_conductor_for\u0027,"},{"line_number":59,"context_line":"                                     autospec\u003dTrue)).mock"},{"line_number":60,"context_line":"        self.mock_get_conductor_for.return_value \u003d \u0027fake.conductor\u0027"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"        def reset_pecan():"},{"line_number":63,"context_line":"            pecan.set_config({}, overwrite\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_e9d2bd60","line":60,"in_reply_to":"3f79a3b5_ae87eb5c","updated":"2018-11-29 09:30:10.000000000","message":"Any code returns node objects will need this mock, for example the /lookup.\nIf you think it\u0027s too broad to put into the base class, I will try to shrink the range.","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"}],"ironic/tests/unit/api/controllers/v1/test_conductor.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            self.assertIn(\u0027alive\u0027, c)"},{"line_number":49,"context_line":"            self.assertNotIn(\u0027drivers\u0027, c)"},{"line_number":50,"context_line":"        self.assertEqual(data[\u0027conductors\u0027][0][\u0027hostname\u0027], \u0027why care\u0027)"},{"line_number":51,"context_line":"        self.assertEqual(data[\u0027conductors\u0027][1][\u0027hostname\u0027], \u0027why not\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def test_list_with_detail(self):"},{"line_number":54,"context_line":"        obj_utils.create_test_conductor(self.context, hostname\u003d\u0027why care\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_2e743b8a","line":51,"updated":"2018-11-29 08:45:50.000000000","message":"Is ordering guaranteed here? I think not without sorting, so maybe sort the list?","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"91dd2d6c88cd162c40e855c801d62ff47408a50a","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            self.assertIn(\u0027alive\u0027, c)"},{"line_number":49,"context_line":"            self.assertNotIn(\u0027drivers\u0027, c)"},{"line_number":50,"context_line":"        self.assertEqual(data[\u0027conductors\u0027][0][\u0027hostname\u0027], \u0027why care\u0027)"},{"line_number":51,"context_line":"        self.assertEqual(data[\u0027conductors\u0027][1][\u0027hostname\u0027], \u0027why not\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def test_list_with_detail(self):"},{"line_number":54,"context_line":"        obj_utils.create_test_conductor(self.context, hostname\u003d\u0027why care\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_0e537f3d","line":51,"in_reply_to":"3f79a3b5_2e743b8a","updated":"2018-11-29 09:30:10.000000000","message":"it is sorted by \"id\" by default, so it\u0027s ok within this test.","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":65,"context_line":"            self.assertIn(\u0027drivers\u0027, c)"},{"line_number":66,"context_line":"        self.assertEqual(data[\u0027conductors\u0027][0][\u0027hostname\u0027], \u0027why care\u0027)"},{"line_number":67,"context_line":"        self.assertEqual(data[\u0027conductors\u0027][1][\u0027hostname\u0027], \u0027why not\u0027)"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    def test_get_one(self):"},{"line_number":70,"context_line":"        obj_utils.create_test_conductor(self.context, hostname\u003d\u0027rocky.rocks\u0027)"},{"line_number":71,"context_line":"        data \u003d self.get_json("}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_4e79777f","line":68,"updated":"2018-11-29 08:45:50.000000000","message":"Let\u0027s add a unit test on old API version","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"18843c7e0fa11f22ec5812c8a391bfdb892387d5","unresolved":false,"context_lines":[{"line_number":65,"context_line":"            self.assertIn(\u0027drivers\u0027, c)"},{"line_number":66,"context_line":"        self.assertEqual(data[\u0027conductors\u0027][0][\u0027hostname\u0027], \u0027why care\u0027)"},{"line_number":67,"context_line":"        self.assertEqual(data[\u0027conductors\u0027][1][\u0027hostname\u0027], \u0027why not\u0027)"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    def test_get_one(self):"},{"line_number":70,"context_line":"        obj_utils.create_test_conductor(self.context, hostname\u003d\u0027rocky.rocks\u0027)"},{"line_number":71,"context_line":"        data \u003d self.get_json("}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_61a54f49","line":68,"in_reply_to":"3f79a3b5_4e79777f","updated":"2018-11-30 08:55:17.000000000","message":"Done","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        obj_utils.create_test_conductor(self.context, hostname\u003d\u0027rocky.rocks\u0027)"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        mock_utcnow.return_value \u003d _time + datetime.timedelta(seconds\u003d30)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        data \u003d self.get_json("},{"line_number":94,"context_line":"            \u0027/conductors/rocky.rocks\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_ee8de37e","line":91,"updated":"2018-11-29 08:45:50.000000000","message":"nit: Cannot we create a conductor with old updated_at instead?","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"91dd2d6c88cd162c40e855c801d62ff47408a50a","unresolved":false,"context_lines":[{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        obj_utils.create_test_conductor(self.context, hostname\u003d\u0027rocky.rocks\u0027)"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        mock_utcnow.return_value \u003d _time + datetime.timedelta(seconds\u003d30)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        data \u003d self.get_json("},{"line_number":94,"context_line":"            \u0027/conductors/rocky.rocks\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_0e013f09","line":91,"in_reply_to":"3f79a3b5_ee8de37e","updated":"2018-11-29 09:30:10.000000000","message":"Unfortunately we have no db api to do so, we can only register a conductor, and utcnow is used in the bottom of db implementation.","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        self.assertEqual(\u0027application/json\u0027, response.content_type)"},{"line_number":134,"context_line":"        self.assertIn(\u0027spongebob\u0027, response.json[\u0027error_message\u0027])"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    def test_get_custom_fields_invalid_api_version(self):"},{"line_number":137,"context_line":"        obj_utils.create_test_conductor(self.context, hostname\u003d\u0027rocky.rocks\u0027)"},{"line_number":138,"context_line":"        fields \u003d \u0027hostname\u0027"},{"line_number":139,"context_line":"        response \u003d self.get_json("}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_0e8b7f6a","line":136,"updated":"2018-11-29 08:45:50.000000000","message":"This test will fail the same way without using fields","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"91dd2d6c88cd162c40e855c801d62ff47408a50a","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        self.assertEqual(\u0027application/json\u0027, response.content_type)"},{"line_number":134,"context_line":"        self.assertIn(\u0027spongebob\u0027, response.json[\u0027error_message\u0027])"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    def test_get_custom_fields_invalid_api_version(self):"},{"line_number":137,"context_line":"        obj_utils.create_test_conductor(self.context, hostname\u003d\u0027rocky.rocks\u0027)"},{"line_number":138,"context_line":"        fields \u003d \u0027hostname\u0027"},{"line_number":139,"context_line":"        response \u003d self.get_json("}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_e9a4fd08","line":136,"in_reply_to":"3f79a3b5_0e8b7f6a","updated":"2018-11-29 09:30:10.000000000","message":"Oh, will update to test without fields, this plans to test the invalid api version","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"18843c7e0fa11f22ec5812c8a391bfdb892387d5","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        self.assertEqual(\u0027application/json\u0027, response.content_type)"},{"line_number":134,"context_line":"        self.assertIn(\u0027spongebob\u0027, response.json[\u0027error_message\u0027])"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    def test_get_custom_fields_invalid_api_version(self):"},{"line_number":137,"context_line":"        obj_utils.create_test_conductor(self.context, hostname\u003d\u0027rocky.rocks\u0027)"},{"line_number":138,"context_line":"        fields \u003d \u0027hostname\u0027"},{"line_number":139,"context_line":"        response \u003d self.get_json("}],"source_content_type":"text/x-python","patch_set":3,"id":"3f79a3b5_e15e3f4f","line":136,"in_reply_to":"3f79a3b5_0e8b7f6a","updated":"2018-11-30 08:55:17.000000000","message":"Removed this one, added two invalid api tests for list and get_one.","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"}],"releasenotes/notes/expose-conductor-d13c9c4ef9d9de86.yaml":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6e40ea04577cf8b2136eab4f9e42402a28ea4c56","unresolved":false,"context_lines":[{"line_number":15,"context_line":"    * ``GET /v1/nodes?detail\u003dtrue`` or ``GET /v1/nodes/detail``"},{"line_number":16,"context_line":"    * ``GET /v1/nodes/\u003cnode_ident\u003e``"},{"line_number":17,"context_line":"    * ``POST /v1/nodes``"},{"line_number":18,"context_line":"    * ``PATCH /v1/nodes/\u003cnode_ident\u003e``"}],"source_content_type":"text/x-yaml","patch_set":3,"id":"3f79a3b5_0ed05f56","line":18,"updated":"2018-11-29 08:45:50.000000000","message":"Maybe mention that this field cannot be changed?","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"},{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"18843c7e0fa11f22ec5812c8a391bfdb892387d5","unresolved":false,"context_lines":[{"line_number":15,"context_line":"    * ``GET /v1/nodes?detail\u003dtrue`` or ``GET /v1/nodes/detail``"},{"line_number":16,"context_line":"    * ``GET /v1/nodes/\u003cnode_ident\u003e``"},{"line_number":17,"context_line":"    * ``POST /v1/nodes``"},{"line_number":18,"context_line":"    * ``PATCH /v1/nodes/\u003cnode_ident\u003e``"}],"source_content_type":"text/x-yaml","patch_set":3,"id":"3f79a3b5_61322f5e","line":18,"in_reply_to":"3f79a3b5_0ed05f56","updated":"2018-11-30 08:55:17.000000000","message":"Sure, piece of cake","commit_id":"1eb4804c0ca672e3e6a29fc9b7ee3c7156ffc65b"}]}
