)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"e5b26492b86a8b7d0ab1109be8fe926c6cfbcf65","unresolved":false,"context_lines":[{"line_number":12,"context_line":"RFC 3986 unreserved characters, which is what was decided upon in the"},{"line_number":13,"context_line":"Ironic meeting on 29 June 2015."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"A new API microversion, 1.9, is introduced to handle this change."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Additionally, the performance of the old is_hostname_safe() is"},{"line_number":18,"context_line":"improved in several ways."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"ba3cc151_30750231","line":15,"updated":"2015-07-03 12:23:31.000000000","message":"nit: wrong microversion number","commit_id":"5cecf08f8b63beef1ab10383965304c8a825681e"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"74d33b37a33078fda59c03fd3e5a0fc65c5837d3","unresolved":false,"context_lines":[{"line_number":12,"context_line":"RFC 3986 unreserved characters, which is what was decided upon in the"},{"line_number":13,"context_line":"Ironic meeting on 29 June 2015."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"A new API microversion, 1.9, is introduced to handle this change."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Additionally, the performance of the old is_hostname_safe() is"},{"line_number":18,"context_line":"improved in several ways."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"ba3cc151_332e698c","line":15,"in_reply_to":"ba3cc151_30750231","updated":"2015-07-03 13:53:00.000000000","message":"++\n\n1.10","commit_id":"5cecf08f8b63beef1ab10383965304c8a825681e"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"74d33b37a33078fda59c03fd3e5a0fc65c5837d3","unresolved":false,"context_lines":[{"line_number":17,"context_line":"Additionally, the performance of the old is_hostname_safe() is"},{"line_number":18,"context_line":"improved in several ways."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Fixes-Bug: 1468508 1434376"},{"line_number":21,"context_line":"Change-Id: I77441ae5a00e52b84051672ecab5785dd0b033a5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"ba3cc151_b3835902","line":20,"updated":"2015-07-03 13:53:00.000000000","message":"Fixes-Bug is not a valid flag see[1]\n\n Closes-Bug: #1468508\n Closes-Bug: #1434376\n\nhttps://wiki.openstack.org/wiki/GitCommitMessages#Including_external_references","commit_id":"5cecf08f8b63beef1ab10383965304c8a825681e"}],"ironic/api/controllers/v1/__init__.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"a935604e120171b46a9e11791767dbef06349673","unresolved":false,"context_lines":[{"line_number":63,"context_line":"# v1.6: Add INSPECT* states"},{"line_number":64,"context_line":"# v1.7: Add node.clean_step"},{"line_number":65,"context_line":"# v1.8: Add ability to return a subset of resource fields"},{"line_number":66,"context_line":"# v1.9: Fix validation of logical node names"},{"line_number":67,"context_line":"MAX_VER_STR \u003d \u00271.9\u0027"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_0a62b5ad","line":66,"updated":"2015-06-30 14:52:30.000000000","message":"better something like \"Loose node name validation rules\", \"fix\" is too generic","commit_id":"f798aff2b549a95e2de8d80f1ba80fcd85ef852e"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"fb0c244eda492e906f434a77683aeeb3aeea8b5e","unresolved":false,"context_lines":[{"line_number":63,"context_line":"# v1.6: Add INSPECT* states"},{"line_number":64,"context_line":"# v1.7: Add node.clean_step"},{"line_number":65,"context_line":"# v1.8: Add ability to return a subset of resource fields"},{"line_number":66,"context_line":"# v1.9: Fix validation of logical node names"},{"line_number":67,"context_line":"MAX_VER_STR \u003d \u00271.9\u0027"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_9ed123d0","line":66,"in_reply_to":"ba3cc151_0a62b5ad","updated":"2015-06-30 16:53:28.000000000","message":"maybe something like \u0027logical node names support RFC 3986 unreserved characters\u0027 ?","commit_id":"f798aff2b549a95e2de8d80f1ba80fcd85ef852e"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"247e729c1c627ec64ff62f9960588a874236eaa0","unresolved":false,"context_lines":[{"line_number":63,"context_line":"# v1.6: Add INSPECT* states"},{"line_number":64,"context_line":"# v1.7: Add node.clean_step"},{"line_number":65,"context_line":"# v1.8: Add ability to return a subset of resource fields"},{"line_number":66,"context_line":"# v1.9: Fix validation of logical node names"},{"line_number":67,"context_line":"MAX_VER_STR \u003d \u00271.9\u0027"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_009cc9be","line":66,"in_reply_to":"ba3cc151_9ed123d0","updated":"2015-06-30 18:46:56.000000000","message":"Done","commit_id":"f798aff2b549a95e2de8d80f1ba80fcd85ef852e"}],"ironic/api/controllers/v1/utils.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1497eade020e25a7a31b5401940187e5b7c640b4","unresolved":false,"context_lines":[{"line_number":110,"context_line":""},{"line_number":111,"context_line":"def is_valid_logical_name(name):"},{"line_number":112,"context_line":"    \"\"\"Determine if the provided name is a valid hostname.\"\"\""},{"line_number":113,"context_line":"    if pecan.request.version.minor \u003c 9:"},{"line_number":114,"context_line":"        return utils.is_hostname_safe(name)"},{"line_number":115,"context_line":"    else:"},{"line_number":116,"context_line":"        return utils.is_valid_logical_name(name)"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_4e6d5131","line":113,"updated":"2015-07-06 15:32:08.000000000","message":"s/9/10/","commit_id":"85d3a6e211ec1b02ae8b20b3ee677d0c347d13b6"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"5e173034810f398c0fcf7277a53e64feb72e68a0","unresolved":false,"context_lines":[{"line_number":110,"context_line":""},{"line_number":111,"context_line":"def is_valid_logical_name(name):"},{"line_number":112,"context_line":"    \"\"\"Determine if the provided name is a valid hostname.\"\"\""},{"line_number":113,"context_line":"    if pecan.request.version.minor \u003c 9:"},{"line_number":114,"context_line":"        return utils.is_hostname_safe(name)"},{"line_number":115,"context_line":"    else:"},{"line_number":116,"context_line":"        return utils.is_valid_logical_name(name)"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_f1a524b5","line":113,"in_reply_to":"ba3cc151_4e6d5131","updated":"2015-07-06 15:45:49.000000000","message":"Done","commit_id":"85d3a6e211ec1b02ae8b20b3ee677d0c347d13b6"}],"ironic/common/utils.py":[{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"2ebde87ff84f857d6f26a8a371cd3d39f8d4ccb5","unresolved":false,"context_lines":[{"line_number":203,"context_line":"    :returns: True if valid. False if not."},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"    \"\"\""},{"line_number":206,"context_line":"    if not isinstance(hostname, six.string_types) or len(hostname) \u003e 253:"},{"line_number":207,"context_line":"        return False"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    return _is_hostname_safe_re.match(hostname) is not None"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa32b979_052ade2c","line":206,"updated":"2015-06-19 16:32:56.000000000","message":"Why is it changed to 253? Looking at wiki page trailing dot should be ignored, so length can be 254?","commit_id":"ff2bb7f7caa528008c626adc2876a2efd817ace1"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"ef35fa89873fbc0390d9d79045e443cfea8ff6a3","unresolved":false,"context_lines":[{"line_number":203,"context_line":"    :returns: True if valid. False if not."},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"    \"\"\""},{"line_number":206,"context_line":"    if not isinstance(hostname, six.string_types) or len(hostname) \u003e 253:"},{"line_number":207,"context_line":"        return False"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    return _is_hostname_safe_re.match(hostname) is not None"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa32b979_97f065cb","line":206,"in_reply_to":"fa32b979_052ade2c","updated":"2015-06-19 16:45:47.000000000","message":"The trailing dot (whether explicitly included or not) is counted as an octet, and the maximum length is 254 octets (not characters). The Wikipedia page links this, which helps: http://blogs.msdn.com/b/oldnewthing/archive/2012/04/12/10292868.aspx\n\nClarified in the commit message.","commit_id":"ff2bb7f7caa528008c626adc2876a2efd817ace1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"43442df2e838ad3e186f618462cf5b19febda524","unresolved":false,"context_lines":[{"line_number":177,"context_line":"            re.match(m, address.lower()))"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"_is_hostname_safe_re \u003d re.compile(r\"\"\"^"},{"line_number":181,"context_line":"[a-z0-9]              # start with a number or letter"},{"line_number":182,"context_line":"(?:[a-z0-9\\-]{0,61}   # followed by up to 61 letters/numbers/dashes"},{"line_number":183,"context_line":" [a-z0-9])?           # and end with a letter or number"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa32b979_f81e190b","line":180,"updated":"2015-06-23 13:10:27.000000000","message":"Not 100% true - IIRC python caches compiled regexps, bit it\u0027s still more visible IMO, so +1 to this change","commit_id":"5d989b9ed4c30ba9cbb81d3e679d1c7f29430401"},{"author":{"_account_id":12459,"name":"Stephanie Miller","email":"stephane@alum.mit.edu","username":"cinerama"},"change_message_id":"1f241ded1af88e245833da89306a4650cf04855c","unresolved":false,"context_lines":[{"line_number":177,"context_line":"            re.match(m, address.lower()))"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"_is_hostname_safe_re \u003d re.compile(r\"\"\"^"},{"line_number":181,"context_line":"[a-z0-9]              # start with a number or letter"},{"line_number":182,"context_line":"(?:[a-z0-9\\-]{0,61}   # followed by up to 61 letters/numbers/dashes"},{"line_number":183,"context_line":" [a-z0-9])?           # and end with a letter or number"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa32b979_1e9e6cb8","line":180,"updated":"2015-06-22 19:34:19.000000000","message":"This regexp only seems to get used by is_hostname_safe - should it go into the function definition?","commit_id":"5d989b9ed4c30ba9cbb81d3e679d1c7f29430401"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"0d1402cf35dd33774b07d8c3ff1664311024a2cb","unresolved":false,"context_lines":[{"line_number":177,"context_line":"            re.match(m, address.lower()))"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"_is_hostname_safe_re \u003d re.compile(r\"\"\"^"},{"line_number":181,"context_line":"[a-z0-9]              # start with a number or letter"},{"line_number":182,"context_line":"(?:[a-z0-9\\-]{0,61}   # followed by up to 61 letters/numbers/dashes"},{"line_number":183,"context_line":" [a-z0-9])?           # and end with a letter or number"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa32b979_7eca1851","line":180,"in_reply_to":"fa32b979_1e9e6cb8","updated":"2015-06-22 19:40:08.000000000","message":"No. Defining it here means that the regex gets compiled once, at module load time. Putting it inside the function means that it gets compiled on every call to is_hostname_safe(), which is unnecessary since the regex is invariant over the calls to is_hostname_safe(). Defining it here thus improves performance.","commit_id":"5d989b9ed4c30ba9cbb81d3e679d1c7f29430401"},{"author":{"_account_id":12459,"name":"Stephanie Miller","email":"stephane@alum.mit.edu","username":"cinerama"},"change_message_id":"24e3158e97abb8cb61f6cce9ee400ec83b49129a","unresolved":false,"context_lines":[{"line_number":177,"context_line":"            re.match(m, address.lower()))"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"_is_hostname_safe_re \u003d re.compile(r\"\"\"^"},{"line_number":181,"context_line":"[a-z0-9]              # start with a number or letter"},{"line_number":182,"context_line":"(?:[a-z0-9\\-]{0,61}   # followed by up to 61 letters/numbers/dashes"},{"line_number":183,"context_line":" [a-z0-9])?           # and end with a letter or number"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa32b979_5c3dd9b9","line":180,"in_reply_to":"fa32b979_7eca1851","updated":"2015-06-22 21:25:49.000000000","message":"Ah, right - my mistake.","commit_id":"5d989b9ed4c30ba9cbb81d3e679d1c7f29430401"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"d39b4a60bbd16a408f34acf3c1e937b695090833","unresolved":false,"context_lines":[{"line_number":197,"context_line":"$\"\"\", re.X)"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"def is_hostname_safe(hostname, api_version\u003dNone):"},{"line_number":201,"context_line":"    \"\"\"Determine if the supplied hostname is RFC compliant."},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"    Check that the supplied hostname conforms to:"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa32b979_d8a507a2","line":200,"updated":"2015-06-24 21:13:50.000000000","message":"I don\u0027t like the api stuff being in here; that stuff is only related to v1 API. Maybe move them to api/controllers/v1/utils.py","commit_id":"d6a9b8fb06690955d6e71bd954dfebf46d3142c3"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"476835559d7d3390e68e39a76f58e9d03ec7e1b6","unresolved":false,"context_lines":[{"line_number":221,"context_line":""},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"def is_hostname_safe_compat(hostname):"},{"line_number":224,"context_line":"    \"\"\"Old and broken implementation of is_hostname_safe()."},{"line_number":225,"context_line":""},{"line_number":226,"context_line":"    Retained for compatibility with REST API \u003c 1.9."},{"line_number":227,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"fa32b979_50e53535","line":224,"updated":"2015-06-25 10:37:35.000000000","message":"it\u0027s not broken, it\u0027s incomplete","commit_id":"b888fa17d68cec2a0f9bd722428fd3a27f55879a"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"994ebfa362d3d5d84855ddd8050b8cfdbe163f08","unresolved":false,"context_lines":[{"line_number":221,"context_line":""},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"def is_hostname_safe_compat(hostname):"},{"line_number":224,"context_line":"    \"\"\"Old and broken implementation of is_hostname_safe()."},{"line_number":225,"context_line":""},{"line_number":226,"context_line":"    Retained for compatibility with REST API \u003c 1.9."},{"line_number":227,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"fa32b979_0639b3a3","line":224,"in_reply_to":"fa32b979_50e53535","updated":"2015-06-25 11:18:56.000000000","message":"The original docstring claimed to implement RFCs 952 and 1123. It did not. is_hostname_safe() returned True for strings that were not actually \"safe\" (i.e., valid) hostnames. So I think \"broken\" is a pretty safe word to use here.","commit_id":"b888fa17d68cec2a0f9bd722428fd3a27f55879a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"fb0c244eda492e906f434a77683aeeb3aeea8b5e","unresolved":false,"context_lines":[{"line_number":179,"context_line":""},{"line_number":180,"context_line":"_is_valid_logical_name_re \u003d re.compile(r\u0027^[A-Z0-9-._~]+$\u0027, re.I)"},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"# old and busted is_hostname_safe() regex, retained for backwards compat"},{"line_number":183,"context_line":"_is_hostname_safe_re \u003d re.compile(r\"\"\"^"},{"line_number":184,"context_line":"[a-z0-9]([a-z0-9\\-]{0,61}[a-z0-9])?  # host"},{"line_number":185,"context_line":"(\\.[a-z0-9\\-_]{0,62}[a-z0-9])*       # domain"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_c4aefc97","line":182,"updated":"2015-06-30 16:53:28.000000000","message":"don\u0027t mean to nit here, but I think we can use something else than \u0027busted\u0027. I\u0027m not even sure \u0027old\u0027 is needed but that\u0027s fine.\n\nSo eg \u0027old (and slightly incorrect) is_hostname_safe() regex, ...\u0027","commit_id":"f798aff2b549a95e2de8d80f1ba80fcd85ef852e"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"247e729c1c627ec64ff62f9960588a874236eaa0","unresolved":false,"context_lines":[{"line_number":179,"context_line":""},{"line_number":180,"context_line":"_is_valid_logical_name_re \u003d re.compile(r\u0027^[A-Z0-9-._~]+$\u0027, re.I)"},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"# old and busted is_hostname_safe() regex, retained for backwards compat"},{"line_number":183,"context_line":"_is_hostname_safe_re \u003d re.compile(r\"\"\"^"},{"line_number":184,"context_line":"[a-z0-9]([a-z0-9\\-]{0,61}[a-z0-9])?  # host"},{"line_number":185,"context_line":"(\\.[a-z0-9\\-_]{0,62}[a-z0-9])*       # domain"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_e0f685f8","line":182,"in_reply_to":"ba3cc151_c4aefc97","updated":"2015-06-30 18:46:56.000000000","message":"Done","commit_id":"f798aff2b549a95e2de8d80f1ba80fcd85ef852e"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"a935604e120171b46a9e11791767dbef06349673","unresolved":false,"context_lines":[{"line_number":202,"context_line":""},{"line_number":203,"context_line":""},{"line_number":204,"context_line":"def is_hostname_safe(hostname):"},{"line_number":205,"context_line":"    \"\"\"Old and broken check for valid logical node names."},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    Retained for compatibility with REST API \u003c 1.9."},{"line_number":208,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_aa5869fb","line":205,"updated":"2015-06-30 14:52:30.000000000","message":"nit: s/broken/incorrect/","commit_id":"f798aff2b549a95e2de8d80f1ba80fcd85ef852e"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"247e729c1c627ec64ff62f9960588a874236eaa0","unresolved":false,"context_lines":[{"line_number":202,"context_line":""},{"line_number":203,"context_line":""},{"line_number":204,"context_line":"def is_hostname_safe(hostname):"},{"line_number":205,"context_line":"    \"\"\"Old and broken check for valid logical node names."},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    Retained for compatibility with REST API \u003c 1.9."},{"line_number":208,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_a0d95d85","line":205,"in_reply_to":"ba3cc151_aa5869fb","updated":"2015-06-30 18:46:56.000000000","message":"Done","commit_id":"f798aff2b549a95e2de8d80f1ba80fcd85ef852e"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"fb0c244eda492e906f434a77683aeeb3aeea8b5e","unresolved":false,"context_lines":[{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    Nominally, checks that the supplied hostname conforms to various"},{"line_number":210,"context_line":"    appropriate RFCs, but has several shortcomings and errors that are"},{"line_number":211,"context_line":"    more thoroughly documented in bug #1468508."},{"line_number":212,"context_line":""},{"line_number":213,"context_line":"    :param hostname: The hostname to be validated."},{"line_number":214,"context_line":"    :returns: True if valid. False if not."}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_243568d9","line":211,"updated":"2015-06-30 16:53:28.000000000","message":"Honestly, I\u0027d put back the original description \u0027Check that the supplied hostname conforms to...\u0027\n\nThen add your \u0027Note, there are several shortcomings and errors that are ...\u0027.","commit_id":"f798aff2b549a95e2de8d80f1ba80fcd85ef852e"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"247e729c1c627ec64ff62f9960588a874236eaa0","unresolved":false,"context_lines":[{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    Nominally, checks that the supplied hostname conforms to various"},{"line_number":210,"context_line":"    appropriate RFCs, but has several shortcomings and errors that are"},{"line_number":211,"context_line":"    more thoroughly documented in bug #1468508."},{"line_number":212,"context_line":""},{"line_number":213,"context_line":"    :param hostname: The hostname to be validated."},{"line_number":214,"context_line":"    :returns: True if valid. False if not."}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_60683588","line":211,"in_reply_to":"ba3cc151_243568d9","updated":"2015-06-30 18:46:56.000000000","message":"Done","commit_id":"f798aff2b549a95e2de8d80f1ba80fcd85ef852e"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"59fc48ecfab1b45d7e4b09f052ed3267a9a9ac24","unresolved":false,"context_lines":[{"line_number":210,"context_line":"        * http://en.wikipedia.org/wiki/Hostname"},{"line_number":211,"context_line":"        * http://tools.ietf.org/html/rfc952"},{"line_number":212,"context_line":"        * http://tools.ietf.org/html/rfc1123"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"    In practice, this check has several shortcomings and errors that"},{"line_number":215,"context_line":"    are more thoroughly documented in bug #1468508."},{"line_number":216,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"ba3cc151_63c7d845","line":213,"updated":"2015-06-30 21:19:55.000000000","message":"I would have liked the \u0027Allowing for hostnames, and hostnames + domains.\u0027 but this is fine :)","commit_id":"9b6851fa1db22be8ff75c32100b15e534fa8e2f9"}],"ironic/tests/api/v1/test_nodes.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"fb0c244eda492e906f434a77683aeeb3aeea8b5e","unresolved":false,"context_lines":[{"line_number":1144,"context_line":""},{"line_number":1145,"context_line":"    def test_patch_add_name_invalid(self):"},{"line_number":1146,"context_line":"        self.mock_update_node.return_value \u003d self.node_no_name"},{"line_number":1147,"context_line":"        test_name \u003d \u0027i_am_invalid\u0027"},{"line_number":1148,"context_line":"        response \u003d self.patch_json(\u0027/nodes/%s\u0027 % self.node_no_name.uuid,"},{"line_number":1149,"context_line":"                                   [{\u0027path\u0027: \u0027/name\u0027,"},{"line_number":1150,"context_line":"                                     \u0027op\u0027: \u0027add\u0027,"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_5fb07543","line":1147,"updated":"2015-06-30 16:53:28.000000000","message":"I was wondering why you changed this.","commit_id":"f798aff2b549a95e2de8d80f1ba80fcd85ef852e"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"247e729c1c627ec64ff62f9960588a874236eaa0","unresolved":false,"context_lines":[{"line_number":1144,"context_line":""},{"line_number":1145,"context_line":"    def test_patch_add_name_invalid(self):"},{"line_number":1146,"context_line":"        self.mock_update_node.return_value \u003d self.node_no_name"},{"line_number":1147,"context_line":"        test_name \u003d \u0027i_am_invalid\u0027"},{"line_number":1148,"context_line":"        response \u003d self.patch_json(\u0027/nodes/%s\u0027 % self.node_no_name.uuid,"},{"line_number":1149,"context_line":"                                   [{\u0027path\u0027: \u0027/name\u0027,"},{"line_number":1150,"context_line":"                                     \u0027op\u0027: \u0027add\u0027,"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_a01cfd13","line":1147,"in_reply_to":"ba3cc151_5fb07543","updated":"2015-06-30 18:46:56.000000000","message":"Cruft from an older version of this change. I\u0027ve changed it to something that\u0027s actually invalid, and updated the microversion for this test to 1.9.","commit_id":"f798aff2b549a95e2de8d80f1ba80fcd85ef852e"},{"author":{"_account_id":8106,"name":"Haomeng,Wang","email":"wanghaomeng@gmail.com","username":"whaom"},"change_message_id":"04e7bc298ec742caf386759032d086d835236c92","unresolved":false,"context_lines":[{"line_number":1179,"context_line":""},{"line_number":1180,"context_line":"    def test_patch_add_name_invalid(self):"},{"line_number":1181,"context_line":"        self.mock_update_node.return_value \u003d self.node_no_name"},{"line_number":1182,"context_line":"        test_name \u003d \u0027i am invalid\u0027"},{"line_number":1183,"context_line":"        response \u003d self.patch_json(\u0027/nodes/%s\u0027 % self.node_no_name.uuid,"},{"line_number":1184,"context_line":"                                   [{\u0027path\u0027: \u0027/name\u0027,"},{"line_number":1185,"context_line":"                                     \u0027op\u0027: \u0027add\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"ba3cc151_2d15c19a","line":1182,"updated":"2015-07-03 03:01:41.000000000","message":"nit: is this necessary?","commit_id":"5cecf08f8b63beef1ab10383965304c8a825681e"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"74d33b37a33078fda59c03fd3e5a0fc65c5837d3","unresolved":false,"context_lines":[{"line_number":1179,"context_line":""},{"line_number":1180,"context_line":"    def test_patch_add_name_invalid(self):"},{"line_number":1181,"context_line":"        self.mock_update_node.return_value \u003d self.node_no_name"},{"line_number":1182,"context_line":"        test_name \u003d \u0027i am invalid\u0027"},{"line_number":1183,"context_line":"        response \u003d self.patch_json(\u0027/nodes/%s\u0027 % self.node_no_name.uuid,"},{"line_number":1184,"context_line":"                                   [{\u0027path\u0027: \u0027/name\u0027,"},{"line_number":1185,"context_line":"                                     \u0027op\u0027: \u0027add\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"ba3cc151_b3103901","line":1182,"in_reply_to":"ba3cc151_2d15c19a","updated":"2015-07-03 13:53:00.000000000","message":"seems so, because \"I-AM-INVALID\" is now a valid name (ALPHA + \u0027-\u0027)","commit_id":"5cecf08f8b63beef1ab10383965304c8a825681e"}],"ironic/tests/api/v1/test_types.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1497eade020e25a7a31b5401940187e5b7c640b4","unresolved":false,"context_lines":[{"line_number":55,"context_line":""},{"line_number":56,"context_line":"    @mock.patch(\"pecan.request\")"},{"line_number":57,"context_line":"    def test_valid_name(self, mock_pecan_req):"},{"line_number":58,"context_line":"        mock_pecan_req.version.minor \u003d 9"},{"line_number":59,"context_line":"        test_name \u003d \u0027hal-9000\u0027"},{"line_number":60,"context_line":"        self.assertEqual(test_name, types.NameType.validate(test_name))"},{"line_number":61,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_0ec4293e","line":58,"updated":"2015-07-06 15:32:08.000000000","message":"I think we should change this to 10.\n\nThe test passes (cuz it just needs minor to be \u003e\u003d 5 I think), but I think it might be confusing not to have 5 or 10 here.\n\nAnd change the other lines that are similar to this.","commit_id":"85d3a6e211ec1b02ae8b20b3ee677d0c347d13b6"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"5e173034810f398c0fcf7277a53e64feb72e68a0","unresolved":false,"context_lines":[{"line_number":55,"context_line":""},{"line_number":56,"context_line":"    @mock.patch(\"pecan.request\")"},{"line_number":57,"context_line":"    def test_valid_name(self, mock_pecan_req):"},{"line_number":58,"context_line":"        mock_pecan_req.version.minor \u003d 9"},{"line_number":59,"context_line":"        test_name \u003d \u0027hal-9000\u0027"},{"line_number":60,"context_line":"        self.assertEqual(test_name, types.NameType.validate(test_name))"},{"line_number":61,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_11c8c873","line":58,"in_reply_to":"ba3cc151_0ec4293e","updated":"2015-07-06 15:45:49.000000000","message":"Done","commit_id":"85d3a6e211ec1b02ae8b20b3ee677d0c347d13b6"}],"ironic/tests/api/v1/test_utils.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"fb0c244eda492e906f434a77683aeeb3aeea8b5e","unresolved":false,"context_lines":[{"line_number":101,"context_line":"        self.assertTrue(utils.is_valid_node_name(self.valid_name))"},{"line_number":102,"context_line":"        self.assertFalse(utils.is_valid_node_name(self.invalid_name))"},{"line_number":103,"context_line":"        self.assertFalse(utils.is_valid_node_name(self.valid_uuid))"},{"line_number":104,"context_line":"        self.assertFalse(utils.is_valid_node_name(self.invalid_uuid))"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    @mock.patch.object(pecan, \u0027request\u0027)"},{"line_number":107,"context_line":"    @mock.patch.object(utils, \u0027allow_node_logical_names\u0027)"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_5f4cf541","side":"PARENT","line":104,"updated":"2015-06-30 16:53:28.000000000","message":"self.invalid_uuid isn\u0027t used any more.\n\nIs it worth replacing this with self.assertTrue()? (Or delete invalid_uuid)","commit_id":"ea09be56050c33c2843fa8568953b7883d328179"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"247e729c1c627ec64ff62f9960588a874236eaa0","unresolved":false,"context_lines":[{"line_number":101,"context_line":"        self.assertTrue(utils.is_valid_node_name(self.valid_name))"},{"line_number":102,"context_line":"        self.assertFalse(utils.is_valid_node_name(self.invalid_name))"},{"line_number":103,"context_line":"        self.assertFalse(utils.is_valid_node_name(self.valid_uuid))"},{"line_number":104,"context_line":"        self.assertFalse(utils.is_valid_node_name(self.invalid_uuid))"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    @mock.patch.object(pecan, \u0027request\u0027)"},{"line_number":107,"context_line":"    @mock.patch.object(utils, \u0027allow_node_logical_names\u0027)"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba3cc151_c0ab4188","side":"PARENT","line":104,"in_reply_to":"ba3cc151_5f4cf541","updated":"2015-06-30 18:46:56.000000000","message":"Done","commit_id":"ea09be56050c33c2843fa8568953b7883d328179"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1497eade020e25a7a31b5401940187e5b7c640b4","unresolved":false,"context_lines":[{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    @mock.patch(\"pecan.request\")"},{"line_number":100,"context_line":"    def test_is_valid_node_name(self, mock_pecan_req):"},{"line_number":101,"context_line":"        mock_pecan_req.version.minor \u003d 9"},{"line_number":102,"context_line":"        self.assertTrue(utils.is_valid_node_name(self.valid_name))"},{"line_number":103,"context_line":"        self.assertFalse(utils.is_valid_node_name(self.invalid_name))"},{"line_number":104,"context_line":"        self.assertFalse(utils.is_valid_node_name(self.valid_uuid))"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_4ee79112","line":101,"updated":"2015-07-06 15:32:08.000000000","message":"I think we should change this to 10.\n\nThe test passes (cuz it just needs minor to be \u003e\u003d 5 I think), but I think it might be confusing not to have 5 or 10 here.","commit_id":"85d3a6e211ec1b02ae8b20b3ee677d0c347d13b6"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"5e173034810f398c0fcf7277a53e64feb72e68a0","unresolved":false,"context_lines":[{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    @mock.patch(\"pecan.request\")"},{"line_number":100,"context_line":"    def test_is_valid_node_name(self, mock_pecan_req):"},{"line_number":101,"context_line":"        mock_pecan_req.version.minor \u003d 9"},{"line_number":102,"context_line":"        self.assertTrue(utils.is_valid_node_name(self.valid_name))"},{"line_number":103,"context_line":"        self.assertFalse(utils.is_valid_node_name(self.invalid_name))"},{"line_number":104,"context_line":"        self.assertFalse(utils.is_valid_node_name(self.valid_uuid))"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_d187c010","line":101,"in_reply_to":"ba3cc151_4ee79112","updated":"2015-07-06 15:45:49.000000000","message":"Done","commit_id":"85d3a6e211ec1b02ae8b20b3ee677d0c347d13b6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1497eade020e25a7a31b5401940187e5b7c640b4","unresolved":false,"context_lines":[{"line_number":122,"context_line":"    @mock.patch.object(objects.Node, \u0027get_by_name\u0027)"},{"line_number":123,"context_line":"    def test_get_rpc_node_expect_name(self, mock_gbn, mock_gbu, mock_anln,"},{"line_number":124,"context_line":"                                      mock_pr):"},{"line_number":125,"context_line":"        mock_pr.version.minor \u003d 9"},{"line_number":126,"context_line":"        mock_anln.return_value \u003d True"},{"line_number":127,"context_line":"        self.node[\u0027name\u0027] \u003d self.valid_name"},{"line_number":128,"context_line":"        mock_gbn.return_value \u003d self.node"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_6ee4d50c","line":125,"updated":"2015-07-06 15:32:08.000000000","message":"ditto","commit_id":"85d3a6e211ec1b02ae8b20b3ee677d0c347d13b6"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"5e173034810f398c0fcf7277a53e64feb72e68a0","unresolved":false,"context_lines":[{"line_number":122,"context_line":"    @mock.patch.object(objects.Node, \u0027get_by_name\u0027)"},{"line_number":123,"context_line":"    def test_get_rpc_node_expect_name(self, mock_gbn, mock_gbu, mock_anln,"},{"line_number":124,"context_line":"                                      mock_pr):"},{"line_number":125,"context_line":"        mock_pr.version.minor \u003d 9"},{"line_number":126,"context_line":"        mock_anln.return_value \u003d True"},{"line_number":127,"context_line":"        self.node[\u0027name\u0027] \u003d self.valid_name"},{"line_number":128,"context_line":"        mock_gbn.return_value \u003d self.node"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_f18c4437","line":125,"in_reply_to":"ba3cc151_6ee4d50c","updated":"2015-07-06 15:45:49.000000000","message":"Done","commit_id":"85d3a6e211ec1b02ae8b20b3ee677d0c347d13b6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1497eade020e25a7a31b5401940187e5b7c640b4","unresolved":false,"context_lines":[{"line_number":136,"context_line":"    @mock.patch.object(objects.Node, \u0027get_by_name\u0027)"},{"line_number":137,"context_line":"    def test_get_rpc_node_invalid_name(self, mock_gbn, mock_gbu,"},{"line_number":138,"context_line":"                                       mock_anln, mock_pr):"},{"line_number":139,"context_line":"        mock_pr.version.minor \u003d 9"},{"line_number":140,"context_line":"        mock_anln.return_value \u003d True"},{"line_number":141,"context_line":"        self.assertRaises(exception.InvalidUuidOrName,"},{"line_number":142,"context_line":"                          utils.get_rpc_node,"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_0ef189cd","line":139,"updated":"2015-07-06 15:32:08.000000000","message":"ditto.","commit_id":"85d3a6e211ec1b02ae8b20b3ee677d0c347d13b6"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"5e173034810f398c0fcf7277a53e64feb72e68a0","unresolved":false,"context_lines":[{"line_number":136,"context_line":"    @mock.patch.object(objects.Node, \u0027get_by_name\u0027)"},{"line_number":137,"context_line":"    def test_get_rpc_node_invalid_name(self, mock_gbn, mock_gbu,"},{"line_number":138,"context_line":"                                       mock_anln, mock_pr):"},{"line_number":139,"context_line":"        mock_pr.version.minor \u003d 9"},{"line_number":140,"context_line":"        mock_anln.return_value \u003d True"},{"line_number":141,"context_line":"        self.assertRaises(exception.InvalidUuidOrName,"},{"line_number":142,"context_line":"                          utils.get_rpc_node,"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_7179142f","line":139,"in_reply_to":"ba3cc151_0ef189cd","updated":"2015-07-06 15:45:49.000000000","message":"Done","commit_id":"85d3a6e211ec1b02ae8b20b3ee677d0c347d13b6"}],"ironic/tests/test_utils.py":[{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"d79004707d92502e4fc776e4932e16247da16bfb","unresolved":false,"context_lines":[{"line_number":383,"context_line":"        valid \u003d ("},{"line_number":384,"context_line":"            \u0027spam\u0027, \u0027spAm\u0027, \u0027SPAM\u0027, \u0027spam-eggs\u0027, \u0027spam.eggs\u0027, \u0027spam_eggs\u0027,"},{"line_number":385,"context_line":"            \u0027spam~eggs\u0027, \u00279spam\u0027, \u0027spam7\u0027, \u0027~spam\u0027, \u0027.spam\u0027, \u0027.~-_\u0027, \u0027~\u0027,"},{"line_number":386,"context_line":"            \u0027br34kf4st\u0027, \u0027s\u0027, \u0027s\u0027 * 63, \u0027s\u0027 * 255)"},{"line_number":387,"context_line":"        invalid \u003d ("},{"line_number":388,"context_line":"            \u0027 \u0027, \u0027spam eggs\u0027, \u0027$pam\u0027, \u0027egg$\u0027, \u0027spam#eggs\u0027,"},{"line_number":389,"context_line":"            \u0027 eggs\u0027, \u0027spam \u0027, \u0027\u0027, None, \u0027spam%20\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba3cc151_d159c75b","line":386,"updated":"2015-06-30 23:37:04.000000000","message":"As a note, I really do like this for loop method much better than lines of assert statements.  Thanks!","commit_id":"9b6851fa1db22be8ff75c32100b15e534fa8e2f9"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"48fcbc5eddd2d1d0e701befbf48b7f657884d6e1","unresolved":false,"context_lines":[{"line_number":393,"context_line":"            # Need to ensure a binary response for success. assertTrue"},{"line_number":394,"context_line":"            # is too generous, and would pass this test if, for"},{"line_number":395,"context_line":"            # instance, a regex Match object were returned."},{"line_number":396,"context_line":"            self.assertIs(result, True)"},{"line_number":397,"context_line":""},{"line_number":398,"context_line":"        for hostname in invalid:"},{"line_number":399,"context_line":"            result \u003d utils.is_valid_logical_name(hostname)"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba3cc151_1bd0b01e","line":396,"updated":"2015-06-30 22:23:46.000000000","message":"I think should use the \u0027Annotate\u0027 capability of testtools here.\n\nIf a test fails there won\u0027t be any detail on which one failed.\n\nhttps://testtools.readthedocs.org/en/latest/for-test-authors.html","commit_id":"9b6851fa1db22be8ff75c32100b15e534fa8e2f9"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"27f395525470a3895f908f6b314c55a3f695449e","unresolved":false,"context_lines":[{"line_number":393,"context_line":"            # Need to ensure a binary response for success. assertTrue"},{"line_number":394,"context_line":"            # is too generous, and would pass this test if, for"},{"line_number":395,"context_line":"            # instance, a regex Match object were returned."},{"line_number":396,"context_line":"            self.assertIs(result, True)"},{"line_number":397,"context_line":""},{"line_number":398,"context_line":"        for hostname in invalid:"},{"line_number":399,"context_line":"            result \u003d utils.is_valid_logical_name(hostname)"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba3cc151_33f6e2f9","line":396,"in_reply_to":"ba3cc151_1bd0b01e","updated":"2015-07-01 11:09:15.000000000","message":"+1  The lines of assert statements at least give clarity into where something failed, and understanding what exactly failed is going to key for anyone troubleshooting.","commit_id":"9b6851fa1db22be8ff75c32100b15e534fa8e2f9"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"48fcbc5eddd2d1d0e701befbf48b7f657884d6e1","unresolved":false,"context_lines":[{"line_number":400,"context_line":"            # Need to ensure a binary response for"},{"line_number":401,"context_line":"            # success. assertFalse is too generous and would pass this"},{"line_number":402,"context_line":"            # test if None were returned."},{"line_number":403,"context_line":"            self.assertIs(result, False)"},{"line_number":404,"context_line":""},{"line_number":405,"context_line":"    def test_validate_and_normalize_mac(self):"},{"line_number":406,"context_line":"        mac \u003d \u0027AA:BB:CC:DD:EE:FF\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba3cc151_dbc9e879","line":403,"updated":"2015-06-30 22:23:46.000000000","message":"same as above","commit_id":"9b6851fa1db22be8ff75c32100b15e534fa8e2f9"}]}
