)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"37f7cd44fd82ad0ba2fc97342a6844e667dd8c4a","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This patch adds support for logical names to Ironic, which can be accessed"},{"line_number":10,"context_line":"via the REST API."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Note that this is a Work-In-Progress and needs more testing before it can"},{"line_number":13,"context_line":"be considered a candidate for merging."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I505181a1df064194848e3d5b79d01746024ce037"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"3a961159_9601c23b","line":12,"updated":"2014-12-17 17:36:29.000000000","message":"Is this still a Work-In-Progress? If so, I\u0027m not sure it is a candidate for kilo-1.","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"cf3d4894996918d1194a24461b1ae6215477f258","unresolved":false,"context_lines":[{"line_number":10,"context_line":"via the REST API."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Note that this is a Work-In-Progress and needs more testing before it can"},{"line_number":13,"context_line":"be considered a candidate for merging."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I505181a1df064194848e3d5b79d01746024ce037"},{"line_number":16,"context_line":"Related-To: blueprint logical-names"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"3a961159_8bcfb0b2","line":13,"updated":"2015-01-05 16:50:22.000000000","message":"Hi Michael, is this still a work-in-progress?","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"6e52f9105f326c3d063250c81b3f35fdcf93b207","unresolved":false,"context_lines":[{"line_number":10,"context_line":"via the REST API."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Note that this is a Work-In-Progress and needs more testing before it can"},{"line_number":13,"context_line":"be considered a candidate for merging."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I505181a1df064194848e3d5b79d01746024ce037"},{"line_number":16,"context_line":"Related-To: blueprint logical-names"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"3a961159_c64d2374","line":13,"in_reply_to":"3a961159_8bcfb0b2","updated":"2015-01-05 22:58:48.000000000","message":"I guess it is until I iron out all the bugs - still working on it, but holidays have got in the way.","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"}],"ironic/api/controllers/v1/__init__.py":[{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"d084db2dd6e7928a1c7052c250f57b12d7802559","unresolved":false,"context_lines":[{"line_number":38,"context_line":""},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"MIN_VER \u003d 0"},{"line_number":41,"context_line":"MAX_VER \u003d 3"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"class MediaType(base.APIBase):"}],"source_content_type":"text/x-python","patch_set":18,"id":"da86d52c_0d2f0cf8","line":41,"updated":"2015-02-05 13:29:39.000000000","message":"This have changed","commit_id":"be3788edae5b09dafbee96acdf6b72f97d5a9e62"}],"ironic/api/controllers/v1/node.py":[{"author":{"_account_id":11929,"name":"Michael Turek","email":"mjturek@linux.vnet.ibm.com","username":"mjturek"},"change_message_id":"5c55858c6cfca96fbbdfec0e43a4586019c2df61","unresolved":false,"context_lines":[{"line_number":54,"context_line":"_VENDOR_METHODS \u003d {}"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"def _get_rpc_node(node_uuid_or_name):"},{"line_number":58,"context_line":"    \"\"\"Get the RPC node from the node uuid or logical name."},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    :param node_uuid_or_name: UUID or logical name of a node."}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_c5512763","line":57,"updated":"2014-12-15 15:39:36.000000000","message":"nit: for consistency, maybe use \u0027node_ident\u0027 rather than \u0027node_uuid_or_name\u0027","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"0445f3f40d0b24c8da0aa18eb7a7ec68633004e7","unresolved":false,"context_lines":[{"line_number":54,"context_line":"_VENDOR_METHODS \u003d {}"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"def _get_rpc_node(node_uuid_or_name):"},{"line_number":58,"context_line":"    \"\"\"Get the RPC node from the node uuid or logical name."},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    :param node_uuid_or_name: UUID or logical name of a node."}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_89ec8e91","line":57,"in_reply_to":"3a961159_c5512763","updated":"2014-12-16 00:09:39.000000000","message":"Thanks for the review.\n\nDone.","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":13362,"name":"Tan Lin","email":"lin.tan@intel.com","username":"zero"},"change_message_id":"a4dea40f92ccaf65c4c6e58a551fa70f7f2da782","unresolved":false,"context_lines":[{"line_number":68,"context_line":"                                            node_uuid_or_name)"},{"line_number":69,"context_line":"    elif utils.is_hostname_safe(node_uuid_or_name):"},{"line_number":70,"context_line":"        rpc_node \u003d objects.Node.get_by_name(pecan.request.context,"},{"line_number":71,"context_line":"                                            node_uuid_or_name)"},{"line_number":72,"context_line":"    return rpc_node"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_245cb418","line":71,"updated":"2014-12-15 12:53:21.000000000","message":"Agree  exception.InvalidUuidOrName should be raise here.","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"7bfc5d030a883cc3f01d503fe1b24e864cd612d2","unresolved":false,"context_lines":[{"line_number":68,"context_line":"                                            node_uuid_or_name)"},{"line_number":69,"context_line":"    elif utils.is_hostname_safe(node_uuid_or_name):"},{"line_number":70,"context_line":"        rpc_node \u003d objects.Node.get_by_name(pecan.request.context,"},{"line_number":71,"context_line":"                                            node_uuid_or_name)"},{"line_number":72,"context_line":"    return rpc_node"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_d9091932","line":71,"updated":"2014-12-15 12:36:08.000000000","message":"I think it should raise instead of returning None:\n\n else:\n   raise NodeNotFound(..)","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"0445f3f40d0b24c8da0aa18eb7a7ec68633004e7","unresolved":false,"context_lines":[{"line_number":68,"context_line":"                                            node_uuid_or_name)"},{"line_number":69,"context_line":"    elif utils.is_hostname_safe(node_uuid_or_name):"},{"line_number":70,"context_line":"        rpc_node \u003d objects.Node.get_by_name(pecan.request.context,"},{"line_number":71,"context_line":"                                            node_uuid_or_name)"},{"line_number":72,"context_line":"    return rpc_node"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_a9878ab5","line":71,"in_reply_to":"3a961159_245cb418","updated":"2014-12-16 00:09:39.000000000","message":"Dmitry/Tan: Thanks for the review.\n\nI\u0027m going to leave this as is for backward compatibility reasons.  If the rpc_node cannot be obtained, the code that invokes this assumes it is None and proceeds (and fails).  To raise an exception here would change the semantics of the calling code, and I don\u0027t want to change that behaviour for the REST API calls.","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":13362,"name":"Tan Lin","email":"lin.tan@intel.com","username":"zero"},"change_message_id":"5fd97a3b1cc37ff3754b630eb58b5e3130700c4e","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        rpc_node \u003d objects.Node.get_by_uuid(pecan.request.context, node_ident)"},{"line_number":68,"context_line":"    elif utils.is_hostname_safe(node_ident):"},{"line_number":69,"context_line":"        rpc_node \u003d objects.Node.get_by_name(pecan.request.context, node_ident)"},{"line_number":70,"context_line":"    return rpc_node"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"class NodePatchType(types.JsonPatchType):"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_a4b5e87f","line":70,"updated":"2014-12-16 06:17:25.000000000","message":"If exception is not a good choice, can we add a warning here?","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"bd0a492cfb5baaad6b191adda1cfd259a8e43e02","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        rpc_node \u003d objects.Node.get_by_uuid(pecan.request.context, node_ident)"},{"line_number":68,"context_line":"    elif utils.is_hostname_safe(node_ident):"},{"line_number":69,"context_line":"        rpc_node \u003d objects.Node.get_by_name(pecan.request.context, node_ident)"},{"line_number":70,"context_line":"    return rpc_node"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"class NodePatchType(types.JsonPatchType):"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_2f6af3b2","line":70,"in_reply_to":"3a961159_a4b5e87f","updated":"2014-12-29 04:54:22.000000000","message":"Hi Tan - thanks for the review.  I\u0027m now adding an exception here.","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"350fe6fa5f6fdb09d0afaffa79461da1fae490d0","unresolved":false,"context_lines":[{"line_number":104,"context_line":"                  boot devices."},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        \"\"\""},{"line_number":107,"context_line":"        rpc_node \u003d _get_rpc_node(node_ident)"},{"line_number":108,"context_line":"        topic \u003d pecan.request.rpcapi.get_topic_for(rpc_node)"},{"line_number":109,"context_line":"        if supported:"},{"line_number":110,"context_line":"            return pecan.request.rpcapi.get_supported_boot_devices("}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_bb7b3e7a","line":107,"updated":"2014-12-16 10:34:37.000000000","message":"Lemme explain better: previously objects.Node.get_by_uuid either raised NodeNotFound or returned a node. Now you add an option of returning None, which will probably lead to some different behavior. Thus my request to raise NodeNotFound in  _get_rpc_node","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"bd0a492cfb5baaad6b191adda1cfd259a8e43e02","unresolved":false,"context_lines":[{"line_number":104,"context_line":"                  boot devices."},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        \"\"\""},{"line_number":107,"context_line":"        rpc_node \u003d _get_rpc_node(node_ident)"},{"line_number":108,"context_line":"        topic \u003d pecan.request.rpcapi.get_topic_for(rpc_node)"},{"line_number":109,"context_line":"        if supported:"},{"line_number":110,"context_line":"            return pecan.request.rpcapi.get_supported_boot_devices("}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_4f657fdf","line":107,"in_reply_to":"3a961159_364d6e9a","updated":"2014-12-29 04:54:22.000000000","message":"Ok, exception added.  Thanks for explaining Dmitry and agreeing Ruby :)","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"37f7cd44fd82ad0ba2fc97342a6844e667dd8c4a","unresolved":false,"context_lines":[{"line_number":104,"context_line":"                  boot devices."},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        \"\"\""},{"line_number":107,"context_line":"        rpc_node \u003d _get_rpc_node(node_ident)"},{"line_number":108,"context_line":"        topic \u003d pecan.request.rpcapi.get_topic_for(rpc_node)"},{"line_number":109,"context_line":"        if supported:"},{"line_number":110,"context_line":"            return pecan.request.rpcapi.get_supported_boot_devices("}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_364d6e9a","line":107,"in_reply_to":"3a961159_bb7b3e7a","updated":"2014-12-17 17:36:29.000000000","message":"+1, I agree with Dmitry.","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"37f7cd44fd82ad0ba2fc97342a6844e667dd8c4a","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        topic \u003d pecan.request.rpcapi.get_topic_for(rpc_node)"},{"line_number":109,"context_line":"        if supported:"},{"line_number":110,"context_line":"            return pecan.request.rpcapi.get_supported_boot_devices("},{"line_number":111,"context_line":"                pecan.request.context, node_ident, topic)"},{"line_number":112,"context_line":"        else:"},{"line_number":113,"context_line":"            return pecan.request.rpcapi.get_boot_device(pecan.request.context,"},{"line_number":114,"context_line":"                                                        node_ident, topic)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_994ad525","line":111,"updated":"2014-12-17 17:36:29.000000000","message":"This is a dumb question (I am only starting to look at this patch). Why not leave \u0027logical name\u0027 of the node, at the api level, and internally, continue to stick with our node_uuid?\n\nEg, can\u0027t you get the node\u0027s uuid from rpc_node?","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"bd0a492cfb5baaad6b191adda1cfd259a8e43e02","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        topic \u003d pecan.request.rpcapi.get_topic_for(rpc_node)"},{"line_number":109,"context_line":"        if supported:"},{"line_number":110,"context_line":"            return pecan.request.rpcapi.get_supported_boot_devices("},{"line_number":111,"context_line":"                pecan.request.context, node_ident, topic)"},{"line_number":112,"context_line":"        else:"},{"line_number":113,"context_line":"            return pecan.request.rpcapi.get_boot_device(pecan.request.context,"},{"line_number":114,"context_line":"                                                        node_ident, topic)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_cfa08ff6","line":111,"in_reply_to":"3a961159_994ad525","updated":"2014-12-29 04:54:22.000000000","message":"Thanks Ruby - that is a good observation.  That should simplify the code in most places.","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"fe1025ded6f5345a7dcc81b5a183432b7096a8e6","unresolved":false,"context_lines":[{"line_number":536,"context_line":"    def sample(cls, expand\u003dTrue):"},{"line_number":537,"context_line":"        time \u003d datetime.datetime(2000, 1, 1, 12, 0, 0)"},{"line_number":538,"context_line":"        node_uuid \u003d \u00271be26c0b-03f2-4d2e-ae87-c02d7f33c123\u0027"},{"line_number":539,"context_line":"        instance_uuid \u003d \u0027dcf1fbc5-93fc-4596-9395-b80572f6267b\u0027"},{"line_number":540,"context_line":"        sample \u003d cls(uuid\u003dnode_uuid, instance_uuid\u003dinstance_uuid,"},{"line_number":541,"context_line":"                     power_state\u003dir_states.POWER_ON,"},{"line_number":542,"context_line":"                     target_power_state\u003dir_states.NOSTATE,"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_b73423fc","line":539,"updated":"2014-12-29 13:23:40.000000000","message":"Please add name to sample too.","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"6b19afe30392a1ce5f9a0a4616398e40e1567542","unresolved":false,"context_lines":[{"line_number":536,"context_line":"    def sample(cls, expand\u003dTrue):"},{"line_number":537,"context_line":"        time \u003d datetime.datetime(2000, 1, 1, 12, 0, 0)"},{"line_number":538,"context_line":"        node_uuid \u003d \u00271be26c0b-03f2-4d2e-ae87-c02d7f33c123\u0027"},{"line_number":539,"context_line":"        instance_uuid \u003d \u0027dcf1fbc5-93fc-4596-9395-b80572f6267b\u0027"},{"line_number":540,"context_line":"        sample \u003d cls(uuid\u003dnode_uuid, instance_uuid\u003dinstance_uuid,"},{"line_number":541,"context_line":"                     power_state\u003dir_states.POWER_ON,"},{"line_number":542,"context_line":"                     target_power_state\u003dir_states.NOSTATE,"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a930d6b_a0408036","line":539,"in_reply_to":"3a961159_b73423fc","updated":"2015-01-23 04:33:33.000000000","message":"Done","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"fe1025ded6f5345a7dcc81b5a183432b7096a8e6","unresolved":false,"context_lines":[{"line_number":823,"context_line":"    def validate(self, node_uuid\u003dNone, node_name\u003dNone):"},{"line_number":824,"context_line":"        \"\"\"Validate the driver interfaces."},{"line_number":825,"context_line":""},{"line_number":826,"context_line":"        :param node_uuid_or_name: UUID or logical name of a node."},{"line_number":827,"context_line":"        \"\"\""},{"line_number":828,"context_line":"        # check if node exists"},{"line_number":829,"context_line":"        node_uuid_or_name \u003d None"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_772abb91","line":826,"updated":"2014-12-29 13:23:40.000000000","message":"Docstring is incorrect.","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"6b19afe30392a1ce5f9a0a4616398e40e1567542","unresolved":false,"context_lines":[{"line_number":823,"context_line":"    def validate(self, node_uuid\u003dNone, node_name\u003dNone):"},{"line_number":824,"context_line":"        \"\"\"Validate the driver interfaces."},{"line_number":825,"context_line":""},{"line_number":826,"context_line":"        :param node_uuid_or_name: UUID or logical name of a node."},{"line_number":827,"context_line":"        \"\"\""},{"line_number":828,"context_line":"        # check if node exists"},{"line_number":829,"context_line":"        node_uuid_or_name \u003d None"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a930d6b_e0b8c82c","line":826,"in_reply_to":"3a961159_772abb91","updated":"2015-01-23 04:33:33.000000000","message":"Done","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f12ed7a2a407a7ad4ae61042b04ac26203a7bcaf","unresolved":false,"context_lines":[{"line_number":914,"context_line":"            # NOTE(mrda): Since name is optional, need to add it into the"},{"line_number":915,"context_line":"            # node dict if it\u0027s going to be patched"},{"line_number":916,"context_line":"            for p in patch:"},{"line_number":917,"context_line":"                if (p[\u0027op\u0027] \u003d\u003d \u0027add\u0027 and p[\u0027path\u0027] \u003d\u003d \u0027/name\u0027 and"},{"line_number":918,"context_line":"                    \u0027name\u0027 not in node_dict):"},{"line_number":919,"context_line":"                    node_dict[\u0027name\u0027] \u003d \u0027fred\u0027"},{"line_number":920,"context_line":"            node \u003d Node(**api_utils.apply_jsonpatch(node_dict, patch))"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a930d6b_bcef5f86","line":917,"updated":"2015-01-23 13:42:45.000000000","message":"what about op \u003d\u003d \u0027replace\u0027?","commit_id":"f45b62e37ce7d2ccd0e9b51d501f5b05fe0ce2e2"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"db36f17d5c30dacb2c46efce62708abaaf9ce51b","unresolved":false,"context_lines":[{"line_number":914,"context_line":"            # NOTE(mrda): Since name is optional, need to add it into the"},{"line_number":915,"context_line":"            # node dict if it\u0027s going to be patched"},{"line_number":916,"context_line":"            for p in patch:"},{"line_number":917,"context_line":"                if (p[\u0027op\u0027] \u003d\u003d \u0027add\u0027 and p[\u0027path\u0027] \u003d\u003d \u0027/name\u0027 and"},{"line_number":918,"context_line":"                    \u0027name\u0027 not in node_dict):"},{"line_number":919,"context_line":"                    node_dict[\u0027name\u0027] \u003d \u0027fred\u0027"},{"line_number":920,"context_line":"            node \u003d Node(**api_utils.apply_jsonpatch(node_dict, patch))"}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_0a931ca4","line":917,"in_reply_to":"1a930d6b_bcef5f86","updated":"2015-02-02 07:09:00.000000000","message":"Thanks Dmitry, will be removing this section as it\u0027s no longer required.","commit_id":"f45b62e37ce7d2ccd0e9b51d501f5b05fe0ce2e2"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"edecef70a3f322f3bea0332aaa1e790d2f3461a2","unresolved":false,"context_lines":[{"line_number":916,"context_line":"            for p in patch:"},{"line_number":917,"context_line":"                if (p[\u0027op\u0027] \u003d\u003d \u0027add\u0027 and p[\u0027path\u0027] \u003d\u003d \u0027/name\u0027 and"},{"line_number":918,"context_line":"                    \u0027name\u0027 not in node_dict):"},{"line_number":919,"context_line":"                    node_dict[\u0027name\u0027] \u003d \u0027fred\u0027"},{"line_number":920,"context_line":"            node \u003d Node(**api_utils.apply_jsonpatch(node_dict, patch))"},{"line_number":921,"context_line":"        except api_utils.JSONPATCH_EXCEPTIONS as e:"},{"line_number":922,"context_line":"            raise exception.PatchError(patch\u003dpatch, reason\u003de)"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa81d914_689b6272","line":919,"updated":"2015-01-29 23:01:21.000000000","message":"I would prefer an empty string be used for the dummy value, rather than fred. But even better would be if such wasn\u0027t necessary. Why is this optional value not present onteh node_dict at all?","commit_id":"f45b62e37ce7d2ccd0e9b51d501f5b05fe0ce2e2"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"db36f17d5c30dacb2c46efce62708abaaf9ce51b","unresolved":false,"context_lines":[{"line_number":916,"context_line":"            for p in patch:"},{"line_number":917,"context_line":"                if (p[\u0027op\u0027] \u003d\u003d \u0027add\u0027 and p[\u0027path\u0027] \u003d\u003d \u0027/name\u0027 and"},{"line_number":918,"context_line":"                    \u0027name\u0027 not in node_dict):"},{"line_number":919,"context_line":"                    node_dict[\u0027name\u0027] \u003d \u0027fred\u0027"},{"line_number":920,"context_line":"            node \u003d Node(**api_utils.apply_jsonpatch(node_dict, patch))"},{"line_number":921,"context_line":"        except api_utils.JSONPATCH_EXCEPTIONS as e:"},{"line_number":922,"context_line":"            raise exception.PatchError(patch\u003dpatch, reason\u003de)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_4a8d147b","line":919,"in_reply_to":"fa81d914_689b6272","updated":"2015-02-02 07:09:00.000000000","message":"Thanks for picking this up - I\u0027ll be removing this special case code in the next patch.","commit_id":"f45b62e37ce7d2ccd0e9b51d501f5b05fe0ce2e2"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"38e377bbf4f6c5518113acea1ac9e503aa59d9ab","unresolved":false,"context_lines":[{"line_number":859,"context_line":"        elif node_name:"},{"line_number":860,"context_line":"            node_uuid_or_name \u003d node_name"},{"line_number":861,"context_line":""},{"line_number":862,"context_line":"        rpc_node \u003d _get_rpc_node(node_uuid_or_name)"},{"line_number":863,"context_line":""},{"line_number":864,"context_line":"        topic \u003d pecan.request.rpcapi.get_topic_for(rpc_node)"},{"line_number":865,"context_line":"        return pecan.request.rpcapi.validate_driver_interfaces("}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_b82b3c81","line":862,"updated":"2015-02-02 12:58:39.000000000","message":"Why not just write _get_rpc_node(node_uuid or node_name)?","commit_id":"cf6aa1928461404766ee2992075cf65e208c2b46"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"cab5334194b2222e03fadd51f4f57a23e091d924","unresolved":false,"context_lines":[{"line_number":859,"context_line":"        elif node_name:"},{"line_number":860,"context_line":"            node_uuid_or_name \u003d node_name"},{"line_number":861,"context_line":""},{"line_number":862,"context_line":"        rpc_node \u003d _get_rpc_node(node_uuid_or_name)"},{"line_number":863,"context_line":""},{"line_number":864,"context_line":"        topic \u003d pecan.request.rpcapi.get_topic_for(rpc_node)"},{"line_number":865,"context_line":"        return pecan.request.rpcapi.validate_driver_interfaces("}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_9d8c8e37","line":862,"in_reply_to":"da86d52c_b82b3c81","updated":"2015-02-02 21:31:38.000000000","message":"Thanks for the suggestion Vladyslav","commit_id":"cf6aa1928461404766ee2992075cf65e208c2b46"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"338f140e87110a95e334c7de8f53c5ef5a173130","unresolved":false,"context_lines":[{"line_number":733,"context_line":"    }"},{"line_number":734,"context_line":""},{"line_number":735,"context_line":"    def _get_nodes_collection(self, chassis_uuid, instance_uuid, associated,"},{"line_number":736,"context_line":"                              maintenance, marker, limit, sort_key, sort_dir,"},{"line_number":737,"context_line":"                              expand\u003dFalse, resource_url\u003dNone):"},{"line_number":738,"context_line":"        if self.from_chassis and not chassis_uuid:"},{"line_number":739,"context_line":"            raise exception.MissingParameterValue(_("}],"source_content_type":"text/x-python","patch_set":10,"id":"da86d52c_02b59230","line":736,"updated":"2015-02-03 01:13:47.000000000","message":"I wonder if we should add a partial name search. Maybe a follow-on patch.","commit_id":"166f09f14b2b5e8f964e2f1b33234b031719421f"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"1c0ee093aeb11f57a0a5ece52bf504250fe21cfc","unresolved":false,"context_lines":[{"line_number":733,"context_line":"    }"},{"line_number":734,"context_line":""},{"line_number":735,"context_line":"    def _get_nodes_collection(self, chassis_uuid, instance_uuid, associated,"},{"line_number":736,"context_line":"                              maintenance, marker, limit, sort_key, sort_dir,"},{"line_number":737,"context_line":"                              expand\u003dFalse, resource_url\u003dNone):"},{"line_number":738,"context_line":"        if self.from_chassis and not chassis_uuid:"},{"line_number":739,"context_line":"            raise exception.MissingParameterValue(_("}],"source_content_type":"text/x-python","patch_set":10,"id":"da86d52c_e2db1e19","line":736,"in_reply_to":"da86d52c_02b59230","updated":"2015-02-03 03:05:06.000000000","message":"I might leave this for now","commit_id":"166f09f14b2b5e8f964e2f1b33234b031719421f"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"338f140e87110a95e334c7de8f53c5ef5a173130","unresolved":false,"context_lines":[{"line_number":846,"context_line":"                                          resource_url)"},{"line_number":847,"context_line":""},{"line_number":848,"context_line":"    @wsme_pecan.wsexpose(wtypes.text, types.uuid, types.name)"},{"line_number":849,"context_line":"    def validate(self, node_uuid\u003dNone, node_name\u003dNone):"},{"line_number":850,"context_line":"        \"\"\"Validate the driver interfaces, using either UUID or name."},{"line_number":851,"context_line":""},{"line_number":852,"context_line":"        :param node_uuid: UUID of a node."}],"source_content_type":"text/x-python","patch_set":10,"id":"da86d52c_9f4b9d2a","line":849,"updated":"2015-02-03 01:13:47.000000000","message":"Why not use node_ident like everywhere else? This actually breaks e.g. /v1/nodes/$name/validate","commit_id":"166f09f14b2b5e8f964e2f1b33234b031719421f"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"1c0ee093aeb11f57a0a5ece52bf504250fe21cfc","unresolved":false,"context_lines":[{"line_number":846,"context_line":"                                          resource_url)"},{"line_number":847,"context_line":""},{"line_number":848,"context_line":"    @wsme_pecan.wsexpose(wtypes.text, types.uuid, types.name)"},{"line_number":849,"context_line":"    def validate(self, node_uuid\u003dNone, node_name\u003dNone):"},{"line_number":850,"context_line":"        \"\"\"Validate the driver interfaces, using either UUID or name."},{"line_number":851,"context_line":""},{"line_number":852,"context_line":"        :param node_uuid: UUID of a node."}],"source_content_type":"text/x-python","patch_set":10,"id":"da86d52c_227a96f1","line":849,"in_reply_to":"da86d52c_9f4b9d2a","updated":"2015-02-03 03:05:06.000000000","message":"The reason I did this was to preserve the current interface.  If you see test_validate_by_uuid you\u0027ll see that the current interface is \"/nodes/validate?node_uuid\u003d%s\".  I don\u0027t want to change this to \"node_ident\" without consultation.  Hence why I added \"node_name\" as an additional parameter.\n\nI\u0027ve spoken with Deva on IRC, and he\u0027d like to see \u0027node_uuid\u0027 continue to be supported for backwards compatibility reasons, along with adding \u0027node\u0027 as a new option which will support both uuid and name as params.  I\u0027ll add this and upload a new patch with this support.","commit_id":"166f09f14b2b5e8f964e2f1b33234b031719421f"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"338f140e87110a95e334c7de8f53c5ef5a173130","unresolved":false,"context_lines":[{"line_number":859,"context_line":"                pecan.request.context, rpc_node.uuid, topic)"},{"line_number":860,"context_line":""},{"line_number":861,"context_line":"    @wsme_pecan.wsexpose(Node, types.uuid)"},{"line_number":862,"context_line":"    def get_one(self, node_uuid):"},{"line_number":863,"context_line":"        \"\"\"Retrieve information about the given node."},{"line_number":864,"context_line":""},{"line_number":865,"context_line":"        :param node_uuid: UUID of a node."}],"source_content_type":"text/x-python","patch_set":10,"id":"da86d52c_c23c5ac2","line":862,"updated":"2015-02-03 01:13:47.000000000","message":"This should take a name as well.","commit_id":"166f09f14b2b5e8f964e2f1b33234b031719421f"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"1c0ee093aeb11f57a0a5ece52bf504250fe21cfc","unresolved":false,"context_lines":[{"line_number":859,"context_line":"                pecan.request.context, rpc_node.uuid, topic)"},{"line_number":860,"context_line":""},{"line_number":861,"context_line":"    @wsme_pecan.wsexpose(Node, types.uuid)"},{"line_number":862,"context_line":"    def get_one(self, node_uuid):"},{"line_number":863,"context_line":"        \"\"\"Retrieve information about the given node."},{"line_number":864,"context_line":""},{"line_number":865,"context_line":"        :param node_uuid: UUID of a node."}],"source_content_type":"text/x-python","patch_set":10,"id":"da86d52c_2261b639","line":862,"in_reply_to":"da86d52c_c23c5ac2","updated":"2015-02-03 03:05:06.000000000","message":"Done","commit_id":"166f09f14b2b5e8f964e2f1b33234b031719421f"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":362,"context_line":""},{"line_number":363,"context_line":"        if target \u003d\u003d rpc_node.provision_state:"},{"line_number":364,"context_line":"            msg \u003d (_(\"Node %(node)s is already in the \u0027%(state)s\u0027 state.\") %"},{"line_number":365,"context_line":"                   {\u0027node\u0027: rpc_node[\u0027uuid\u0027], \u0027state\u0027: target})"},{"line_number":366,"context_line":"            raise wsme.exc.ClientSideError(msg, status_code\u003d400)"},{"line_number":367,"context_line":""},{"line_number":368,"context_line":"        if target not in (ir_states.ACTIVE, ir_states.DELETED,"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_0a2bce82","line":365,"updated":"2015-02-03 16:06:18.000000000","message":"do you want this to be node_ident instead of rpc_node[\u0027uuid\u0027]?","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":362,"context_line":""},{"line_number":363,"context_line":"        if target \u003d\u003d rpc_node.provision_state:"},{"line_number":364,"context_line":"            msg \u003d (_(\"Node %(node)s is already in the \u0027%(state)s\u0027 state.\") %"},{"line_number":365,"context_line":"                   {\u0027node\u0027: rpc_node[\u0027uuid\u0027], \u0027state\u0027: target})"},{"line_number":366,"context_line":"            raise wsme.exc.ClientSideError(msg, status_code\u003d400)"},{"line_number":367,"context_line":""},{"line_number":368,"context_line":"        if target not in (ir_states.ACTIVE, ir_states.DELETED,"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_293b2e39","line":365,"in_reply_to":"da86d52c_0a2bce82","updated":"2015-02-04 04:56:16.000000000","message":"Done","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":368,"context_line":"        if target not in (ir_states.ACTIVE, ir_states.DELETED,"},{"line_number":369,"context_line":"                          ir_states.REBUILD):"},{"line_number":370,"context_line":"            raise exception.InvalidStateRequested(state\u003dtarget,"},{"line_number":371,"context_line":"                                                  node\u003dnode_ident)"},{"line_number":372,"context_line":""},{"line_number":373,"context_line":"        valid_states_if_processing \u003d [ir_states.DEPLOYFAIL]"},{"line_number":374,"context_line":"        if target \u003d\u003d ir_states.DELETED:"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_ca5e1612","line":371,"updated":"2015-02-03 16:06:18.000000000","message":"Hmm, I hadn\u0027t thought about this. When do we use the identifier of the node that the user specified, vs the node\u0027s uuid, in messages to the user?\n\nAt the API level, I guess it makes sense to use the identifier that the user specified.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":368,"context_line":"        if target not in (ir_states.ACTIVE, ir_states.DELETED,"},{"line_number":369,"context_line":"                          ir_states.REBUILD):"},{"line_number":370,"context_line":"            raise exception.InvalidStateRequested(state\u003dtarget,"},{"line_number":371,"context_line":"                                                  node\u003dnode_ident)"},{"line_number":372,"context_line":""},{"line_number":373,"context_line":"        valid_states_if_processing \u003d [ir_states.DEPLOYFAIL]"},{"line_number":374,"context_line":"        if target \u003d\u003d ir_states.DELETED:"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_694a86ad","line":371,"in_reply_to":"da86d52c_ca5e1612","updated":"2015-02-04 04:56:16.000000000","message":"I don\u0027t think there\u0027s a right answer here, it\u0027s just one of preference.  I\u0027ll change user facing strings to node_ident to try and make this consistent.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":377,"context_line":"        if (rpc_node.target_provision_state is not None and"},{"line_number":378,"context_line":"                rpc_node.provision_state not in valid_states_if_processing):"},{"line_number":379,"context_line":"            msg \u003d (_(\u0027Node %s is already being provisioned or decommissioned.\u0027)"},{"line_number":380,"context_line":"                   % rpc_node.uuid)"},{"line_number":381,"context_line":"            raise wsme.exc.ClientSideError(msg, status_code\u003d409)  # Conflict"},{"line_number":382,"context_line":""},{"line_number":383,"context_line":"        if configdrive and target !\u003d ir_states.ACTIVE:"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_eaeafa0d","line":380,"updated":"2015-02-03 16:06:18.000000000","message":"So wherever we use uuid, we should replace with node_ident if that\u0027s what we want.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":377,"context_line":"        if (rpc_node.target_provision_state is not None and"},{"line_number":378,"context_line":"                rpc_node.provision_state not in valid_states_if_processing):"},{"line_number":379,"context_line":"            msg \u003d (_(\u0027Node %s is already being provisioned or decommissioned.\u0027)"},{"line_number":380,"context_line":"                   % rpc_node.uuid)"},{"line_number":381,"context_line":"            raise wsme.exc.ClientSideError(msg, status_code\u003d409)  # Conflict"},{"line_number":382,"context_line":""},{"line_number":383,"context_line":"        if configdrive and target !\u003d ir_states.ACTIVE:"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_b9a84f8e","line":380,"in_reply_to":"da86d52c_eaeafa0d","updated":"2015-02-04 04:56:16.000000000","message":"Done","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":846,"context_line":"                                          resource_url)"},{"line_number":847,"context_line":""},{"line_number":848,"context_line":"    @wsme_pecan.wsexpose(wtypes.text, types.uuid, types.uuid_or_name)"},{"line_number":849,"context_line":"    def validate(self, node_uuid\u003dNone, node\u003dNone):"},{"line_number":850,"context_line":"        \"\"\"Validate the driver interfaces, using the node\u0027s UUID or name."},{"line_number":851,"context_line":""},{"line_number":852,"context_line":"        :param node_uuid: UUID of a node."}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_25ea8575","line":849,"updated":"2015-02-03 16:06:18.000000000","message":"nit, for consistency, why not \u0027node\u0027 -\u003e \u0027node_ident\u0027?","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":846,"context_line":"                                          resource_url)"},{"line_number":847,"context_line":""},{"line_number":848,"context_line":"    @wsme_pecan.wsexpose(wtypes.text, types.uuid, types.uuid_or_name)"},{"line_number":849,"context_line":"    def validate(self, node_uuid\u003dNone, node\u003dNone):"},{"line_number":850,"context_line":"        \"\"\"Validate the driver interfaces, using the node\u0027s UUID or name."},{"line_number":851,"context_line":""},{"line_number":852,"context_line":"        :param node_uuid: UUID of a node."}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_79a89777","line":849,"in_reply_to":"da86d52c_25ea8575","updated":"2015-02-04 04:56:16.000000000","message":"I discussed this with Deva on IRC, and he suggested \u0027node\u0027 as it\u0027s a public API (somewhere around http://eavesdrop.openstack.org/irclogs/%23openstack-ironic/%23openstack-ironic.2015-02-03.log#2015-02-03T01:47:50)","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":855,"context_line":"        # Note(mrda): The \u0027node_uuid\u0027 interface is deprecated in favour"},{"line_number":856,"context_line":"        # of the \u0027node\u0027 interface"},{"line_number":857,"context_line":"        if node_uuid:"},{"line_number":858,"context_line":"            LOG.warning(_LW(\"The /nodes/validate?node_uuid\u003d... interface is \""},{"line_number":859,"context_line":"                            \"deprecated. Please use /nodes/validate?node\u003d... \""},{"line_number":860,"context_line":"                            \"instead\"))"},{"line_number":861,"context_line":"        rpc_node \u003d _get_rpc_node(node_uuid or node)"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_ea967aef","line":858,"updated":"2015-02-03 16:06:18.000000000","message":"It probably isn\u0027t useful to log warnings about this; here\u0027s an example where we removed a similar warning [1].\n\n[1] https://review.openstack.org/#/c/136934/","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":855,"context_line":"        # Note(mrda): The \u0027node_uuid\u0027 interface is deprecated in favour"},{"line_number":856,"context_line":"        # of the \u0027node\u0027 interface"},{"line_number":857,"context_line":"        if node_uuid:"},{"line_number":858,"context_line":"            LOG.warning(_LW(\"The /nodes/validate?node_uuid\u003d... interface is \""},{"line_number":859,"context_line":"                            \"deprecated. Please use /nodes/validate?node\u003d... \""},{"line_number":860,"context_line":"                            \"instead\"))"},{"line_number":861,"context_line":"        rpc_node \u003d _get_rpc_node(node_uuid or node)"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_99df0b0d","line":858,"in_reply_to":"da86d52c_ea967aef","updated":"2015-02-04 04:56:16.000000000","message":"Ok, shall remove.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"286c278e1338a69ccb30336dd106e7b3cdb74725","unresolved":false,"context_lines":[{"line_number":857,"context_line":"        if node_uuid:"},{"line_number":858,"context_line":"            LOG.warning(_LW(\"The /nodes/validate?node_uuid\u003d... interface is \""},{"line_number":859,"context_line":"                            \"deprecated. Please use /nodes/validate?node\u003d... \""},{"line_number":860,"context_line":"                            \"instead\"))"},{"line_number":861,"context_line":"        rpc_node \u003d _get_rpc_node(node_uuid or node)"},{"line_number":862,"context_line":""},{"line_number":863,"context_line":"        topic \u003d pecan.request.rpcapi.get_topic_for(rpc_node)"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_763b5d38","line":860,"updated":"2015-02-03 14:23:15.000000000","message":"Right, there\u0027s a problem here, there\u0027s 2 syntax that wsme will allow we to trigger this validate method:\n\n1- GET /nodes/validate?node_uuid\u003d...\n\nor\n\n2- GET /nodes/\u003cnode uuid\u003e/validate\n\n...\n\nNow I think that for logical name we should support the 2) syntax as well, because the rest of the API is accepting it as part of this work.\n\nWSME will pick the first parameter there if not specified, so right with the code as-is right now if we do:\n\nGET /nodes/\u003cnode logical name\u003e/validate\n\nThat will fail because it will try to validate the logical name against the types.uuid.\n\nSo my suggestion here would be to invert the parameters from the validate() method to:\n\n    @wsme_pecan.wsexpose(wtypes.text, types.uuid_or_name, types.uuid)\n    validate(self, node\u003dNone, node_uuid\u003dNone): \n     ...\n\nBecause that way we keep the backward compatibility of things, if they do:\n\n GET /nodes/\u003cnode uuid\u003e/validate - works\n GET /nodes/\u003cnode logical name\u003e/validate - works\n GET /nodes/validate?node_uuid\u003d... - works\n GET /nodes/validate?node\u003d... - works","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":857,"context_line":"        if node_uuid:"},{"line_number":858,"context_line":"            LOG.warning(_LW(\"The /nodes/validate?node_uuid\u003d... interface is \""},{"line_number":859,"context_line":"                            \"deprecated. Please use /nodes/validate?node\u003d... \""},{"line_number":860,"context_line":"                            \"instead\"))"},{"line_number":861,"context_line":"        rpc_node \u003d _get_rpc_node(node_uuid or node)"},{"line_number":862,"context_line":""},{"line_number":863,"context_line":"        topic \u003d pecan.request.rpcapi.get_topic_for(rpc_node)"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_196f9b2c","line":860,"in_reply_to":"da86d52c_763b5d38","updated":"2015-02-04 04:56:16.000000000","message":"Fantastic suggestion Lucas!  Really appreciate your eyeballs and understanding of WSME here.  Thank you.  Implemented as suggested.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":929,"context_line":"                    \"is in progress.\")"},{"line_number":930,"context_line":"            raise wsme.exc.ClientSideError(msg % node_ident, status_code\u003d409)"},{"line_number":931,"context_line":""},{"line_number":932,"context_line":"        # Verify that if we\u0027re patching \u0027name\u0027 that it is a valid"},{"line_number":933,"context_line":"        for p in patch:"},{"line_number":934,"context_line":"            name \u003d api_utils.get_patch_value(patch, \u0027/name\u0027)"},{"line_number":935,"context_line":"            if name and not utils.is_hostname_safe(name):"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_05ee6122","line":932,"updated":"2015-02-03 16:06:18.000000000","message":"Oh interesting. So we\u0027re allowing the user to change the name.\n\nnit: \u0027a valid\u0027 -\u003e \u0027valid\u0027 or \u0027a valid name\u0027?","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":929,"context_line":"                    \"is in progress.\")"},{"line_number":930,"context_line":"            raise wsme.exc.ClientSideError(msg % node_ident, status_code\u003d409)"},{"line_number":931,"context_line":""},{"line_number":932,"context_line":"        # Verify that if we\u0027re patching \u0027name\u0027 that it is a valid"},{"line_number":933,"context_line":"        for p in patch:"},{"line_number":934,"context_line":"            name \u003d api_utils.get_patch_value(patch, \u0027/name\u0027)"},{"line_number":935,"context_line":"            if name and not utils.is_hostname_safe(name):"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_3988dfc4","line":932,"in_reply_to":"da86d52c_05ee6122","updated":"2015-02-04 04:56:16.000000000","message":"Done","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":930,"context_line":"            raise wsme.exc.ClientSideError(msg % node_ident, status_code\u003d409)"},{"line_number":931,"context_line":""},{"line_number":932,"context_line":"        # Verify that if we\u0027re patching \u0027name\u0027 that it is a valid"},{"line_number":933,"context_line":"        for p in patch:"},{"line_number":934,"context_line":"            name \u003d api_utils.get_patch_value(patch, \u0027/name\u0027)"},{"line_number":935,"context_line":"            if name and not utils.is_hostname_safe(name):"},{"line_number":936,"context_line":"                msg \u003d _(\"Node cannot have it\u0027s name changed to %s\")"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_25dfe53c","line":933,"updated":"2015-02-03 16:06:18.000000000","message":"why do you need this for loop? I don\u0027t see \u0027p\u0027 used.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":930,"context_line":"            raise wsme.exc.ClientSideError(msg % node_ident, status_code\u003d409)"},{"line_number":931,"context_line":""},{"line_number":932,"context_line":"        # Verify that if we\u0027re patching \u0027name\u0027 that it is a valid"},{"line_number":933,"context_line":"        for p in patch:"},{"line_number":934,"context_line":"            name \u003d api_utils.get_patch_value(patch, \u0027/name\u0027)"},{"line_number":935,"context_line":"            if name and not utils.is_hostname_safe(name):"},{"line_number":936,"context_line":"                msg \u003d _(\"Node cannot have it\u0027s name changed to %s\")"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_39761fd8","line":933,"in_reply_to":"da86d52c_25dfe53c","updated":"2015-02-04 04:56:16.000000000","message":"Sorry, that was left over from before I split out a new utility function.  Removed.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":933,"context_line":"        for p in patch:"},{"line_number":934,"context_line":"            name \u003d api_utils.get_patch_value(patch, \u0027/name\u0027)"},{"line_number":935,"context_line":"            if name and not utils.is_hostname_safe(name):"},{"line_number":936,"context_line":"                msg \u003d _(\"Node cannot have it\u0027s name changed to %s\")"},{"line_number":937,"context_line":"                raise wsme.exc.ClientSideError(msg % name, status_code\u003d409)"},{"line_number":938,"context_line":""},{"line_number":939,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_a51bd519","line":936,"updated":"2015-02-03 16:06:18.000000000","message":"nit s/it\u0027s/its/\n\nMaybe we should indicate why it can\u0027t be changed -- because the string is an invalid name. Otherwise it could look like we don\u0027t allow nodes to change their names.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":933,"context_line":"        for p in patch:"},{"line_number":934,"context_line":"            name \u003d api_utils.get_patch_value(patch, \u0027/name\u0027)"},{"line_number":935,"context_line":"            if name and not utils.is_hostname_safe(name):"},{"line_number":936,"context_line":"                msg \u003d _(\"Node cannot have it\u0027s name changed to %s\")"},{"line_number":937,"context_line":"                raise wsme.exc.ClientSideError(msg % name, status_code\u003d409)"},{"line_number":938,"context_line":""},{"line_number":939,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_7c46c550","line":936,"in_reply_to":"da86d52c_a51bd519","updated":"2015-02-04 04:56:16.000000000","message":"Done","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5ab649ef2298b38920f12640eba1baa7a112e13e","unresolved":false,"context_lines":[{"line_number":707,"context_line":"    def delete(self, node_ident):"},{"line_number":708,"context_line":"        \"\"\"Remove the node from maintenance mode."},{"line_number":709,"context_line":""},{"line_number":710,"context_line":"        :param node_uuid: the UUID or logical name of a node."},{"line_number":711,"context_line":""},{"line_number":712,"context_line":"        \"\"\""},{"line_number":713,"context_line":"        self._set_maintenance(node_ident, False)"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_c96eed2e","line":710,"updated":"2015-02-04 17:45:28.000000000","message":"s/node_uuid/node_ident/","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"5a3129c111d4230e6a675c327e218dd67766a935","unresolved":false,"context_lines":[{"line_number":707,"context_line":"    def delete(self, node_ident):"},{"line_number":708,"context_line":"        \"\"\"Remove the node from maintenance mode."},{"line_number":709,"context_line":""},{"line_number":710,"context_line":"        :param node_uuid: the UUID or logical name of a node."},{"line_number":711,"context_line":""},{"line_number":712,"context_line":"        \"\"\""},{"line_number":713,"context_line":"        self._set_maintenance(node_ident, False)"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_28913a47","line":710,"in_reply_to":"da86d52c_c96eed2e","updated":"2015-02-04 21:56:18.000000000","message":"Done","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5ab649ef2298b38920f12640eba1baa7a112e13e","unresolved":false,"context_lines":[{"line_number":916,"context_line":"        if node.name and not utils.is_hostname_safe(node.name):"},{"line_number":917,"context_line":"            msg \u003d _(\"Cannot create node with invalid name %(name)s\")"},{"line_number":918,"context_line":"            raise wsme.exc.ClientSideError(msg % {\u0027name\u0027: node.name},"},{"line_number":919,"context_line":"                                           status_code\u003d409)"},{"line_number":920,"context_line":""},{"line_number":921,"context_line":"        new_node \u003d objects.Node(pecan.request.context,"},{"line_number":922,"context_line":"                                **node.as_dict())"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_44282486","line":919,"updated":"2015-02-04 17:45:28.000000000","message":"I think we want to return 400, not 409, because the request is bad.","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"5a3129c111d4230e6a675c327e218dd67766a935","unresolved":false,"context_lines":[{"line_number":916,"context_line":"        if node.name and not utils.is_hostname_safe(node.name):"},{"line_number":917,"context_line":"            msg \u003d _(\"Cannot create node with invalid name %(name)s\")"},{"line_number":918,"context_line":"            raise wsme.exc.ClientSideError(msg % {\u0027name\u0027: node.name},"},{"line_number":919,"context_line":"                                           status_code\u003d409)"},{"line_number":920,"context_line":""},{"line_number":921,"context_line":"        new_node \u003d objects.Node(pecan.request.context,"},{"line_number":922,"context_line":"                                **node.as_dict())"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_28b85ac7","line":919,"in_reply_to":"da86d52c_44282486","updated":"2015-02-04 21:56:18.000000000","message":"Done","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5ab649ef2298b38920f12640eba1baa7a112e13e","unresolved":false,"context_lines":[{"line_number":953,"context_line":"                    \"name \u0027%(name)s\u0027\")"},{"line_number":954,"context_line":"            raise wsme.exc.ClientSideError(msg % {\u0027node\u0027: node_ident,"},{"line_number":955,"context_line":"                                                  \u0027name\u0027: name},"},{"line_number":956,"context_line":"                                           status_code\u003d409)"},{"line_number":957,"context_line":""},{"line_number":958,"context_line":"        try:"},{"line_number":959,"context_line":"            node_dict \u003d rpc_node.as_dict()"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_a423a0a5","line":956,"updated":"2015-02-04 17:45:28.000000000","message":"400 here too.","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"5a3129c111d4230e6a675c327e218dd67766a935","unresolved":false,"context_lines":[{"line_number":953,"context_line":"                    \"name \u0027%(name)s\u0027\")"},{"line_number":954,"context_line":"            raise wsme.exc.ClientSideError(msg % {\u0027node\u0027: node_ident,"},{"line_number":955,"context_line":"                                                  \u0027name\u0027: name},"},{"line_number":956,"context_line":"                                           status_code\u003d409)"},{"line_number":957,"context_line":""},{"line_number":958,"context_line":"        try:"},{"line_number":959,"context_line":"            node_dict \u003d rpc_node.as_dict()"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_68aed282","line":956,"in_reply_to":"da86d52c_a423a0a5","updated":"2015-02-04 21:56:18.000000000","message":"Done","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"fb583842ec4b24c9043218e90fdcf87db18e3bac","unresolved":false,"context_lines":[{"line_number":933,"context_line":"        if node.name and not utils.is_hostname_safe(node.name):"},{"line_number":934,"context_line":"            msg \u003d _(\"Cannot create node with invalid name %(name)s\")"},{"line_number":935,"context_line":"            raise wsme.exc.ClientSideError(msg % {\u0027name\u0027: node.name},"},{"line_number":936,"context_line":"                                           status_code\u003d400)"},{"line_number":937,"context_line":""},{"line_number":938,"context_line":"        new_node \u003d objects.Node(pecan.request.context,"},{"line_number":939,"context_line":"                                **node.as_dict())"}],"source_content_type":"text/x-python","patch_set":20,"id":"da86d52c_dec3dc35","line":936,"updated":"2015-02-05 14:25:56.000000000","message":"If we make Node.name a types.NameType, that will handle this validation for us, right?","commit_id":"16ecc2bfdff6e80d09d5acf61232655698ee7ff2"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6cc95a2b44b799944313b42ce8983ac69a3bfcf0","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        return objects.Node.get_by_name(pecan.request.context, node_ident)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    # it\u0027s not a valid uuid, or it\u0027s not a valid name, or we don\u0027t allow names"},{"line_number":111,"context_line":"    raise exception.InvalidUUID(uuid\u003dnode_ident)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"class NodePatchType(types.JsonPatchType):"}],"source_content_type":"text/x-python","patch_set":22,"id":"da86d52c_7efd87b0","line":111,"updated":"2015-02-05 17:52:16.000000000","message":"the message from this is \u0027Expected a uuid but received \u003cnode_ident\u003e\u0027\n\nNot sure how helpful that is, but we can improve on it later.","commit_id":"1ed7d5ac75d8f9975bc05e05c3428a96bc395faa"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6cc95a2b44b799944313b42ce8983ac69a3bfcf0","unresolved":false,"context_lines":[{"line_number":908,"context_line":"        :param node: UUID or name of a node."},{"line_number":909,"context_line":"        :param node_uuid: UUID of a node."},{"line_number":910,"context_line":"        \"\"\""},{"line_number":911,"context_line":"        rpc_node \u003d _get_rpc_node(node_uuid or node)"},{"line_number":912,"context_line":""},{"line_number":913,"context_line":"        topic \u003d pecan.request.rpcapi.get_topic_for(rpc_node)"},{"line_number":914,"context_line":"        return pecan.request.rpcapi.validate_driver_interfaces("}],"source_content_type":"text/x-python","patch_set":22,"id":"da86d52c_1e29ebe5","line":911,"updated":"2015-02-05 17:52:16.000000000","message":"Are we allowing the use of \u0027node\u0027 (instead of \u0027node_uuid\u0027) in the API for v1.0, or only with microversion 5+? [I\u0027m still trying to get the hang of microversions...]","commit_id":"1ed7d5ac75d8f9975bc05e05c3428a96bc395faa"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6cc95a2b44b799944313b42ce8983ac69a3bfcf0","unresolved":false,"context_lines":[{"line_number":955,"context_line":"        # that it is a valid name"},{"line_number":956,"context_line":"        if node.name:"},{"line_number":957,"context_line":"            if not allow_logical_names():"},{"line_number":958,"context_line":"                raise exception.InvalidUUID(uuid\u003dnode.name)"},{"line_number":959,"context_line":"            if not utils.is_hostname_safe(node.name):"},{"line_number":960,"context_line":"                msg \u003d _(\"Cannot create node with invalid name %(name)s\")"},{"line_number":961,"context_line":"                raise wsme.exc.ClientSideError(msg % {\u0027name\u0027: node.name},"}],"source_content_type":"text/x-python","patch_set":22,"id":"da86d52c_de9e7306","line":958,"updated":"2015-02-05 17:52:16.000000000","message":"That doesn\u0027t seem like the right exception to raise. \u0027Expected a uuid but received \u003cnode.name\u003e\u0027\n\nFor the mangeable state stuff, we\u0027re raising exception.NotAcceptable(); maybe we should a similar thing here, and mention the microversion needed?","commit_id":"1ed7d5ac75d8f9975bc05e05c3428a96bc395faa"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6cc95a2b44b799944313b42ce8983ac69a3bfcf0","unresolved":false,"context_lines":[{"line_number":991,"context_line":""},{"line_number":992,"context_line":"        # Verify that if we\u0027re patching \u0027name\u0027 that it is a valid"},{"line_number":993,"context_line":"        name \u003d api_utils.get_patch_value(patch, \u0027/name\u0027)"},{"line_number":994,"context_line":"        if name and not utils.is_hostname_safe(name):"},{"line_number":995,"context_line":"            msg \u003d _(\"Node %(node)s: Cannot change name to invalid \""},{"line_number":996,"context_line":"                    \"name \u0027%(name)s\u0027\")"},{"line_number":997,"context_line":"            raise wsme.exc.ClientSideError(msg % {\u0027node\u0027: node_ident,"}],"source_content_type":"text/x-python","patch_set":22,"id":"da86d52c_de3af3e5","line":994,"updated":"2015-02-05 17:52:16.000000000","message":"if name and not allow_logical_names()...","commit_id":"1ed7d5ac75d8f9975bc05e05c3428a96bc395faa"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5f5c3995565f81cc59d37ed59a97f47575fb51d6","unresolved":false,"context_lines":[{"line_number":97,"context_line":"    :param node_ident: the UUID or logical name of a node."},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    :returns: The RPC Node."},{"line_number":100,"context_line":"    :raises: NodeNotFound if the node is not found."},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    \"\"\""},{"line_number":103,"context_line":"    # Check to see if the node_ident is a valid UUID.  If it is, treat it"}],"source_content_type":"text/x-python","patch_set":28,"id":"da86d52c_a19c806b","line":100,"updated":"2015-02-11 10:40:29.000000000","message":"nit: :raises: InvalidUUID","commit_id":"b559771318cdb3d1a3bf20d7e02199e26f121fe5"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"e250ae39b68fcaf5e3493ec838a65476e76feec8","unresolved":false,"context_lines":[{"line_number":97,"context_line":"    :param node_ident: the UUID or logical name of a node."},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    :returns: The RPC Node."},{"line_number":100,"context_line":"    :raises: NodeNotFound if the node is not found."},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    \"\"\""},{"line_number":103,"context_line":"    # Check to see if the node_ident is a valid UUID.  If it is, treat it"}],"source_content_type":"text/x-python","patch_set":28,"id":"da86d52c_24f6d05d","line":100,"in_reply_to":"da86d52c_a19c806b","updated":"2015-02-11 15:55:01.000000000","message":"Added InvalidUuidOrName in addition (the NodeNotFound is raised from the db search if the node is not found)","commit_id":"b559771318cdb3d1a3bf20d7e02199e26f121fe5"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5f5c3995565f81cc59d37ed59a97f47575fb51d6","unresolved":false,"context_lines":[{"line_number":111,"context_line":"        return objects.Node.get_by_name(pecan.request.context, node_ident)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    # It\u0027s not a valid uuid, or it\u0027s not a valid name, or we don\u0027t allow names"},{"line_number":114,"context_line":"    raise exception.InvalidUUID(uuid\u003dnode_ident)"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"class NodePatchType(types.JsonPatchType):"}],"source_content_type":"text/x-python","patch_set":28,"id":"da86d52c_e1b758d6","line":114,"updated":"2015-02-11 10:40:29.000000000","message":"Looks a bit wrong to raise InvalidUUID when a name is supplied or a names are not allowed.\n\nBtw shouldn\u0027t it raise InvalidUuidOrName here?","commit_id":"b559771318cdb3d1a3bf20d7e02199e26f121fe5"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"e250ae39b68fcaf5e3493ec838a65476e76feec8","unresolved":false,"context_lines":[{"line_number":111,"context_line":"        return objects.Node.get_by_name(pecan.request.context, node_ident)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    # It\u0027s not a valid uuid, or it\u0027s not a valid name, or we don\u0027t allow names"},{"line_number":114,"context_line":"    raise exception.InvalidUUID(uuid\u003dnode_ident)"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"class NodePatchType(types.JsonPatchType):"}],"source_content_type":"text/x-python","patch_set":28,"id":"da86d52c_a4464079","line":114,"in_reply_to":"da86d52c_e1b758d6","updated":"2015-02-11 15:55:01.000000000","message":"It did originally, but a few edits and merges later and this was lost :)  Fixed.","commit_id":"b559771318cdb3d1a3bf20d7e02199e26f121fe5"}],"ironic/api/controllers/v1/types.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"37f7cd44fd82ad0ba2fc97342a6844e667dd8c4a","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    @staticmethod"},{"line_number":85,"context_line":"    def validate(value):"},{"line_number":86,"context_line":"        if not utils.is_hostname_safe(value):"},{"line_number":87,"context_line":"            raise exception.InvalidUuidOrName(name\u003dvalue)"},{"line_number":88,"context_line":"        return value"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_99c3b589","line":87,"updated":"2014-12-17 17:36:29.000000000","message":"Not sure, but wouldn\u0027t it be more explicit if the exception was invalid Name. If it was a valid UUID, this exception will still be raised, and that would be confusing.","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"bd0a492cfb5baaad6b191adda1cfd259a8e43e02","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    @staticmethod"},{"line_number":85,"context_line":"    def validate(value):"},{"line_number":86,"context_line":"        if not utils.is_hostname_safe(value):"},{"line_number":87,"context_line":"            raise exception.InvalidUuidOrName(name\u003dvalue)"},{"line_number":88,"context_line":"        return value"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_13d512b9","line":87,"in_reply_to":"3a961159_99c3b589","updated":"2014-12-29 04:54:22.000000000","message":"Thanks Ruby - fixed","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"}],"ironic/api/controllers/v1/utils.py":[{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"fb583842ec4b24c9043218e90fdcf87db18e3bac","unresolved":false,"context_lines":[{"line_number":55,"context_line":"def get_patch_value(patch, path):"},{"line_number":56,"context_line":"    for p in patch:"},{"line_number":57,"context_line":"        if p[\u0027path\u0027] \u003d\u003d path:"},{"line_number":58,"context_line":"            return p[\u0027value\u0027]"}],"source_content_type":"text/x-python","patch_set":20,"id":"da86d52c_9efb2478","line":58,"updated":"2015-02-05 14:25:56.000000000","message":"If we let wsme do the validation for us, I think we can drop this.","commit_id":"16ecc2bfdff6e80d09d5acf61232655698ee7ff2"}],"ironic/common/exception.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"7bfc5d030a883cc3f01d503fe1b24e864cd612d2","unresolved":false,"context_lines":[{"line_number":143,"context_line":"    message \u003d _(\"Instance %(instance_uuid)s is already associated with a node,\""},{"line_number":144,"context_line":"                \" it cannot be associated with this other node %(node)s\")"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"class InvalidUUID(Invalid):"},{"line_number":148,"context_line":"    message \u003d _(\"Expected a uuid but received %(uuid)s.\")"},{"line_number":149,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_39669d2a","side":"PARENT","line":146,"updated":"2014-12-15 12:36:08.000000000","message":"should not be deleted","commit_id":"9dc2166dce09305a086a263f6eba8602e912349b"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"0445f3f40d0b24c8da0aa18eb7a7ec68633004e7","unresolved":false,"context_lines":[{"line_number":143,"context_line":"    message \u003d _(\"Instance %(instance_uuid)s is already associated with a node,\""},{"line_number":144,"context_line":"                \" it cannot be associated with this other node %(node)s\")"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"class InvalidUUID(Invalid):"},{"line_number":148,"context_line":"    message \u003d _(\"Expected a uuid but received %(uuid)s.\")"},{"line_number":149,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_49c0e6e0","side":"PARENT","line":146,"in_reply_to":"3a961159_39669d2a","updated":"2014-12-16 00:09:39.000000000","message":"Done","commit_id":"9dc2166dce09305a086a263f6eba8602e912349b"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"7bfc5d030a883cc3f01d503fe1b24e864cd612d2","unresolved":false,"context_lines":[{"line_number":147,"context_line":"    message \u003d _(\"Expected a uuid but received %(uuid)s.\")"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"class InvalidUuidOrName(Invalid):"},{"line_number":150,"context_line":"    message \u003d _(\"Expected a logical name or uuid but received %(name)s.\")"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"class InvalidIdentity(Invalid):"},{"line_number":153,"context_line":"    message \u003d _(\"Expected an uuid or int but received %(identity)s.\")"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_5969a9f7","line":150,"updated":"2014-12-15 12:36:08.000000000","message":"2 new lines required around this IIRC","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"0445f3f40d0b24c8da0aa18eb7a7ec68633004e7","unresolved":false,"context_lines":[{"line_number":147,"context_line":"    message \u003d _(\"Expected a uuid but received %(uuid)s.\")"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"class InvalidUuidOrName(Invalid):"},{"line_number":150,"context_line":"    message \u003d _(\"Expected a logical name or uuid but received %(name)s.\")"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"class InvalidIdentity(Invalid):"},{"line_number":153,"context_line":"    message \u003d _(\"Expected an uuid or int but received %(identity)s.\")"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_69b5a27d","line":150,"in_reply_to":"3a961159_5969a9f7","updated":"2014-12-16 00:09:39.000000000","message":"Done","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":159,"context_line":""},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"class InvalidName(Invalid):"},{"line_number":162,"context_line":"    message \u003d _(\"Expected a logical name but received %(name)s.\")"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":""},{"line_number":165,"context_line":"class InvalidIdentity(Invalid):"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_80c07f7d","line":162,"updated":"2015-02-03 16:06:18.000000000","message":"It would be great to put more information here about the syntax for a valid logical name but I can\u0027t think of any description that would be short.\n\nFor this exception, maybe putting \u0027invalid\u0027 might help.\n\n[I don\u0027t have a concrete answer for this, maybe someone else does, or just leave it as-is until someone asks...]","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":159,"context_line":""},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"class InvalidName(Invalid):"},{"line_number":162,"context_line":"    message \u003d _(\"Expected a logical name but received %(name)s.\")"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":""},{"line_number":165,"context_line":"class InvalidIdentity(Invalid):"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_3c88cdc4","line":162,"in_reply_to":"da86d52c_80c07f7d","updated":"2015-02-04 04:56:16.000000000","message":"I don\u0027t think there\u0027s an easy solution here.  I don\u0027t think I should be referring to RFCs or putting regexs here in an error message, so I think we just leave it for now.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"}],"ironic/common/utils.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"7bfc5d030a883cc3f01d503fe1b24e864cd612d2","unresolved":false,"context_lines":[{"line_number":202,"context_line":"    m \u003d \u0027^[a-z0-9]([a-z0-9\\-]{0,61}[a-z0-9]|[a-z0-9]{0,62})?$\u0027"},{"line_number":203,"context_line":"    if isinstance(hostname, six.string_types) and re.match(m, hostname):"},{"line_number":204,"context_line":"        return True"},{"line_number":205,"context_line":"    return False"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"def validate_and_normalize_mac(address):"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_d974b9d0","line":205,"updated":"2014-12-15 12:36:08.000000000","message":"simpler\n\n return isinstance(hostname, six.string_types) and re.match(m, hostname)","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"0445f3f40d0b24c8da0aa18eb7a7ec68633004e7","unresolved":false,"context_lines":[{"line_number":202,"context_line":"    m \u003d \u0027^[a-z0-9]([a-z0-9\\-]{0,61}[a-z0-9]|[a-z0-9]{0,62})?$\u0027"},{"line_number":203,"context_line":"    if isinstance(hostname, six.string_types) and re.match(m, hostname):"},{"line_number":204,"context_line":"        return True"},{"line_number":205,"context_line":"    return False"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"def validate_and_normalize_mac(address):"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_a9aeaa2d","line":205,"in_reply_to":"3a961159_d974b9d0","updated":"2014-12-16 00:09:39.000000000","message":"Done","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"fe1025ded6f5345a7dcc81b5a183432b7096a8e6","unresolved":false,"context_lines":[{"line_number":190,"context_line":"    \"\"\"Determine if the supplied hostname is RFC compliant."},{"line_number":191,"context_line":""},{"line_number":192,"context_line":"    Check of the supplied hostname conforms to:"},{"line_number":193,"context_line":"        * http://en.wikipedia.org/wiki/Hostname"},{"line_number":194,"context_line":"        * http://tools.ietf.org/html/rfc952"},{"line_number":195,"context_line":"        * http://tools.ietf.org/html/rfc1123"},{"line_number":196,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_d758cf8c","line":193,"updated":"2014-12-29 13:23:40.000000000","message":"It says that hostname consists of labels separated by dots. Seems that here you\u0027re validating not the hostname, but label.","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"6e52f9105f326c3d063250c81b3f35fdcf93b207","unresolved":false,"context_lines":[{"line_number":190,"context_line":"    \"\"\"Determine if the supplied hostname is RFC compliant."},{"line_number":191,"context_line":""},{"line_number":192,"context_line":"    Check of the supplied hostname conforms to:"},{"line_number":193,"context_line":"        * http://en.wikipedia.org/wiki/Hostname"},{"line_number":194,"context_line":"        * http://tools.ietf.org/html/rfc952"},{"line_number":195,"context_line":"        * http://tools.ietf.org/html/rfc1123"},{"line_number":196,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_f1106cad","line":193,"in_reply_to":"3a961159_d758cf8c","updated":"2015-01-05 22:58:48.000000000","message":"We\u0027re looking for the hostname only portion here, not the full FQDN - hence no dots required (and no domain part and hence no _ chars allowed).\n\ni.e. hostname(.domain)*","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"fe1025ded6f5345a7dcc81b5a183432b7096a8e6","unresolved":false,"context_lines":[{"line_number":198,"context_line":"    :returns: True if valid. False if not."},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"    \"\"\""},{"line_number":201,"context_line":"    m \u003d \u0027^[a-z0-9]([a-z0-9\\-]{0,61}[a-z0-9]|[a-z0-9]{0,62})?$\u0027"},{"line_number":202,"context_line":"    return isinstance(hostname, six.string_types) and re.match(m, hostname)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_97c5670c","line":201,"updated":"2014-12-29 13:23:40.000000000","message":"Maybe it can be simplified like \u0027^[a-z0-9]([a-z0-9\\-]{0,61})?[a-z0-9]?$\u0027","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"6e52f9105f326c3d063250c81b3f35fdcf93b207","unresolved":false,"context_lines":[{"line_number":198,"context_line":"    :returns: True if valid. False if not."},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"    \"\"\""},{"line_number":201,"context_line":"    m \u003d \u0027^[a-z0-9]([a-z0-9\\-]{0,61}[a-z0-9]|[a-z0-9]{0,62})?$\u0027"},{"line_number":202,"context_line":"    return isinstance(hostname, six.string_types) and re.match(m, hostname)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_5113000d","line":201,"in_reply_to":"3a961159_2d68e620","updated":"2015-01-05 22:58:48.000000000","message":"That is a great question!  Thanks for raising it.\n\nAccording to the spec for this work, we\u0027re wanting hostnames to be able to be used as logical names for baremetal instances.  Consequently, we want lower case logical names when we add/modify a logical name.","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"111e97edd9f0050fdc2c2f1d60becf616152a99d","unresolved":false,"context_lines":[{"line_number":198,"context_line":"    :returns: True if valid. False if not."},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"    \"\"\""},{"line_number":201,"context_line":"    m \u003d \u0027^[a-z0-9]([a-z0-9\\-]{0,61}[a-z0-9]|[a-z0-9]{0,62})?$\u0027"},{"line_number":202,"context_line":"    return isinstance(hostname, six.string_types) and re.match(m, hostname)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_edb33ee7","line":201,"in_reply_to":"3a961159_97c5670c","updated":"2014-12-29 14:32:06.000000000","message":"Oops, regexp in comment is incorrect, should be \u0027^[a-z0-9]([a-z0-9\\-]{0,61}[a-z0-9])?$\u0027","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"d2857df0f00724507c9d6e073997971746d0b4a9","unresolved":false,"context_lines":[{"line_number":198,"context_line":"    :returns: True if valid. False if not."},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"    \"\"\""},{"line_number":201,"context_line":"    m \u003d \u0027^[a-z0-9]([a-z0-9\\-]{0,61}[a-z0-9]|[a-z0-9]{0,62})?$\u0027"},{"line_number":202,"context_line":"    return isinstance(hostname, six.string_types) and re.match(m, hostname)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_2d68e620","line":201,"in_reply_to":"3a961159_edb33ee7","updated":"2014-12-29 14:40:49.000000000","message":"And what about upper case letters?","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"6e52f9105f326c3d063250c81b3f35fdcf93b207","unresolved":false,"context_lines":[{"line_number":198,"context_line":"    :returns: True if valid. False if not."},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"    \"\"\""},{"line_number":201,"context_line":"    m \u003d \u0027^[a-z0-9]([a-z0-9\\-]{0,61}[a-z0-9]|[a-z0-9]{0,62})?$\u0027"},{"line_number":202,"context_line":"    return isinstance(hostname, six.string_types) and re.match(m, hostname)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_b147c4bb","line":201,"in_reply_to":"3a961159_edb33ee7","updated":"2015-01-05 22:58:48.000000000","message":"Thanks Vladyslav, nice optimisation.","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"d084db2dd6e7928a1c7052c250f57b12d7802559","unresolved":false,"context_lines":[{"line_number":183,"context_line":"    \"\"\""},{"line_number":184,"context_line":"    m \u003d \"[0-9a-f]{2}(:[0-9a-f]{2}){5}$\""},{"line_number":185,"context_line":"    return (isinstance(address, six.string_types) and"},{"line_number":186,"context_line":"            re.match(m, address.lower()))"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"def is_hostname_safe(hostname):"}],"source_content_type":"text/x-python","patch_set":18,"id":"da86d52c_cd76d405","line":186,"updated":"2015-02-05 13:29:39.000000000","message":"cool but unrelated change to the patch","commit_id":"be3788edae5b09dafbee96acdf6b72f97d5a9e62"}],"ironic/conductor/manager.py":[{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"fe1025ded6f5345a7dcc81b5a183432b7096a8e6","unresolved":false,"context_lines":[{"line_number":1215,"context_line":"        :raises: MissingParameterValue if missing supplied info."},{"line_number":1216,"context_line":"        \"\"\""},{"line_number":1217,"context_line":"        LOG.debug(\u0027RPC get_console_information called for node %s\u0027 % ("},{"line_number":1218,"context_line":"            node_id))"},{"line_number":1219,"context_line":""},{"line_number":1220,"context_line":"        with task_manager.acquire(context, node_id, shared\u003dTrue) as task:"},{"line_number":1221,"context_line":"            node \u003d task.node"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_9afd8e0b","line":1218,"updated":"2014-12-29 13:23:40.000000000","message":"No need to change it now.","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"6b19afe30392a1ce5f9a0a4616398e40e1567542","unresolved":false,"context_lines":[{"line_number":1215,"context_line":"        :raises: MissingParameterValue if missing supplied info."},{"line_number":1216,"context_line":"        \"\"\""},{"line_number":1217,"context_line":"        LOG.debug(\u0027RPC get_console_information called for node %s\u0027 % ("},{"line_number":1218,"context_line":"            node_id))"},{"line_number":1219,"context_line":""},{"line_number":1220,"context_line":"        with task_manager.acquire(context, node_id, shared\u003dTrue) as task:"},{"line_number":1221,"context_line":"            node \u003d task.node"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a930d6b_1f9533e4","line":1218,"in_reply_to":"3a961159_9afd8e0b","updated":"2015-01-23 04:33:33.000000000","message":"Done","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"38e377bbf4f6c5518113acea1ac9e503aa59d9ab","unresolved":false,"context_lines":[{"line_number":997,"context_line":"        :raises: InvalidParameterValue when the wrong driver info is specified."},{"line_number":998,"context_line":"        :raises: MissingParameterValue if missing supplied info."},{"line_number":999,"context_line":"        \"\"\""},{"line_number":1000,"context_line":"        LOG.debug(\u0027RPC get_console_information called for node %s\u0027 % (node_id))"},{"line_number":1001,"context_line":""},{"line_number":1002,"context_line":"        with task_manager.acquire(context, node_id, shared\u003dTrue) as task:"},{"line_number":1003,"context_line":"            node \u003d task.node"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_984d9875","line":1000,"updated":"2015-02-02 12:58:39.000000000","message":"Seems to be unrelated.","commit_id":"cf6aa1928461404766ee2992075cf65e208c2b46"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"cab5334194b2222e03fadd51f4f57a23e091d924","unresolved":false,"context_lines":[{"line_number":997,"context_line":"        :raises: InvalidParameterValue when the wrong driver info is specified."},{"line_number":998,"context_line":"        :raises: MissingParameterValue if missing supplied info."},{"line_number":999,"context_line":"        \"\"\""},{"line_number":1000,"context_line":"        LOG.debug(\u0027RPC get_console_information called for node %s\u0027 % (node_id))"},{"line_number":1001,"context_line":""},{"line_number":1002,"context_line":"        with task_manager.acquire(context, node_id, shared\u003dTrue) as task:"},{"line_number":1003,"context_line":"            node \u003d task.node"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_dd9d265b","line":1000,"in_reply_to":"da86d52c_984d9875","updated":"2015-02-02 21:31:38.000000000","message":"Done","commit_id":"cf6aa1928461404766ee2992075cf65e208c2b46"}],"ironic/db/sqlalchemy/alembic/versions/3ae36a5f5131_add_logical_name.py":[{"author":{"_account_id":11929,"name":"Michael Turek","email":"mjturek@linux.vnet.ibm.com","username":"mjturek"},"change_message_id":"5c55858c6cfca96fbbdfec0e43a4586019c2df61","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"3a961159_c5104750","updated":"2014-12-15 15:39:36.000000000","message":"Missing the license header","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"0445f3f40d0b24c8da0aa18eb7a7ec68633004e7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"3a961159_e29e0754","in_reply_to":"3a961159_c5104750","updated":"2014-12-16 00:09:39.000000000","message":"Done","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":13362,"name":"Tan Lin","email":"lin.tan@intel.com","username":"zero"},"change_message_id":"a4dea40f92ccaf65c4c6e58a551fa70f7f2da782","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"def upgrade():"},{"line_number":18,"context_line":"    ### commands auto generated by Alembic - please adjust! ###"},{"line_number":19,"context_line":"    op.add_column(\u0027nodes\u0027, sa.Column(\u0027name\u0027, sa.String(length\u003d63), nullable\u003dTrue))"},{"line_number":20,"context_line":"    op.drop_index(\u0027nodes_conductor_affinity_fk\u0027, table_name\u003d\u0027nodes\u0027)"},{"line_number":21,"context_line":"    ### end Alembic commands ###"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_a4e984b8","line":18,"updated":"2014-12-15 12:53:21.000000000","message":"Should we remove this?","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"0445f3f40d0b24c8da0aa18eb7a7ec68633004e7","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"def upgrade():"},{"line_number":18,"context_line":"    ### commands auto generated by Alembic - please adjust! ###"},{"line_number":19,"context_line":"    op.add_column(\u0027nodes\u0027, sa.Column(\u0027name\u0027, sa.String(length\u003d63), nullable\u003dTrue))"},{"line_number":20,"context_line":"    op.drop_index(\u0027nodes_conductor_affinity_fk\u0027, table_name\u003d\u0027nodes\u0027)"},{"line_number":21,"context_line":"    ### end Alembic commands ###"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_ec7520fb","line":18,"in_reply_to":"3a961159_a4e984b8","updated":"2014-12-16 00:09:39.000000000","message":"Done","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"4a0bdf748aca0952e16760572f48fa8a9233d817","unresolved":false,"context_lines":[{"line_number":17,"context_line":"def upgrade():"},{"line_number":18,"context_line":"    ### commands auto generated by Alembic - please adjust! ###"},{"line_number":19,"context_line":"    op.add_column(\u0027nodes\u0027, sa.Column(\u0027name\u0027, sa.String(length\u003d63), nullable\u003dTrue))"},{"line_number":20,"context_line":"    op.drop_index(\u0027nodes_conductor_affinity_fk\u0027, table_name\u003d\u0027nodes\u0027)"},{"line_number":21,"context_line":"    ### end Alembic commands ###"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_5f9b4917","line":20,"updated":"2014-12-15 13:49:45.000000000","message":"Why this migration drops this?","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"0445f3f40d0b24c8da0aa18eb7a7ec68633004e7","unresolved":false,"context_lines":[{"line_number":17,"context_line":"def upgrade():"},{"line_number":18,"context_line":"    ### commands auto generated by Alembic - please adjust! ###"},{"line_number":19,"context_line":"    op.add_column(\u0027nodes\u0027, sa.Column(\u0027name\u0027, sa.String(length\u003d63), nullable\u003dTrue))"},{"line_number":20,"context_line":"    op.drop_index(\u0027nodes_conductor_affinity_fk\u0027, table_name\u003d\u0027nodes\u0027)"},{"line_number":21,"context_line":"    ### end Alembic commands ###"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_ccab041d","line":20,"in_reply_to":"3a961159_5f9b4917","updated":"2014-12-16 00:09:39.000000000","message":"I think this is because we are modifying the nodes table, and as such, the index should be regenerated.  But since this is autogenerated, I\u0027m tempted to leave it as is.","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"f76432a7735728f5937f2cad903af77e7ed834d3","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"def upgrade():"},{"line_number":30,"context_line":"    op.add_column(\u0027nodes\u0027, sa.Column(\u0027name\u0027, sa.String(length\u003d63),"},{"line_number":31,"context_line":"                  nullable\u003dTrue))"},{"line_number":32,"context_line":"    op.create_unique_constraint(\u0027uniq_nodes0name\u0027, \u0027nodes\u0027, [\u0027name\u0027])"},{"line_number":33,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_7e824b95","line":30,"updated":"2015-02-03 16:24:45.000000000","message":"Should 63 be a constant that could be used throughout the code?","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":1420,"name":"Adam Gandelman","email":"adamg@ubuntu.com","username":"gandelman-a"},"change_message_id":"7bf567b63b253aab9ad7a8f89bacf53e9f774c87","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"def upgrade():"},{"line_number":30,"context_line":"    op.add_column(\u0027nodes\u0027, sa.Column(\u0027name\u0027, sa.String(length\u003d63),"},{"line_number":31,"context_line":"                  nullable\u003dTrue))"},{"line_number":32,"context_line":"    op.create_unique_constraint(\u0027uniq_nodes0name\u0027, \u0027nodes\u0027, [\u0027name\u0027])"},{"line_number":33,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_c05ef711","line":30,"updated":"2015-02-03 15:37:37.000000000","message":"This length constraint needs to be asserted during API validation, otherwise we\u0027ll be raising and returning DB exceptions to the client.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"def upgrade():"},{"line_number":30,"context_line":"    op.add_column(\u0027nodes\u0027, sa.Column(\u0027name\u0027, sa.String(length\u003d63),"},{"line_number":31,"context_line":"                  nullable\u003dTrue))"},{"line_number":32,"context_line":"    op.create_unique_constraint(\u0027uniq_nodes0name\u0027, \u0027nodes\u0027, [\u0027name\u0027])"},{"line_number":33,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_3c244dc4","line":30,"in_reply_to":"da86d52c_7e824b95","updated":"2015-02-04 04:56:16.000000000","message":"That\u0027s a good idea John, but we don\u0027t actually use it elsewhere.  As mentioned in my comment to Adam, we enforce the length constraints in is_hostname_safe() and there we use 61 as a constant (due to the way the regex is constructed).  We also reference in that place the justification for this length.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":1420,"name":"Adam Gandelman","email":"adamg@ubuntu.com","username":"gandelman-a"},"change_message_id":"b56ea433fd4704d971e1aaf95cc9b120a46b1268","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"def upgrade():"},{"line_number":30,"context_line":"    op.add_column(\u0027nodes\u0027, sa.Column(\u0027name\u0027, sa.String(length\u003d63),"},{"line_number":31,"context_line":"                  nullable\u003dTrue))"},{"line_number":32,"context_line":"    op.create_unique_constraint(\u0027uniq_nodes0name\u0027, \u0027nodes\u0027, [\u0027name\u0027])"},{"line_number":33,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_60a46ba6","line":30,"in_reply_to":"da86d52c_c05ef711","updated":"2015-02-03 15:47:00.000000000","message":"... or wrapped in ironic.db.sqlalchemy.api","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"def upgrade():"},{"line_number":30,"context_line":"    op.add_column(\u0027nodes\u0027, sa.Column(\u0027name\u0027, sa.String(length\u003d63),"},{"line_number":31,"context_line":"                  nullable\u003dTrue))"},{"line_number":32,"context_line":"    op.create_unique_constraint(\u0027uniq_nodes0name\u0027, \u0027nodes\u0027, [\u0027name\u0027])"},{"line_number":33,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_dc425167","line":30,"in_reply_to":"da86d52c_c05ef711","updated":"2015-02-04 04:56:16.000000000","message":"Thanks Adam for raising this.  \n\nIf you look at patch() in ironic/api/controllers/v1/node.py you\u0027ll see we check for is_hostname_safe() which validates the length constraints already.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"}],"ironic/db/sqlalchemy/api.py":[{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"fe1025ded6f5345a7dcc81b5a183432b7096a8e6","unresolved":false,"context_lines":[{"line_number":288,"context_line":"    def get_node_by_name(self, node_name):"},{"line_number":289,"context_line":"        query \u003d model_query(models.Node).filter_by(name\u003dnode_name)"},{"line_number":290,"context_line":"        try:"},{"line_number":291,"context_line":"            return query.one()"},{"line_number":292,"context_line":"        except NoResultFound:"},{"line_number":293,"context_line":"            raise exception.NodeNotFound(node\u003dnode_name)"},{"line_number":294,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_5abc0607","line":291,"updated":"2014-12-29 13:23:40.000000000","message":"IIUC, this can raise sqlalchemy.orm.exc.MultipleResultsFound if multiple nodes with this name found, but seems that you dont restrict creation of such nodes. Maybe return first instead?","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"6b19afe30392a1ce5f9a0a4616398e40e1567542","unresolved":false,"context_lines":[{"line_number":288,"context_line":"    def get_node_by_name(self, node_name):"},{"line_number":289,"context_line":"        query \u003d model_query(models.Node).filter_by(name\u003dnode_name)"},{"line_number":290,"context_line":"        try:"},{"line_number":291,"context_line":"            return query.one()"},{"line_number":292,"context_line":"        except NoResultFound:"},{"line_number":293,"context_line":"            raise exception.NodeNotFound(node\u003dnode_name)"},{"line_number":294,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a930d6b_c0f58ccc","line":291,"in_reply_to":"3a961159_469dbd65","updated":"2015-01-23 04:33:33.000000000","message":"So I think this is fine as is, we enforce uniqueness on update, so this will only return one result unless things have gone wrong.  And iof they do, I think raising an exception is the right thing to do.","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f179cfc3c447dc601dab9dd30e88d6c2043b0795","unresolved":false,"context_lines":[{"line_number":288,"context_line":"    def get_node_by_name(self, node_name):"},{"line_number":289,"context_line":"        query \u003d model_query(models.Node).filter_by(name\u003dnode_name)"},{"line_number":290,"context_line":"        try:"},{"line_number":291,"context_line":"            return query.one()"},{"line_number":292,"context_line":"        except NoResultFound:"},{"line_number":293,"context_line":"            raise exception.NodeNotFound(node\u003dnode_name)"},{"line_number":294,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_469dbd65","line":291,"in_reply_to":"3a961159_5abc0607","updated":"2015-01-14 13:21:16.000000000","message":"We must enforce uniqueness somehow, not hide an exception","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":1420,"name":"Adam Gandelman","email":"adamg@ubuntu.com","username":"gandelman-a"},"change_message_id":"bc581c7347cf4f1bbe61753d6e96b82d6cc2e410","unresolved":false,"context_lines":[{"line_number":341,"context_line":"        except db_exc.DBDuplicateEntry:"},{"line_number":342,"context_line":"            if \u0027name\u0027 in values:"},{"line_number":343,"context_line":"                raise exception.DuplicateName(name\u003dvalues[\u0027name\u0027])"},{"line_number":344,"context_line":"            else:"},{"line_number":345,"context_line":"                raise exception.InstanceAssociated("},{"line_number":346,"context_line":"                    instance_uuid\u003dvalues[\u0027instance_uuid\u0027],"},{"line_number":347,"context_line":"                    node\u003dnode_id)"}],"source_content_type":"text/x-python","patch_set":15,"id":"da86d52c_4a3f61d6","line":344,"updated":"2015-02-04 09:44:38.000000000","message":"We need to replicate this logic in create_node()","commit_id":"97b523df00e24dab8358006cd6e08d30092718c8"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"808f4d4ecafa717f193876feaa87504e88494aa0","unresolved":false,"context_lines":[{"line_number":341,"context_line":"        except db_exc.DBDuplicateEntry:"},{"line_number":342,"context_line":"            if \u0027name\u0027 in values:"},{"line_number":343,"context_line":"                raise exception.DuplicateName(name\u003dvalues[\u0027name\u0027])"},{"line_number":344,"context_line":"            else:"},{"line_number":345,"context_line":"                raise exception.InstanceAssociated("},{"line_number":346,"context_line":"                    instance_uuid\u003dvalues[\u0027instance_uuid\u0027],"},{"line_number":347,"context_line":"                    node\u003dnode_id)"}],"source_content_type":"text/x-python","patch_set":15,"id":"da86d52c_9b18cd1f","line":344,"in_reply_to":"da86d52c_4a3f61d6","updated":"2015-02-04 10:59:08.000000000","message":"Thanks Adam - good pick up!  Will add. Mea culpa.","commit_id":"97b523df00e24dab8358006cd6e08d30092718c8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"d084db2dd6e7928a1c7052c250f57b12d7802559","unresolved":false,"context_lines":[{"line_number":341,"context_line":"        try:"},{"line_number":342,"context_line":"            return self._do_update_node(node_id, values)"},{"line_number":343,"context_line":"        except db_exc.DBDuplicateEntry:"},{"line_number":344,"context_line":"            if \u0027name\u0027 in values:"},{"line_number":345,"context_line":"                raise exception.DuplicateName(name\u003dvalues[\u0027name\u0027])"},{"line_number":346,"context_line":"            else:"},{"line_number":347,"context_line":"                raise exception.InstanceAssociated("}],"source_content_type":"text/x-python","patch_set":18,"id":"da86d52c_cd57b424","line":344,"updated":"2015-02-05 13:29:39.000000000","message":"This might raise the wrong exception here.\n\nIt\u0027s possible to update multiple parts of the node at once, say someone updates instance_uuid and name, then the instance_uuid conflicts and raise DBDubplicateEntry, the name was fine but this code is going to raise DuplicateName() exception.\n\nI think that the right way to validade this, is to look at the exception object and check the columns that was affected.\n\nlike:\n\n except db_exc.DBDuplicateEntry as exc:\n     if \u0027name\u0027 in exc.columns:\n         raise DuplicateName\n     else:\n         ...","commit_id":"be3788edae5b09dafbee96acdf6b72f97d5a9e62"}],"ironic/db/sqlalchemy/models.py":[{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"4a0bdf748aca0952e16760572f48fa8a9233d817","unresolved":false,"context_lines":[{"line_number":145,"context_line":"    __table_args__ \u003d ("},{"line_number":146,"context_line":"        schema.UniqueConstraint(\u0027uuid\u0027, name\u003d\u0027uniq_nodes0uuid\u0027),"},{"line_number":147,"context_line":"        schema.UniqueConstraint(\u0027instance_uuid\u0027,"},{"line_number":148,"context_line":"                                name\u003d\u0027uniq_nodes0instance_uuid\u0027),"},{"line_number":149,"context_line":"        table_args())"},{"line_number":150,"context_line":"    id \u003d Column(Integer, primary_key\u003dTrue)"},{"line_number":151,"context_line":"    uuid \u003d Column(String(36))"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_f1498960","line":148,"updated":"2014-12-15 13:49:45.000000000","message":"AFAIK logical names should be unique. UniqueConstraint(\u0027name\u0027, name\u003d\u0027uniq_nodes0name\u0027) should be here and added to migration.","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"0445f3f40d0b24c8da0aa18eb7a7ec68633004e7","unresolved":false,"context_lines":[{"line_number":145,"context_line":"    __table_args__ \u003d ("},{"line_number":146,"context_line":"        schema.UniqueConstraint(\u0027uuid\u0027, name\u003d\u0027uniq_nodes0uuid\u0027),"},{"line_number":147,"context_line":"        schema.UniqueConstraint(\u0027instance_uuid\u0027,"},{"line_number":148,"context_line":"                                name\u003d\u0027uniq_nodes0instance_uuid\u0027),"},{"line_number":149,"context_line":"        table_args())"},{"line_number":150,"context_line":"    id \u003d Column(Integer, primary_key\u003dTrue)"},{"line_number":151,"context_line":"    uuid \u003d Column(String(36))"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_82af037d","line":148,"in_reply_to":"3a961159_f1498960","updated":"2014-12-16 00:09:39.000000000","message":"Thanks Yuriy - Done","commit_id":"c6a41c3366fba8e7b95123d2b373af5454d21d03"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"92a1266f3525fba420d3d80c4a505b3038239bdb","unresolved":false,"context_lines":[{"line_number":145,"context_line":"    __table_args__ \u003d ("},{"line_number":146,"context_line":"        schema.UniqueConstraint(\u0027uuid\u0027, name\u003d\u0027uniq_nodes0uuid\u0027),"},{"line_number":147,"context_line":"        schema.UniqueConstraint(\u0027instance_uuid\u0027,"},{"line_number":148,"context_line":"                                name\u003d\u0027uniq_nodes0instance_uuid\u0027),"},{"line_number":149,"context_line":"        table_args())"},{"line_number":150,"context_line":"    id \u003d Column(Integer, primary_key\u003dTrue)"},{"line_number":151,"context_line":"    uuid \u003d Column(String(36))"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_44544421","line":148,"updated":"2014-12-16 06:14:52.000000000","message":"Removed the constraint on the \u0027name\u0027 field  as it\u0027s nullable.  Will handle the constraint in code.","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"bd0a492cfb5baaad6b191adda1cfd259a8e43e02","unresolved":false,"context_lines":[{"line_number":145,"context_line":"    __table_args__ \u003d ("},{"line_number":146,"context_line":"        schema.UniqueConstraint(\u0027uuid\u0027, name\u003d\u0027uniq_nodes0uuid\u0027),"},{"line_number":147,"context_line":"        schema.UniqueConstraint(\u0027instance_uuid\u0027,"},{"line_number":148,"context_line":"                                name\u003d\u0027uniq_nodes0instance_uuid\u0027),"},{"line_number":149,"context_line":"        table_args())"},{"line_number":150,"context_line":"    id \u003d Column(Integer, primary_key\u003dTrue)"},{"line_number":151,"context_line":"    uuid \u003d Column(String(36))"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_2c0e813b","line":148,"in_reply_to":"3a961159_1974259b","updated":"2014-12-29 04:54:22.000000000","message":"Done","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"37f7cd44fd82ad0ba2fc97342a6844e667dd8c4a","unresolved":false,"context_lines":[{"line_number":145,"context_line":"    __table_args__ \u003d ("},{"line_number":146,"context_line":"        schema.UniqueConstraint(\u0027uuid\u0027, name\u003d\u0027uniq_nodes0uuid\u0027),"},{"line_number":147,"context_line":"        schema.UniqueConstraint(\u0027instance_uuid\u0027,"},{"line_number":148,"context_line":"                                name\u003d\u0027uniq_nodes0instance_uuid\u0027),"},{"line_number":149,"context_line":"        table_args())"},{"line_number":150,"context_line":"    id \u003d Column(Integer, primary_key\u003dTrue)"},{"line_number":151,"context_line":"    uuid \u003d Column(String(36))"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_1974259b","line":148,"in_reply_to":"3a961159_44544421","updated":"2014-12-17 17:36:29.000000000","message":"I think it is worth adding a comment about this, just above name (line 155).","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"37f7cd44fd82ad0ba2fc97342a6844e667dd8c4a","unresolved":false,"context_lines":[{"line_number":152,"context_line":"    # NOTE(deva): we store instance_uuid directly on the node so that we can"},{"line_number":153,"context_line":"    #             filter on it more efficiently, even though it is"},{"line_number":154,"context_line":"    #             user-settable, and would otherwise be in node.properties."},{"line_number":155,"context_line":"    name \u003d Column(String(63), nullable\u003dTrue)"},{"line_number":156,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dTrue)"},{"line_number":157,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":158,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_397721a1","line":155,"updated":"2014-12-17 17:36:29.000000000","message":"I\u0027d prefer if you put this after instance_uuid or move it before the NOTE above that pertains to instance_uuid :-)","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"bd0a492cfb5baaad6b191adda1cfd259a8e43e02","unresolved":false,"context_lines":[{"line_number":152,"context_line":"    # NOTE(deva): we store instance_uuid directly on the node so that we can"},{"line_number":153,"context_line":"    #             filter on it more efficiently, even though it is"},{"line_number":154,"context_line":"    #             user-settable, and would otherwise be in node.properties."},{"line_number":155,"context_line":"    name \u003d Column(String(63), nullable\u003dTrue)"},{"line_number":156,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dTrue)"},{"line_number":157,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":158,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_8cff7501","line":155,"in_reply_to":"3a961159_397721a1","updated":"2014-12-29 04:54:22.000000000","message":"Done","commit_id":"1ed50359fe2df1acf34503d7073ce1f1c9b3f46c"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f179cfc3c447dc601dab9dd30e88d6c2043b0795","unresolved":false,"context_lines":[{"line_number":154,"context_line":"    #             user-settable, and would otherwise be in node.properties."},{"line_number":155,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dTrue)"},{"line_number":156,"context_line":"    # NOTE(mrda): name is unique, but also optional, so we don\u0027t place a"},{"line_number":157,"context_line":"    #             database uniqueness constraint on the field"},{"line_number":158,"context_line":"    name \u003d Column(String(63), nullable\u003dTrue)"},{"line_number":159,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":160,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_e6ace9a1","line":157,"updated":"2015-01-14 13:21:16.000000000","message":"IIRC unique plays nicely with NULL. anyway we must enforce it somehow","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"edecef70a3f322f3bea0332aaa1e790d2f3461a2","unresolved":false,"context_lines":[{"line_number":154,"context_line":"    #             user-settable, and would otherwise be in node.properties."},{"line_number":155,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dTrue)"},{"line_number":156,"context_line":"    # NOTE(mrda): name is unique, but also optional, so we don\u0027t place a"},{"line_number":157,"context_line":"    #             database uniqueness constraint on the field"},{"line_number":158,"context_line":"    name \u003d Column(String(63), nullable\u003dTrue)"},{"line_number":159,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":160,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa81d914_88897628","line":157,"updated":"2015-01-29 23:01:21.000000000","message":"I second Dmitry\u0027s point (sqlite being a possible exception, and we dont support that anyway)","commit_id":"f45b62e37ce7d2ccd0e9b51d501f5b05fe0ce2e2"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f12ed7a2a407a7ad4ae61042b04ac26203a7bcaf","unresolved":false,"context_lines":[{"line_number":154,"context_line":"    #             user-settable, and would otherwise be in node.properties."},{"line_number":155,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dTrue)"},{"line_number":156,"context_line":"    # NOTE(mrda): name is unique, but also optional, so we don\u0027t place a"},{"line_number":157,"context_line":"    #             database uniqueness constraint on the field"},{"line_number":158,"context_line":"    name \u003d Column(String(63), nullable\u003dTrue)"},{"line_number":159,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":160,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a930d6b_9c7d43b4","line":157,"updated":"2015-01-23 13:42:45.000000000","message":"unique columns allow NULL\u0027s in all databases I\u0027m aware of, please make it unique","commit_id":"f45b62e37ce7d2ccd0e9b51d501f5b05fe0ce2e2"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"db36f17d5c30dacb2c46efce62708abaaf9ce51b","unresolved":false,"context_lines":[{"line_number":154,"context_line":"    #             user-settable, and would otherwise be in node.properties."},{"line_number":155,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dTrue)"},{"line_number":156,"context_line":"    # NOTE(mrda): name is unique, but also optional, so we don\u0027t place a"},{"line_number":157,"context_line":"    #             database uniqueness constraint on the field"},{"line_number":158,"context_line":"    name \u003d Column(String(63), nullable\u003dTrue)"},{"line_number":159,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":160,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_6bad7988","line":157,"in_reply_to":"1a930d6b_9c7d43b4","updated":"2015-02-02 07:09:00.000000000","message":"Done","commit_id":"f45b62e37ce7d2ccd0e9b51d501f5b05fe0ce2e2"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"db36f17d5c30dacb2c46efce62708abaaf9ce51b","unresolved":false,"context_lines":[{"line_number":154,"context_line":"    #             user-settable, and would otherwise be in node.properties."},{"line_number":155,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dTrue)"},{"line_number":156,"context_line":"    # NOTE(mrda): name is unique, but also optional, so we don\u0027t place a"},{"line_number":157,"context_line":"    #             database uniqueness constraint on the field"},{"line_number":158,"context_line":"    name \u003d Column(String(63), nullable\u003dTrue)"},{"line_number":159,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":160,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_8baaad6e","line":157,"in_reply_to":"fa81d914_88897628","updated":"2015-02-02 07:09:00.000000000","message":"Done","commit_id":"f45b62e37ce7d2ccd0e9b51d501f5b05fe0ce2e2"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"338f140e87110a95e334c7de8f53c5ef5a173130","unresolved":false,"context_lines":[{"line_number":156,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dTrue)"},{"line_number":157,"context_line":"    # NOTE(mrda): name is unique, but also optional, so we don\u0027t place a"},{"line_number":158,"context_line":"    #             database uniqueness constraint on the field"},{"line_number":159,"context_line":"    name \u003d Column(String(63), nullable\u003dTrue)"},{"line_number":160,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":161,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":162,"context_line":"    target_power_state \u003d Column(String(15), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":10,"id":"da86d52c_5f84c5d3","line":159,"updated":"2015-02-03 01:13:47.000000000","message":"MySQL doesn\u0027t count two NULL values as non-unique, so maybe we can have unique\u003dTrue? I also see the UniqueConstraint above, perhaps we can just remove this comment?","commit_id":"166f09f14b2b5e8f964e2f1b33234b031719421f"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"1c0ee093aeb11f57a0a5ece52bf504250fe21cfc","unresolved":false,"context_lines":[{"line_number":156,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dTrue)"},{"line_number":157,"context_line":"    # NOTE(mrda): name is unique, but also optional, so we don\u0027t place a"},{"line_number":158,"context_line":"    #             database uniqueness constraint on the field"},{"line_number":159,"context_line":"    name \u003d Column(String(63), nullable\u003dTrue)"},{"line_number":160,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":161,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":162,"context_line":"    target_power_state \u003d Column(String(15), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":10,"id":"da86d52c_33302a9e","line":159,"in_reply_to":"da86d52c_5f84c5d3","updated":"2015-02-03 03:05:06.000000000","message":"Done","commit_id":"166f09f14b2b5e8f964e2f1b33234b031719421f"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":154,"context_line":"    #             filter on it more efficiently, even though it is"},{"line_number":155,"context_line":"    #             user-settable, and would otherwise be in node.properties."},{"line_number":156,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dTrue)"},{"line_number":157,"context_line":"    name \u003d Column(String(63), nullable\u003dTrue)"},{"line_number":158,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":159,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":160,"context_line":"    target_power_state \u003d Column(String(15), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_40b5a7cb","line":157,"updated":"2015-02-03 16:06:18.000000000","message":"just wondering -- how\u0027d you come up with 63?","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"c565f771a93ef6e39a1c0c992b624c8644fe70bc","unresolved":false,"context_lines":[{"line_number":154,"context_line":"    #             filter on it more efficiently, even though it is"},{"line_number":155,"context_line":"    #             user-settable, and would otherwise be in node.properties."},{"line_number":156,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dTrue)"},{"line_number":157,"context_line":"    name \u003d Column(String(63), nullable\u003dTrue)"},{"line_number":158,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":159,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":160,"context_line":"    target_power_state \u003d Column(String(15), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_44df440d","line":157,"in_reply_to":"da86d52c_3f127f57","updated":"2015-02-04 17:45:44.000000000","message":"Thx for explaining. We don\u0027t mention it for the other columns, but for me, it would be useful if there was a docstring about it.\n\nTo be honest, I looked at is_hostname_safe() quickly and didn\u0027t read the references, nor does \u002763\u0027 stick out there. (Ok, I\u0027ll admit, my eyes glaze over when I see a regex.)","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":154,"context_line":"    #             filter on it more efficiently, even though it is"},{"line_number":155,"context_line":"    #             user-settable, and would otherwise be in node.properties."},{"line_number":156,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dTrue)"},{"line_number":157,"context_line":"    name \u003d Column(String(63), nullable\u003dTrue)"},{"line_number":158,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":159,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":160,"context_line":"    target_power_state \u003d Column(String(15), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_3f127f57","line":157,"in_reply_to":"da86d52c_40b5a7cb","updated":"2015-02-04 04:56:16.000000000","message":"Thanks Ruby for the question.\n\nIn is_hostname_safe(), the function we use to verify \u0027name\u0027 is valid, we enforce the 63 character limit and we reference why that number.  Basically it\u0027s the maximum length of the hostname portion of a FQDN.  i.e. hostname.domain.domain.  We want \u0027name\u0027 to potentially be reusable as a hostname, hence the restriction.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"}],"ironic/objects/node.py":[{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"edecef70a3f322f3bea0332aaa1e790d2f3461a2","unresolved":false,"context_lines":[{"line_number":82,"context_line":"    def _from_db_object(node, db_node):"},{"line_number":83,"context_line":"        \"\"\"Converts a database entity to a formal object.\"\"\""},{"line_number":84,"context_line":"        for field in node.fields:"},{"line_number":85,"context_line":"            # Allow for optional fields"},{"line_number":86,"context_line":"            node[field] \u003d db_node.get(field, None)"},{"line_number":87,"context_line":"        node.obj_reset_changes()"},{"line_number":88,"context_line":"        return node"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa81d914_a88c7a36","line":85,"updated":"2015-01-29 23:01:21.000000000","message":"What is this for? We already have some optional / nullable fields -- I don\u0027t understand why this would be necessary.","commit_id":"f45b62e37ce7d2ccd0e9b51d501f5b05fe0ce2e2"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"db36f17d5c30dacb2c46efce62708abaaf9ce51b","unresolved":false,"context_lines":[{"line_number":82,"context_line":"    def _from_db_object(node, db_node):"},{"line_number":83,"context_line":"        \"\"\"Converts a database entity to a formal object.\"\"\""},{"line_number":84,"context_line":"        for field in node.fields:"},{"line_number":85,"context_line":"            # Allow for optional fields"},{"line_number":86,"context_line":"            node[field] \u003d db_node.get(field, None)"},{"line_number":87,"context_line":"        node.obj_reset_changes()"},{"line_number":88,"context_line":"        return node"}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_25957240","line":85,"in_reply_to":"fa81d914_a88c7a36","updated":"2015-02-02 07:09:00.000000000","message":"Removed - this is vestigal code from another approach to deal with optional fields.  Thanks for picking it up.","commit_id":"f45b62e37ce7d2ccd0e9b51d501f5b05fe0ce2e2"}],"ironic/tests/api/v1/test_nodes.py":[{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"38e377bbf4f6c5518113acea1ac9e503aa59d9ab","unresolved":false,"context_lines":[{"line_number":1305,"context_line":"                         expected_location)"},{"line_number":1306,"context_line":""},{"line_number":1307,"context_line":"    def test_power_state_by_name(self):"},{"line_number":1308,"context_line":"        response \u003d self.put_json(\u0027/nodes/%s/states/power\u0027 % self.node[\u0027name\u0027],"},{"line_number":1309,"context_line":"                                 {\u0027target\u0027: states.POWER_ON})"},{"line_number":1310,"context_line":"        self.assertEqual(202, response.status_code)"},{"line_number":1311,"context_line":"        self.assertEqual(\u0027\u0027, response.body)"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_d8f39008","line":1308,"updated":"2015-02-02 12:58:39.000000000","message":"Should it be self.node.name for conformity?","commit_id":"cf6aa1928461404766ee2992075cf65e208c2b46"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"cab5334194b2222e03fadd51f4f57a23e091d924","unresolved":false,"context_lines":[{"line_number":1305,"context_line":"                         expected_location)"},{"line_number":1306,"context_line":""},{"line_number":1307,"context_line":"    def test_power_state_by_name(self):"},{"line_number":1308,"context_line":"        response \u003d self.put_json(\u0027/nodes/%s/states/power\u0027 % self.node[\u0027name\u0027],"},{"line_number":1309,"context_line":"                                 {\u0027target\u0027: states.POWER_ON})"},{"line_number":1310,"context_line":"        self.assertEqual(202, response.status_code)"},{"line_number":1311,"context_line":"        self.assertEqual(\u0027\u0027, response.body)"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_ddb446d3","line":1308,"in_reply_to":"da86d52c_d8f39008","updated":"2015-02-02 21:31:38.000000000","message":"Done","commit_id":"cf6aa1928461404766ee2992075cf65e208c2b46"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"38e377bbf4f6c5518113acea1ac9e503aa59d9ab","unresolved":false,"context_lines":[{"line_number":1310,"context_line":"        self.assertEqual(202, response.status_code)"},{"line_number":1311,"context_line":"        self.assertEqual(\u0027\u0027, response.body)"},{"line_number":1312,"context_line":"        self.mock_cnps.assert_called_once_with(mock.ANY,"},{"line_number":1313,"context_line":"                                               self.node[\u0027uuid\u0027],"},{"line_number":1314,"context_line":"                                               states.POWER_ON,"},{"line_number":1315,"context_line":"                                               \u0027test-topic\u0027)"},{"line_number":1316,"context_line":"        # Check location header"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_38daec78","line":1313,"updated":"2015-02-02 12:58:39.000000000","message":"ditto self.node.uuid","commit_id":"cf6aa1928461404766ee2992075cf65e208c2b46"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"cab5334194b2222e03fadd51f4f57a23e091d924","unresolved":false,"context_lines":[{"line_number":1310,"context_line":"        self.assertEqual(202, response.status_code)"},{"line_number":1311,"context_line":"        self.assertEqual(\u0027\u0027, response.body)"},{"line_number":1312,"context_line":"        self.mock_cnps.assert_called_once_with(mock.ANY,"},{"line_number":1313,"context_line":"                                               self.node[\u0027uuid\u0027],"},{"line_number":1314,"context_line":"                                               states.POWER_ON,"},{"line_number":1315,"context_line":"                                               \u0027test-topic\u0027)"},{"line_number":1316,"context_line":"        # Check location header"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_1dc6de49","line":1313,"in_reply_to":"da86d52c_38daec78","updated":"2015-02-02 21:31:38.000000000","message":"Done","commit_id":"cf6aa1928461404766ee2992075cf65e208c2b46"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"38e377bbf4f6c5518113acea1ac9e503aa59d9ab","unresolved":false,"context_lines":[{"line_number":1460,"context_line":"                             expected_location)"},{"line_number":1461,"context_line":""},{"line_number":1462,"context_line":"    def test_set_console_by_name(self):"},{"line_number":1463,"context_line":"        with mock.patch.object(rpcapi.ConductorAPI,"},{"line_number":1464,"context_line":"                               \u0027set_console_mode\u0027) as mock_scm:"},{"line_number":1465,"context_line":"            ret \u003d self.put_json(\u0027/nodes/%s/states/console\u0027 % self.node.name,"},{"line_number":1466,"context_line":"                                {\u0027enabled\u0027: \"true\"})"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_38c10c81","line":1463,"updated":"2015-02-02 12:58:39.000000000","message":"Better to write it as a decorator.","commit_id":"cf6aa1928461404766ee2992075cf65e208c2b46"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"cab5334194b2222e03fadd51f4f57a23e091d924","unresolved":false,"context_lines":[{"line_number":1460,"context_line":"                             expected_location)"},{"line_number":1461,"context_line":""},{"line_number":1462,"context_line":"    def test_set_console_by_name(self):"},{"line_number":1463,"context_line":"        with mock.patch.object(rpcapi.ConductorAPI,"},{"line_number":1464,"context_line":"                               \u0027set_console_mode\u0027) as mock_scm:"},{"line_number":1465,"context_line":"            ret \u003d self.put_json(\u0027/nodes/%s/states/console\u0027 % self.node.name,"},{"line_number":1466,"context_line":"                                {\u0027enabled\u0027: \"true\"})"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_dd3fe6d4","line":1463,"in_reply_to":"da86d52c_38c10c81","updated":"2015-02-02 21:31:38.000000000","message":"Done","commit_id":"cf6aa1928461404766ee2992075cf65e208c2b46"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":910,"context_line":"    def test_patch_add_name_ok(self):"},{"line_number":911,"context_line":"        self.mock_update_node.return_value \u003d self.node_no_name"},{"line_number":912,"context_line":"        test_name \u003d \u0027guido-van-rossum\u0027"},{"line_number":913,"context_line":"        response \u003d self.patch_json(\u0027/nodes/%s\u0027 % self.node_no_name[\u0027uuid\u0027],"},{"line_number":914,"context_line":"                                   [{\u0027path\u0027: \u0027/name\u0027,"},{"line_number":915,"context_line":"                                     \u0027op\u0027: \u0027add\u0027,"},{"line_number":916,"context_line":"                                     \u0027value\u0027: test_name}])"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_dbdeea10","line":913,"updated":"2015-02-03 16:06:18.000000000","message":"You can use self.node_no_name.uuid\n\nI know, this file uses .node[\u0027uuid\u0027]. i think we were going to slowly convert them, when/if we touch them. But at least for new code, we should go with the \u0027new\u0027 way ;)","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":910,"context_line":"    def test_patch_add_name_ok(self):"},{"line_number":911,"context_line":"        self.mock_update_node.return_value \u003d self.node_no_name"},{"line_number":912,"context_line":"        test_name \u003d \u0027guido-van-rossum\u0027"},{"line_number":913,"context_line":"        response \u003d self.patch_json(\u0027/nodes/%s\u0027 % self.node_no_name[\u0027uuid\u0027],"},{"line_number":914,"context_line":"                                   [{\u0027path\u0027: \u0027/name\u0027,"},{"line_number":915,"context_line":"                                     \u0027op\u0027: \u0027add\u0027,"},{"line_number":916,"context_line":"                                     \u0027value\u0027: test_name}])"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_9feb6b12","line":913,"in_reply_to":"da86d52c_dbdeea10","updated":"2015-02-04 04:56:16.000000000","message":"Ok, I\u0027ll drink the cod liver oil.  I\u0027ll fix a bunch of them.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":949,"context_line":"                                   expect_errors\u003dTrue)"},{"line_number":950,"context_line":"        self.assertEqual(\u0027application/json\u0027, response.content_type)"},{"line_number":951,"context_line":"        self.assertEqual(409, response.status_code)"},{"line_number":952,"context_line":"        self.assertTrue(response.json[\u0027error_message\u0027])"},{"line_number":953,"context_line":""},{"line_number":954,"context_line":""},{"line_number":955,"context_line":"class TestPost(test_api_base.FunctionalTest):"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_9bbab108","line":952,"updated":"2015-02-03 16:06:18.000000000","message":"Maybe I missed it and I\u0027m not sure if it goes here, but what about testing for:\n\n1. creating a new node that has the same name as for an existing node\n2. updating a node\u0027s name with a new name that is the same as an existing node","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":949,"context_line":"                                   expect_errors\u003dTrue)"},{"line_number":950,"context_line":"        self.assertEqual(\u0027application/json\u0027, response.content_type)"},{"line_number":951,"context_line":"        self.assertEqual(409, response.status_code)"},{"line_number":952,"context_line":"        self.assertTrue(response.json[\u0027error_message\u0027])"},{"line_number":953,"context_line":""},{"line_number":954,"context_line":""},{"line_number":955,"context_line":"class TestPost(test_api_base.FunctionalTest):"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_ff9c675f","line":952,"in_reply_to":"da86d52c_9bbab108","updated":"2015-02-04 04:56:16.000000000","message":"Great Idea Ruby - shall add a test.  I don\u0027t have a great way to test this unfortunately, but I\u0027ll add in something that will at least define the expected behaviour - the problem is that we are relying upon the database constraint on the other side of the conductor RPC call, which is hard to mock and still be useful.  Other opinions welcomed on how to do this best.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"c565f771a93ef6e39a1c0c992b624c8644fe70bc","unresolved":false,"context_lines":[{"line_number":949,"context_line":"                                   expect_errors\u003dTrue)"},{"line_number":950,"context_line":"        self.assertEqual(\u0027application/json\u0027, response.content_type)"},{"line_number":951,"context_line":"        self.assertEqual(409, response.status_code)"},{"line_number":952,"context_line":"        self.assertTrue(response.json[\u0027error_message\u0027])"},{"line_number":953,"context_line":""},{"line_number":954,"context_line":""},{"line_number":955,"context_line":"class TestPost(test_api_base.FunctionalTest):"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_ef7571cb","line":952,"in_reply_to":"da86d52c_ff9c675f","updated":"2015-02-04 17:45:44.000000000","message":"I think adding some tests to db/tests_nodes.py would be good too.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":1646,"context_line":"        self.assertEqual(reason, self.node.maintenance_reason)"},{"line_number":1647,"context_line":"        mock_get.assert_called_once_with(mock.ANY, self.node.name)"},{"line_number":1648,"context_line":"        mock_update.assert_called_once_with(mock.ANY, mock.ANY,"},{"line_number":1649,"context_line":"                                            topic\u003d\u0027test-topic\u0027)"},{"line_number":1650,"context_line":""},{"line_number":1651,"context_line":"    @mock.patch.object(objects.Node, \u0027get_by_uuid\u0027)"},{"line_number":1652,"context_line":"    @mock.patch.object(rpcapi.ConductorAPI, \u0027update_node\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_fb356ef7","line":1649,"updated":"2015-02-03 16:06:18.000000000","message":"just thinking. You can get rid of this test by generalizing the one above it -- by adding a (eg) \u0027node_ident\u0027 or \u0027node_ident\u003dNone\u0027 parameter, and used that value (or self.node.uuid if it wasn\u0027t specified).","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":1646,"context_line":"        self.assertEqual(reason, self.node.maintenance_reason)"},{"line_number":1647,"context_line":"        mock_get.assert_called_once_with(mock.ANY, self.node.name)"},{"line_number":1648,"context_line":"        mock_update.assert_called_once_with(mock.ANY, mock.ANY,"},{"line_number":1649,"context_line":"                                            topic\u003d\u0027test-topic\u0027)"},{"line_number":1650,"context_line":""},{"line_number":1651,"context_line":"    @mock.patch.object(objects.Node, \u0027get_by_uuid\u0027)"},{"line_number":1652,"context_line":"    @mock.patch.object(rpcapi.ConductorAPI, \u0027update_node\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_3b97ea49","line":1649,"in_reply_to":"da86d52c_fb356ef7","updated":"2015-02-04 04:56:16.000000000","message":"Thanks Ruby - done.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5ab649ef2298b38920f12640eba1baa7a112e13e","unresolved":false,"context_lines":[{"line_number":177,"context_line":"                headers\u003d{api_base.Version.string: \"1.0\"})"},{"line_number":178,"context_line":"        self.assertNotIn(\u0027driver_internal_info\u0027, data)"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"        data \u003d self.get_json(\u0027/nodes/%s\u0027 % node[\u0027uuid\u0027],"},{"line_number":181,"context_line":"                headers\u003d{api_base.Version.string: \"1.2\"})"},{"line_number":182,"context_line":"        self.assertEqual({\"foo\": \"bar\"}, data[\u0027driver_internal_info\u0027])"},{"line_number":183,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_84421c66","line":180,"updated":"2015-02-04 17:45:28.000000000","message":"if you feel like it, you could change these node[\u0027uuid\u0027]s too.","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"5a3129c111d4230e6a675c327e218dd67766a935","unresolved":false,"context_lines":[{"line_number":177,"context_line":"                headers\u003d{api_base.Version.string: \"1.0\"})"},{"line_number":178,"context_line":"        self.assertNotIn(\u0027driver_internal_info\u0027, data)"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"        data \u003d self.get_json(\u0027/nodes/%s\u0027 % node[\u0027uuid\u0027],"},{"line_number":181,"context_line":"                headers\u003d{api_base.Version.string: \"1.2\"})"},{"line_number":182,"context_line":"        self.assertEqual({\"foo\": \"bar\"}, data[\u0027driver_internal_info\u0027])"},{"line_number":183,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_a8b1aa90","line":180,"in_reply_to":"da86d52c_84421c66","updated":"2015-02-04 21:56:18.000000000","message":"Done","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5ab649ef2298b38920f12640eba1baa7a112e13e","unresolved":false,"context_lines":[{"line_number":989,"context_line":"                                    expect_errors\u003dTrue)"},{"line_number":990,"context_line":"        self.assertEqual(\u0027application/json\u0027, response2.content_type)"},{"line_number":991,"context_line":"        self.assertEqual(409, response2.status_code)"},{"line_number":992,"context_line":"        self.assertTrue(response2.json[\u0027error_message\u0027])"},{"line_number":993,"context_line":""},{"line_number":994,"context_line":""},{"line_number":995,"context_line":"class TestPost(test_api_base.FunctionalTest):"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_04a8ec1e","line":992,"updated":"2015-02-04 17:45:28.000000000","message":"Yeah, I guess in this file, the only thing that can be reasonably tested is the handling of a DuplicateName exception.\n\nI think that it can be made more succinct w/o the node1/response1 part; just set the mock_update_node.side_effect stuff and issue the request...","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"5a3129c111d4230e6a675c327e218dd67766a935","unresolved":false,"context_lines":[{"line_number":989,"context_line":"                                    expect_errors\u003dTrue)"},{"line_number":990,"context_line":"        self.assertEqual(\u0027application/json\u0027, response2.content_type)"},{"line_number":991,"context_line":"        self.assertEqual(409, response2.status_code)"},{"line_number":992,"context_line":"        self.assertTrue(response2.json[\u0027error_message\u0027])"},{"line_number":993,"context_line":""},{"line_number":994,"context_line":""},{"line_number":995,"context_line":"class TestPost(test_api_base.FunctionalTest):"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_a3146d44","line":992,"in_reply_to":"da86d52c_04a8ec1e","updated":"2015-02-04 21:56:18.000000000","message":"Done","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6cc95a2b44b799944313b42ce8983ac69a3bfcf0","unresolved":false,"context_lines":[{"line_number":218,"context_line":"            node_names.append(name)"},{"line_number":219,"context_line":"        data \u003d self.get_json(\u0027/nodes\u0027,"},{"line_number":220,"context_line":"                headers\u003d{api_base.Version.string: \"1.5\"})"},{"line_number":221,"context_line":"        names \u003d [n[\u0027name\u0027] for n in data[\u0027nodes\u0027]]"},{"line_number":222,"context_line":"        self.assertEqual(len(nodes), len(data[\u0027nodes\u0027]))"},{"line_number":223,"context_line":"        self.assertEqual(sorted(node_names), sorted(names))"},{"line_number":224,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"da86d52c_e9561f05","line":221,"updated":"2015-02-05 17:52:16.000000000","message":"nit s/n[\u0027name\u0027]/n.name/","commit_id":"1ed7d5ac75d8f9975bc05e05c3428a96bc395faa"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6cc95a2b44b799944313b42ce8983ac69a3bfcf0","unresolved":false,"context_lines":[{"line_number":616,"context_line":"    def test_validate_by_uuid(self, mock_vdi):"},{"line_number":617,"context_line":"        node \u003d obj_utils.create_test_node(self.context)"},{"line_number":618,"context_line":"        self.get_json(\u0027/nodes/validate?node\u003d%s\u0027 % node.uuid)"},{"line_number":619,"context_line":"        mock_vdi.assert_called_once_with(mock.ANY, node.uuid, \u0027test-topic\u0027)"},{"line_number":620,"context_line":""},{"line_number":621,"context_line":"    @mock.patch.object(rpcapi.ConductorAPI, \u0027validate_driver_interfaces\u0027)"},{"line_number":622,"context_line":"    def test_validate_by_name_unsupported(self, mock_vdi):"}],"source_content_type":"text/x-python","patch_set":22,"id":"da86d52c_e9c9bfac","line":619,"updated":"2015-02-05 17:52:16.000000000","message":"this test needs the microversion header if we decide that \u0027node\u0027 shouldn\u0027t work for v1.0","commit_id":"1ed7d5ac75d8f9975bc05e05c3428a96bc395faa"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6cc95a2b44b799944313b42ce8983ac69a3bfcf0","unresolved":false,"context_lines":[{"line_number":623,"context_line":"        node \u003d obj_utils.create_test_node(self.context, name\u003d\u0027spam\u0027)"},{"line_number":624,"context_line":"        self.get_json(\u0027/nodes/validate?node\u003d%s\u0027 % node.name,"},{"line_number":625,"context_line":"                expect_errors\u003dTrue)"},{"line_number":626,"context_line":"        self.assertFalse(mock_vdi.called)"},{"line_number":627,"context_line":""},{"line_number":628,"context_line":"    @mock.patch.object(rpcapi.ConductorAPI, \u0027validate_driver_interfaces\u0027)"},{"line_number":629,"context_line":"    def test_validate_by_name(self, mock_vdi):"}],"source_content_type":"text/x-python","patch_set":22,"id":"da86d52c_49c2cb85","line":626,"updated":"2015-02-05 17:52:16.000000000","message":"This fails because node.name isn\u0027t supported. Do we want it to fail for that reason or for using \u0027node\u0027 instead of \u0027node_uuid\u0027 in the request? (if \u0027node\u0027 isn\u0027t supported in v1.0)","commit_id":"1ed7d5ac75d8f9975bc05e05c3428a96bc395faa"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6cc95a2b44b799944313b42ce8983ac69a3bfcf0","unresolved":false,"context_lines":[{"line_number":671,"context_line":"        self.mock_update_node.assert_called_once_with("},{"line_number":672,"context_line":"                mock.ANY, mock.ANY, \u0027test-topic\u0027)"},{"line_number":673,"context_line":""},{"line_number":674,"context_line":"    def test_update_ok_by_name_unsupported(self):"},{"line_number":675,"context_line":"        self.mock_update_node.return_value \u003d self.node"},{"line_number":676,"context_line":"        (self"},{"line_number":677,"context_line":"         .mock_update_node"}],"source_content_type":"text/x-python","patch_set":22,"id":"da86d52c_a9926749","line":674,"updated":"2015-02-05 17:52:16.000000000","message":"I\u0027m not sure why this is \u0027ok\u0027 if we expect an error.","commit_id":"1ed7d5ac75d8f9975bc05e05c3428a96bc395faa"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6cc95a2b44b799944313b42ce8983ac69a3bfcf0","unresolved":false,"context_lines":[{"line_number":985,"context_line":"                                     \u0027op\u0027: \u0027add\u0027,"},{"line_number":986,"context_line":"                                     \u0027value\u0027: test_name}])"},{"line_number":987,"context_line":"        self.assertEqual(\u0027application/json\u0027, response.content_type)"},{"line_number":988,"context_line":"        self.assertEqual(200, response.status_code)"},{"line_number":989,"context_line":""},{"line_number":990,"context_line":"    def test_patch_add_name_invalid(self):"},{"line_number":991,"context_line":"        self.mock_update_node.return_value \u003d self.node_no_name"}],"source_content_type":"text/x-python","patch_set":22,"id":"da86d52c_09ea93ab","line":988,"updated":"2015-02-05 17:52:16.000000000","message":"without the microversion header, this should fail.\n\nThe following 4 tests should have headers too.","commit_id":"1ed7d5ac75d8f9975bc05e05c3428a96bc395faa"}],"ironic/tests/api/v1/test_types.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f179cfc3c447dc601dab9dd30e88d6c2043b0795","unresolved":false,"context_lines":[{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def test_valid_name(self):"},{"line_number":58,"context_line":"        test_name \u003d \u0027hal-9000\u0027"},{"line_number":59,"context_line":"        with mock.patch.object(utils, \u0027is_hostname_safe\u0027) as ihs_mock:"},{"line_number":60,"context_line":"            types.NameType.validate(test_name)"},{"line_number":61,"context_line":"            ihs_mock.assert_called_once_with(test_name)"},{"line_number":62,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_4674dd35","line":59,"updated":"2015-01-14 13:21:16.000000000","message":"this is better be done as decorator\n\n @mock.patch.object(utils, \u0027is_hostname_safe\u0027)\n def test_valid_name(self, ihs_mock):","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"6b19afe30392a1ce5f9a0a4616398e40e1567542","unresolved":false,"context_lines":[{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def test_valid_name(self):"},{"line_number":58,"context_line":"        test_name \u003d \u0027hal-9000\u0027"},{"line_number":59,"context_line":"        with mock.patch.object(utils, \u0027is_hostname_safe\u0027) as ihs_mock:"},{"line_number":60,"context_line":"            types.NameType.validate(test_name)"},{"line_number":61,"context_line":"            ihs_mock.assert_called_once_with(test_name)"},{"line_number":62,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a930d6b_a0e6c014","line":59,"in_reply_to":"3a961159_4674dd35","updated":"2015-01-23 04:33:33.000000000","message":"Thanks Dmitry, mea culpa.","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f179cfc3c447dc601dab9dd30e88d6c2043b0795","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    def test_valid_uuid(self):"},{"line_number":71,"context_line":"        test_uuid \u003d \u00271a1a1a1a-2b2b-3c3c-4d4d-5e5e5e5e5e5e\u0027"},{"line_number":72,"context_line":"        with mock.patch.object(utils, \u0027is_uuid_like\u0027) as uuid_mock:"},{"line_number":73,"context_line":"            with mock.patch.object(utils, \u0027is_hostname_safe\u0027) as host_mock:"},{"line_number":74,"context_line":"                host_mock.return_value \u003d False"},{"line_number":75,"context_line":"                self.assertTrue(types.UuidOrNameType.validate(test_uuid))"},{"line_number":76,"context_line":"                uuid_mock.assert_called_once_with(test_uuid)"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_c697ed38","line":73,"updated":"2015-01-14 13:21:16.000000000","message":"ditto about mocking","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"6b19afe30392a1ce5f9a0a4616398e40e1567542","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    def test_valid_uuid(self):"},{"line_number":71,"context_line":"        test_uuid \u003d \u00271a1a1a1a-2b2b-3c3c-4d4d-5e5e5e5e5e5e\u0027"},{"line_number":72,"context_line":"        with mock.patch.object(utils, \u0027is_uuid_like\u0027) as uuid_mock:"},{"line_number":73,"context_line":"            with mock.patch.object(utils, \u0027is_hostname_safe\u0027) as host_mock:"},{"line_number":74,"context_line":"                host_mock.return_value \u003d False"},{"line_number":75,"context_line":"                self.assertTrue(types.UuidOrNameType.validate(test_uuid))"},{"line_number":76,"context_line":"                uuid_mock.assert_called_once_with(test_uuid)"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a930d6b_20a1f0a9","line":73,"in_reply_to":"3a961159_c697ed38","updated":"2015-01-23 04:33:33.000000000","message":"Done","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f179cfc3c447dc601dab9dd30e88d6c2043b0795","unresolved":false,"context_lines":[{"line_number":78,"context_line":"    def test_valid_name(self):"},{"line_number":79,"context_line":"        test_name \u003d \u0027dc16-database5\u0027"},{"line_number":80,"context_line":"        with mock.patch.object(utils, \u0027is_uuid_like\u0027) as uuid_mock:"},{"line_number":81,"context_line":"            with mock.patch.object(utils, \u0027is_hostname_safe\u0027) as host_mock:"},{"line_number":82,"context_line":"                uuid_mock.return_value \u003d False"},{"line_number":83,"context_line":"                self.assertTrue(types.UuidOrNameType.validate(test_name))"},{"line_number":84,"context_line":"                host_mock.assert_called_once_with(test_name)"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a961159_06a1f594","line":81,"updated":"2015-01-14 13:21:16.000000000","message":"ditto","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"6b19afe30392a1ce5f9a0a4616398e40e1567542","unresolved":false,"context_lines":[{"line_number":78,"context_line":"    def test_valid_name(self):"},{"line_number":79,"context_line":"        test_name \u003d \u0027dc16-database5\u0027"},{"line_number":80,"context_line":"        with mock.patch.object(utils, \u0027is_uuid_like\u0027) as uuid_mock:"},{"line_number":81,"context_line":"            with mock.patch.object(utils, \u0027is_hostname_safe\u0027) as host_mock:"},{"line_number":82,"context_line":"                uuid_mock.return_value \u003d False"},{"line_number":83,"context_line":"                self.assertTrue(types.UuidOrNameType.validate(test_name))"},{"line_number":84,"context_line":"                host_mock.assert_called_once_with(test_name)"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a930d6b_40a6fcc2","line":81,"in_reply_to":"3a961159_06a1f594","updated":"2015-01-23 04:33:33.000000000","message":"Done","commit_id":"ae1ac722aa29ce12c4cfff1112407d0f818ff200"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"286c278e1338a69ccb30336dd106e7b3cdb74725","unresolved":false,"context_lines":[{"line_number":80,"context_line":"    def test_valid_name(self, host_mock, uuid_mock):"},{"line_number":81,"context_line":"        test_name \u003d \u0027dc16-database5\u0027"},{"line_number":82,"context_line":"        uuid_mock.return_value \u003d False"},{"line_number":83,"context_line":"        self.assertTrue(types.UuidOrNameType.validate(test_name))"},{"line_number":84,"context_line":"        host_mock.assert_called_once_with(test_name)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def test_invalid_uuid_or_name(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_f9865e64","line":83,"updated":"2015-02-03 14:23:15.000000000","message":"I don\u0027t think you should mock is_hostname_sage(), otherwise it\u0027s not being tested correctly, if return_value is not set for that mock it\u0027s going to return a mock object and not True or False.\n\nIt\u0027s passing tests because you the mock object returned satisfy the conditional we have:\n\n if utils.is_hostname_sage():\n     ...\n\nBut it\u0027s actually a bit wrong. We should either set a host_mock.return_code \u003d True, or not mock it. \n\n(Same comment apply to the test_valid_uuid() test above)","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":80,"context_line":"    def test_valid_name(self, host_mock, uuid_mock):"},{"line_number":81,"context_line":"        test_name \u003d \u0027dc16-database5\u0027"},{"line_number":82,"context_line":"        uuid_mock.return_value \u003d False"},{"line_number":83,"context_line":"        self.assertTrue(types.UuidOrNameType.validate(test_name))"},{"line_number":84,"context_line":"        host_mock.assert_called_once_with(test_name)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def test_invalid_uuid_or_name(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_dbe40ee3","line":83,"in_reply_to":"da86d52c_f9865e64","updated":"2015-02-04 04:56:16.000000000","message":"Great pickup Lucus - that\u0027ll teach me for copy/pasting existing tests :)  I\u0027ll also update TestUuidType as suggested.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5ab649ef2298b38920f12640eba1baa7a112e13e","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    @mock.patch.object(utils, \u0027is_hostname_safe\u0027)"},{"line_number":56,"context_line":"    def test_valid_name(self, ihs_mock):"},{"line_number":57,"context_line":"        test_name \u003d \u0027hal-9000\u0027"},{"line_number":58,"context_line":"        self.assertEqual(test_name, types.NameType.validate(test_name))"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def test_invalid_name(self):"},{"line_number":61,"context_line":"        self.assertRaises(exception.InvalidName,"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_4fa3ddb1","line":58,"updated":"2015-02-04 17:45:28.000000000","message":"If you mock is_hostname_safe, you probably want to \u0027ihs_mock.return_value \u003d True\u0027, and then check that it was called.","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"5a3129c111d4230e6a675c327e218dd67766a935","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    @mock.patch.object(utils, \u0027is_hostname_safe\u0027)"},{"line_number":56,"context_line":"    def test_valid_name(self, ihs_mock):"},{"line_number":57,"context_line":"        test_name \u003d \u0027hal-9000\u0027"},{"line_number":58,"context_line":"        self.assertEqual(test_name, types.NameType.validate(test_name))"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def test_invalid_name(self):"},{"line_number":61,"context_line":"        self.assertRaises(exception.InvalidName,"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_a342ad3b","line":58,"in_reply_to":"da86d52c_4fa3ddb1","updated":"2015-02-04 21:56:18.000000000","message":"Sorry will remove the mock now as per Lucas\u0027 last suggestion","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5ab649ef2298b38920f12640eba1baa7a112e13e","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        test_name \u003d \u0027dc16-database5\u0027"},{"line_number":79,"context_line":"        uuid_mock.return_value \u003d False"},{"line_number":80,"context_line":"        self.assertTrue(types.UuidOrNameType.validate(test_name))"},{"line_number":81,"context_line":"        host_mock.assert_called_once_with(test_name)"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    def test_invalid_uuid_or_name(self):"},{"line_number":84,"context_line":"        self.assertRaises(exception.InvalidUuidOrName,"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_cf4c2d45","line":81,"updated":"2015-02-04 17:45:28.000000000","message":"I\u0027m not sure you addressed Lucas\u0027 concern. If you want to use host_mock, you should add a \u0027host_mock.return_value\u003dTrue\u0027.","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"5a3129c111d4230e6a675c327e218dd67766a935","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        test_name \u003d \u0027dc16-database5\u0027"},{"line_number":79,"context_line":"        uuid_mock.return_value \u003d False"},{"line_number":80,"context_line":"        self.assertTrue(types.UuidOrNameType.validate(test_name))"},{"line_number":81,"context_line":"        host_mock.assert_called_once_with(test_name)"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    def test_invalid_uuid_or_name(self):"},{"line_number":84,"context_line":"        self.assertRaises(exception.InvalidUuidOrName,"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_837f6965","line":81,"in_reply_to":"da86d52c_cf4c2d45","updated":"2015-02-04 21:56:18.000000000","message":"Thanks, updated","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"}],"ironic/tests/db/test_nodes.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5ab649ef2298b38920f12640eba1baa7a112e13e","unresolved":false,"context_lines":[{"line_number":49,"context_line":"                          utils.create_test_node,"},{"line_number":50,"context_line":"                          uuid\u003dironic_utils.generate_uuid(),"},{"line_number":51,"context_line":"                          instance_uuid\u003dinstance)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def test_get_node_by_id(self):"},{"line_number":54,"context_line":"        node \u003d utils.create_test_node()"},{"line_number":55,"context_line":"        res \u003d self.dbapi.get_node_by_id(node.id)"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_6f9c2110","line":52,"updated":"2015-02-04 17:45:28.000000000","message":"I think this is the test file where we should add tests for node creates/updates with names that already exist.","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"5a3129c111d4230e6a675c327e218dd67766a935","unresolved":false,"context_lines":[{"line_number":49,"context_line":"                          utils.create_test_node,"},{"line_number":50,"context_line":"                          uuid\u003dironic_utils.generate_uuid(),"},{"line_number":51,"context_line":"                          instance_uuid\u003dinstance)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def test_get_node_by_id(self):"},{"line_number":54,"context_line":"        node \u003d utils.create_test_node()"},{"line_number":55,"context_line":"        res \u003d self.dbapi.get_node_by_id(node.id)"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_e31745ec","line":52,"in_reply_to":"da86d52c_6f9c2110","updated":"2015-02-04 21:56:18.000000000","message":"Thanks Ruby - will add","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"}],"ironic/tests/objects/test_node.py":[{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"286c278e1338a69ccb30336dd106e7b3cdb74725","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def test_get_bad_id_and_uuid(self):"},{"line_number":54,"context_line":"        self.assertRaises(exception.InvalidIdentity, objects.Node.get,"},{"line_number":55,"context_line":"                          self.context, \u002712345abc67890\u0027)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def test_save(self):"},{"line_number":58,"context_line":"        uuid \u003d self.fake_node[\u0027uuid\u0027]"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_b9022609","line":55,"updated":"2015-02-03 14:23:15.000000000","message":"Why is this a bad id?\n\nIt\u0027s valid according to \u0027^[a-z0-9]([a-z0-9\\\\-]{0,61}[a-z0-9])?$\u0027 no? Is it because rpc objects only accepts numerical id or uuid? If so I don\u0027t think we should change this test in this patch.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def test_get_bad_id_and_uuid(self):"},{"line_number":54,"context_line":"        self.assertRaises(exception.InvalidIdentity, objects.Node.get,"},{"line_number":55,"context_line":"                          self.context, \u002712345abc67890\u0027)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def test_save(self):"},{"line_number":58,"context_line":"        uuid \u003d self.fake_node[\u0027uuid\u0027]"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_9b1b76c9","line":55,"in_reply_to":"da86d52c_b9022609","updated":"2015-02-04 04:56:16.000000000","message":"Thanks Lucas - that was a unnecessary change made as part of a previous patch revision (when we accepted logical name way down into ironic instead of isolating this patch change at the API).\n\nReverted.  Thanks :)","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5ab649ef2298b38920f12640eba1baa7a112e13e","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def test_get_bad_id_and_uuid(self):"},{"line_number":54,"context_line":"        self.assertRaises(exception.InvalidIdentity, objects.Node.get,"},{"line_number":55,"context_line":"                          self.context, \u0027not-a-uuid\u0027)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def test_save(self):"},{"line_number":58,"context_line":"        uuid \u003d self.fake_node[\u0027uuid\u0027]"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_af38d93d","line":55,"updated":"2015-02-04 17:45:28.000000000","message":"If you changed this to what it had been originally, will it look like you never modified this file?","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"5a3129c111d4230e6a675c327e218dd67766a935","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def test_get_bad_id_and_uuid(self):"},{"line_number":54,"context_line":"        self.assertRaises(exception.InvalidIdentity, objects.Node.get,"},{"line_number":55,"context_line":"                          self.context, \u0027not-a-uuid\u0027)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def test_save(self):"},{"line_number":58,"context_line":"        uuid \u003d self.fake_node[\u0027uuid\u0027]"}],"source_content_type":"text/x-python","patch_set":16,"id":"da86d52c_63b27507","line":55,"in_reply_to":"da86d52c_af38d93d","updated":"2015-02-04 21:56:18.000000000","message":"Done","commit_id":"53c089a7f4818151fd53450fddd86a086d2a8e39"}],"ironic/tests/test_utils.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5b9e93f04f28805fbdf4fed7c607db5f4b80327c","unresolved":false,"context_lines":[{"line_number":357,"context_line":"        self.assertFalse(utils.is_hostname_safe(\u0027s\u0027 * 64))"},{"line_number":358,"context_line":"        self.assertFalse(utils.is_hostname_safe(\u0027\u0027))"},{"line_number":359,"context_line":"        self.assertFalse(utils.is_hostname_safe(None))"},{"line_number":360,"context_line":""},{"line_number":361,"context_line":"    def test_validate_and_normalize_mac(self):"},{"line_number":362,"context_line":"        mac \u003d \u0027AA:BB:CC:DD:EE:FF\u0027"},{"line_number":363,"context_line":"        with mock.patch.object(utils, \u0027is_valid_mac\u0027) as m_mock:"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_bb9cd5c1","line":360,"updated":"2015-02-03 16:06:18.000000000","message":"in your spec, you mention that a UUID will not be a valid logical name, so maybe add that as a test here.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"c565f771a93ef6e39a1c0c992b624c8644fe70bc","unresolved":false,"context_lines":[{"line_number":357,"context_line":"        self.assertFalse(utils.is_hostname_safe(\u0027s\u0027 * 64))"},{"line_number":358,"context_line":"        self.assertFalse(utils.is_hostname_safe(\u0027\u0027))"},{"line_number":359,"context_line":"        self.assertFalse(utils.is_hostname_safe(None))"},{"line_number":360,"context_line":""},{"line_number":361,"context_line":"    def test_validate_and_normalize_mac(self):"},{"line_number":362,"context_line":"        mac \u003d \u0027AA:BB:CC:DD:EE:FF\u0027"},{"line_number":363,"context_line":"        with mock.patch.object(utils, \u0027is_valid_mac\u0027) as m_mock:"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_cf27cd10","line":360,"in_reply_to":"da86d52c_9b72960f","updated":"2015-02-04 17:45:44.000000000","message":"Thx for explaining. When you get a chance, please update the spec to reflect this.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"},{"author":{"_account_id":8125,"name":"Michael Davies","email":"michael@the-davies.net","username":"mrda"},"change_message_id":"78d2c5699cf1cedaa27fb927f2ddc23d8b119fa7","unresolved":false,"context_lines":[{"line_number":357,"context_line":"        self.assertFalse(utils.is_hostname_safe(\u0027s\u0027 * 64))"},{"line_number":358,"context_line":"        self.assertFalse(utils.is_hostname_safe(\u0027\u0027))"},{"line_number":359,"context_line":"        self.assertFalse(utils.is_hostname_safe(None))"},{"line_number":360,"context_line":""},{"line_number":361,"context_line":"    def test_validate_and_normalize_mac(self):"},{"line_number":362,"context_line":"        mac \u003d \u0027AA:BB:CC:DD:EE:FF\u0027"},{"line_number":363,"context_line":"        with mock.patch.object(utils, \u0027is_valid_mac\u0027) as m_mock:"}],"source_content_type":"text/x-python","patch_set":13,"id":"da86d52c_9b72960f","line":360,"in_reply_to":"da86d52c_bb9cd5c1","updated":"2015-02-04 04:56:16.000000000","message":"That\u0027s actually not going to be possible now.\n\nI misunderstood how uuids are defined.  I thought they were hexadecimal, whereas other characters are allowed. hence-this-is-valid is both a valid UUID and logical name.  As a consequence I can\u0027t think of an easy way to distinguish the two.","commit_id":"13724e5919806c1a671e33386982c30b35e3b70a"}]}
