)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"ff5de292b1d8e22f24e8dbb967b45b57a6731c4c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"86d3c3c8_52945f0d","updated":"2024-08-14 19:24:38.000000000","message":"Should we retain the deprecated rules?","commit_id":"7cbfda8ac3fa35efb3bff030892a2492ac1e85d0"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"88628c01240f12e1d5688885b34b5e77fc03d745","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"dfe07f4e_c42c05bb","updated":"2024-08-14 16:23:38.000000000","message":"Testing if setting Workflow -1 marks this change as Work In Progress","commit_id":"7cbfda8ac3fa35efb3bff030892a2492ac1e85d0"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"34906715_45ae3c3a","updated":"2024-09-12 10:36:13.000000000","message":"Great work!","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"ebfa8b0ed3290f0a7ce44ce56b73a8dcff25e5c0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"80a7d95b_2cb48117","updated":"2024-08-30 09:26:04.000000000","message":"recheck (Failure looks unrelated)","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"b84d7ece9027864e310776dcbfc6735c48872d77","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"137e17dd_f95de455","updated":"2024-08-30 09:24:59.000000000","message":"retest (Failure looks unrelated)","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":20,"id":"f7e1cb65_3dbde072","updated":"2024-09-26 15:27:50.000000000","message":"Great start! Some places are not consistent with the spec + there is a confusion around the scope parameter.","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"1d8a9145c41c69a9df2b09e57fa6549d3e1b12d7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":23,"id":"5c49d8a7_abf987da","updated":"2024-11-06 05:07:37.000000000","message":"Out of steam on this one.","commit_id":"31d01e756c51dad5898bfc0dfc636a44ce96459a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":25,"id":"963b84ff_0e933955","updated":"2024-11-12 13:23:23.000000000","message":"This is shaping really well, thank you!\n\nA new bunch of comments posted. Regretfully, I did not manage to get to the API. Maybe you could split the patch into the core functionality and then the API? This way we could review it faster. Just a suggestion though, not a critical comment.","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":43,"id":"679c1ce2_ca52c08a","updated":"2025-01-08 13:32:17.000000000","message":"Ran out of time again, but more substantial comments now.\n\nI\u0027d probably suggest to land the database part in a separate patch. Since it\u0027s agreed on in the spec, it should not take so many iterations. Then we can work on the engine, then we can finish with the API. This way, you won\u0027t need to update such a large patch (and we won\u0027t need to review it many times).","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":43,"id":"f8448d3c_2ba2f5ef","updated":"2025-01-02 16:28:09.000000000","message":"Ran out of time on my initial review pass. A few assorted comments inline.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"8a744361ff110fbcc2bac89ae01451833381808c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":43,"id":"2ffb679e_13fde7b8","updated":"2025-01-08 15:37:11.000000000","message":"Thanks for the reviews, I will get to addressing these feedback ASAP. But first I will be splitting up this changeset into 3 chained patches, just as you have suggested.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"18343ff5213222355647e510a4460f4183fb1c34","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":46,"id":"ba1fcc73_d075ba8e","updated":"2025-02-18 09:34:25.000000000","message":"Yes, this should be abandoned, I didn\u0027t because I couldn\u0027t.","commit_id":"8c3e4108497c54aee0fc42e4df9f06acf60600de"},{"author":{"_account_id":5890,"name":"Doug Goldstein","email":"cardoe@cardoe.com","username":"cardoe"},"change_message_id":"bdba28e3dda4e5aea554b95566fc191113fd6811","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":46,"id":"d003c89b_511d414d","updated":"2025-02-15 05:15:16.000000000","message":"do you want to abandon this one?","commit_id":"8c3e4108497c54aee0fc42e4df9f06acf60600de"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"6b03c60299be975b8a6424b0c75066a88a87b7e4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":46,"id":"812e4a0a_6d0480cd","in_reply_to":"ba1fcc73_d075ba8e","updated":"2025-02-18 10:08:11.000000000","message":"Oh, I didn\u0027t realize that. Done!","commit_id":"8c3e4108497c54aee0fc42e4df9f06acf60600de"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"f160eb26654fa1cbc64f0070277609ffc0c13dd6","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":46,"id":"9ba88d5f_1027c8fd","in_reply_to":"d003c89b_511d414d","updated":"2025-02-18 09:10:24.000000000","message":"Same question: most likely, yes?","commit_id":"8c3e4108497c54aee0fc42e4df9f06acf60600de"}],"ironic/api/controllers/v1/inspection_rule.py":[{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":48,"context_line":"    \"\"\"Parse path, extract scheme and path."},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"     Parse path with \u0027node\u0027 and \u0027data\u0027 scheme, which links on"},{"line_number":51,"context_line":"     introspection data and node info respectively. If scheme is"},{"line_number":52,"context_line":"     missing in path, default is \u0027data\u0027."},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    :param path: data or node path"}],"source_content_type":"text/x-python","patch_set":15,"id":"267fe269_bddcd781","line":51,"updated":"2024-09-12 10:36:13.000000000","message":"Lets use the term inspection instead of introspection everywhere.","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    \"\"\"Parse path, extract scheme and path."},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"     Parse path with \u0027node\u0027 and \u0027data\u0027 scheme, which links on"},{"line_number":51,"context_line":"     introspection data and node info respectively. If scheme is"},{"line_number":52,"context_line":"     missing in path, default is \u0027data\u0027."},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    :param path: data or node path"}],"source_content_type":"text/x-python","patch_set":15,"id":"2e1dbbf9_4f2cbd75","line":51,"in_reply_to":"267fe269_bddcd781","updated":"2024-09-17 11:41:10.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":71,"context_line":"        condition_plugins \u003d [x.name for x"},{"line_number":72,"context_line":"                             in plugins.rule_conditions_manager()]"},{"line_number":73,"context_line":"        _CONDITIONS_SCHEMA \u003d {"},{"line_number":74,"context_line":"            \"title\": \"Inspector rule conditions schema\","},{"line_number":75,"context_line":"            \"type\": \"array\","},{"line_number":76,"context_line":"            # we can have rules that always apply"},{"line_number":77,"context_line":"            \"minItems\": 0,"}],"source_content_type":"text/x-python","patch_set":15,"id":"ac535517_265f3682","line":74,"updated":"2024-09-12 10:36:13.000000000","message":"Inspection rule conditions schema sounds a bit better","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        condition_plugins \u003d [x.name for x"},{"line_number":72,"context_line":"                             in plugins.rule_conditions_manager()]"},{"line_number":73,"context_line":"        _CONDITIONS_SCHEMA \u003d {"},{"line_number":74,"context_line":"            \"title\": \"Inspector rule conditions schema\","},{"line_number":75,"context_line":"            \"type\": \"array\","},{"line_number":76,"context_line":"            # we can have rules that always apply"},{"line_number":77,"context_line":"            \"minItems\": 0,"}],"source_content_type":"text/x-python","patch_set":15,"id":"778215e9_150c6c43","line":74,"in_reply_to":"ac535517_265f3682","updated":"2024-09-17 11:41:10.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":78,"context_line":"            \"items\": {"},{"line_number":79,"context_line":"                \"type\": \"object\","},{"line_number":80,"context_line":"                # field might become optional in the future, but not right now"},{"line_number":81,"context_line":"                \"required\": [\"op\", \"field\"],"},{"line_number":82,"context_line":"                \"properties\": {"},{"line_number":83,"context_line":"                    \"op\": {"},{"line_number":84,"context_line":"                        \"description\": \"condition operator\","}],"source_content_type":"text/x-python","patch_set":15,"id":"fca57d07_37996e4c","line":81,"updated":"2024-09-12 10:36:13.000000000","message":"Please make this as per the spec: https://specs.openstack.org/openstack/ironic-specs/specs/not-implemented/inspection-rules.html#:~:text\u003dop%20%2D%20operation%3A%20either,)%20with%20arguments.","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"63d2acb354ea3f9812b7ec24baf6de01d8c27da0","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            \"items\": {"},{"line_number":79,"context_line":"                \"type\": \"object\","},{"line_number":80,"context_line":"                # field might become optional in the future, but not right now"},{"line_number":81,"context_line":"                \"required\": [\"op\", \"field\"],"},{"line_number":82,"context_line":"                \"properties\": {"},{"line_number":83,"context_line":"                    \"op\": {"},{"line_number":84,"context_line":"                        \"description\": \"condition operator\","}],"source_content_type":"text/x-python","patch_set":15,"id":"245af983_12aaa7cc","line":81,"in_reply_to":"fca57d07_37996e4c","updated":"2024-09-20 09:44:04.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":88,"context_line":"                        \"description\": \"JSON path to field for matching\","},{"line_number":89,"context_line":"                        \"type\": \"string\""},{"line_number":90,"context_line":"                    },"},{"line_number":91,"context_line":"                    \"multiple\": {"},{"line_number":92,"context_line":"                        \"description\": \"how to treat multiple values\","},{"line_number":93,"context_line":"                        \"enum\": [\"all\", \"any\", \"first\"]"},{"line_number":94,"context_line":"                    },"}],"source_content_type":"text/x-python","patch_set":15,"id":"f9ae5b50_2bf52be5","line":91,"updated":"2024-09-12 10:36:13.000000000","message":"This will be loop, as per the spec.","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"f75c78b00f5a99fda0543c9c0bbd1059bf151039","unresolved":true,"context_lines":[{"line_number":88,"context_line":"                        \"description\": \"JSON path to field for matching\","},{"line_number":89,"context_line":"                        \"type\": \"string\""},{"line_number":90,"context_line":"                    },"},{"line_number":91,"context_line":"                    \"multiple\": {"},{"line_number":92,"context_line":"                        \"description\": \"how to treat multiple values\","},{"line_number":93,"context_line":"                        \"enum\": [\"all\", \"any\", \"first\"]"},{"line_number":94,"context_line":"                    },"}],"source_content_type":"text/x-python","patch_set":15,"id":"1c760c9d_083c4655","line":91,"in_reply_to":"88b8d6ef_e2ebab50","updated":"2024-09-19 17:53:38.000000000","message":"I\u0027m unsure what the `loop` field should look like.","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":true,"context_lines":[{"line_number":88,"context_line":"                        \"description\": \"JSON path to field for matching\","},{"line_number":89,"context_line":"                        \"type\": \"string\""},{"line_number":90,"context_line":"                    },"},{"line_number":91,"context_line":"                    \"multiple\": {"},{"line_number":92,"context_line":"                        \"description\": \"how to treat multiple values\","},{"line_number":93,"context_line":"                        \"enum\": [\"all\", \"any\", \"first\"]"},{"line_number":94,"context_line":"                    },"}],"source_content_type":"text/x-python","patch_set":15,"id":"fbcea6a9_69c76783","line":91,"in_reply_to":"f9ae5b50_2bf52be5","updated":"2024-09-17 11:41:10.000000000","message":"No, turns out loop is another field","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"c3b837f4b8ff2fbd7af491de22b7517a1f08586a","unresolved":true,"context_lines":[{"line_number":88,"context_line":"                        \"description\": \"JSON path to field for matching\","},{"line_number":89,"context_line":"                        \"type\": \"string\""},{"line_number":90,"context_line":"                    },"},{"line_number":91,"context_line":"                    \"multiple\": {"},{"line_number":92,"context_line":"                        \"description\": \"how to treat multiple values\","},{"line_number":93,"context_line":"                        \"enum\": [\"all\", \"any\", \"first\"]"},{"line_number":94,"context_line":"                    },"}],"source_content_type":"text/x-python","patch_set":15,"id":"88b8d6ef_e2ebab50","line":91,"in_reply_to":"fbcea6a9_69c76783","updated":"2024-09-19 13:29:26.000000000","message":"The loop field is for both conditions and actions. For actions, it\u0027s simply a sequence of actions. For conditions, we also need a \u0027multiple\u0027 field, which explains how the conditions will be joined together (e.g. and/or).","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":90,"context_line":"                    },"},{"line_number":91,"context_line":"                    \"multiple\": {"},{"line_number":92,"context_line":"                        \"description\": \"how to treat multiple values\","},{"line_number":93,"context_line":"                        \"enum\": [\"all\", \"any\", \"first\"]"},{"line_number":94,"context_line":"                    },"},{"line_number":95,"context_line":"                    \"invert\": {"},{"line_number":96,"context_line":"                        \"description\": \"whether to invert the result\","}],"source_content_type":"text/x-python","patch_set":15,"id":"62e20374_c322b172","line":93,"updated":"2024-09-12 10:36:13.000000000","message":"Also, last","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":false,"context_lines":[{"line_number":90,"context_line":"                    },"},{"line_number":91,"context_line":"                    \"multiple\": {"},{"line_number":92,"context_line":"                        \"description\": \"how to treat multiple values\","},{"line_number":93,"context_line":"                        \"enum\": [\"all\", \"any\", \"first\"]"},{"line_number":94,"context_line":"                    },"},{"line_number":95,"context_line":"                    \"invert\": {"},{"line_number":96,"context_line":"                        \"description\": \"whether to invert the result\","}],"source_content_type":"text/x-python","patch_set":15,"id":"aa932655_1f053062","line":93,"in_reply_to":"62e20374_c322b172","updated":"2024-09-17 11:41:10.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":92,"context_line":"                        \"description\": \"how to treat multiple values\","},{"line_number":93,"context_line":"                        \"enum\": [\"all\", \"any\", \"first\"]"},{"line_number":94,"context_line":"                    },"},{"line_number":95,"context_line":"                    \"invert\": {"},{"line_number":96,"context_line":"                        \"description\": \"whether to invert the result\","},{"line_number":97,"context_line":"                        \"type\": \"boolean\""},{"line_number":98,"context_line":"                    },"}],"source_content_type":"text/x-python","patch_set":15,"id":"72b3aa0f_f190daee","line":95,"updated":"2024-09-12 10:36:13.000000000","message":"This will be replaced with !op, as per the spec","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":false,"context_lines":[{"line_number":92,"context_line":"                        \"description\": \"how to treat multiple values\","},{"line_number":93,"context_line":"                        \"enum\": [\"all\", \"any\", \"first\"]"},{"line_number":94,"context_line":"                    },"},{"line_number":95,"context_line":"                    \"invert\": {"},{"line_number":96,"context_line":"                        \"description\": \"whether to invert the result\","},{"line_number":97,"context_line":"                        \"type\": \"boolean\""},{"line_number":98,"context_line":"                    },"}],"source_content_type":"text/x-python","patch_set":15,"id":"26b71d3a_a3c3b79c","line":95,"in_reply_to":"72b3aa0f_f190daee","updated":"2024-09-17 11:41:10.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":111,"context_line":"        action_plugins \u003d [x.name for x"},{"line_number":112,"context_line":"                          in plugins.rule_actions_manager()]"},{"line_number":113,"context_line":"        _ACTIONS_SCHEMA \u003d {"},{"line_number":114,"context_line":"            \"title\": \"Inspector rule actions schema\","},{"line_number":115,"context_line":"            \"type\": \"array\","},{"line_number":116,"context_line":"            \"minItems\": 1,"},{"line_number":117,"context_line":"            \"items\": {"}],"source_content_type":"text/x-python","patch_set":15,"id":"c1a7c1e6_9d089b4e","line":114,"updated":"2024-09-12 10:36:13.000000000","message":"\"Inspection rule actions schema\" sounds better","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":false,"context_lines":[{"line_number":111,"context_line":"        action_plugins \u003d [x.name for x"},{"line_number":112,"context_line":"                          in plugins.rule_actions_manager()]"},{"line_number":113,"context_line":"        _ACTIONS_SCHEMA \u003d {"},{"line_number":114,"context_line":"            \"title\": \"Inspector rule actions schema\","},{"line_number":115,"context_line":"            \"type\": \"array\","},{"line_number":116,"context_line":"            \"minItems\": 1,"},{"line_number":117,"context_line":"            \"items\": {"}],"source_content_type":"text/x-python","patch_set":15,"id":"6ffdd8f1_c943fd1f","line":114,"in_reply_to":"c1a7c1e6_9d089b4e","updated":"2024-09-17 11:41:10.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":118,"context_line":"                \"type\": \"object\","},{"line_number":119,"context_line":"                \"required\": [\"action\"],"},{"line_number":120,"context_line":"                \"properties\": {"},{"line_number":121,"context_line":"                    \"action\": {"},{"line_number":122,"context_line":"                        \"description\": \"action to take\","},{"line_number":123,"context_line":"                        \"enum\": action_plugins"},{"line_number":124,"context_line":"                    },"}],"source_content_type":"text/x-python","patch_set":15,"id":"73a23072_4a98393d","line":121,"updated":"2024-09-12 10:36:13.000000000","message":"This will be op, as per the spec.","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":false,"context_lines":[{"line_number":118,"context_line":"                \"type\": \"object\","},{"line_number":119,"context_line":"                \"required\": [\"action\"],"},{"line_number":120,"context_line":"                \"properties\": {"},{"line_number":121,"context_line":"                    \"action\": {"},{"line_number":122,"context_line":"                        \"description\": \"action to take\","},{"line_number":123,"context_line":"                        \"enum\": action_plugins"},{"line_number":124,"context_line":"                    },"}],"source_content_type":"text/x-python","patch_set":15,"id":"51b8c1c8_ed9f6918","line":121,"in_reply_to":"73a23072_4a98393d","updated":"2024-09-17 11:41:10.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":121,"context_line":"                    \"action\": {"},{"line_number":122,"context_line":"                        \"description\": \"action to take\","},{"line_number":123,"context_line":"                        \"enum\": action_plugins"},{"line_number":124,"context_line":"                    },"},{"line_number":125,"context_line":"                },"},{"line_number":126,"context_line":"                # other properties are validated by plugins"},{"line_number":127,"context_line":"                \"additionalProperties\": True"}],"source_content_type":"text/x-python","patch_set":15,"id":"9ea40447_8ae358ad","line":124,"updated":"2024-09-12 10:36:13.000000000","message":"Need to add args, as per spec","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":false,"context_lines":[{"line_number":121,"context_line":"                    \"action\": {"},{"line_number":122,"context_line":"                        \"description\": \"action to take\","},{"line_number":123,"context_line":"                        \"enum\": action_plugins"},{"line_number":124,"context_line":"                    },"},{"line_number":125,"context_line":"                },"},{"line_number":126,"context_line":"                # other properties are validated by plugins"},{"line_number":127,"context_line":"                \"additionalProperties\": True"}],"source_content_type":"text/x-python","patch_set":15,"id":"df013ed4_a8622257","line":124,"in_reply_to":"9ea40447_8ae358ad","updated":"2024-09-17 11:41:10.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":175,"context_line":"            raise exception.Invalid(msg)"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"        conditions.append({"},{"line_number":178,"context_line":"            \u0027field\u0027: cond_json[\u0027field\u0027],"},{"line_number":179,"context_line":"            \u0027op\u0027: cond_json[\u0027op\u0027],"},{"line_number":180,"context_line":"            \u0027multiple\u0027: cond_json.get(\u0027multiple\u0027, \u0027any\u0027),"},{"line_number":181,"context_line":"            \u0027invert\u0027: cond_json.get(\u0027invert\u0027, False),"}],"source_content_type":"text/x-python","patch_set":15,"id":"20bde38c_6c2c33bc","line":178,"updated":"2024-09-12 10:36:13.000000000","message":"Needs to be updated as per the new struct (see spec)","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"63d2acb354ea3f9812b7ec24baf6de01d8c27da0","unresolved":false,"context_lines":[{"line_number":175,"context_line":"            raise exception.Invalid(msg)"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"        conditions.append({"},{"line_number":178,"context_line":"            \u0027field\u0027: cond_json[\u0027field\u0027],"},{"line_number":179,"context_line":"            \u0027op\u0027: cond_json[\u0027op\u0027],"},{"line_number":180,"context_line":"            \u0027multiple\u0027: cond_json.get(\u0027multiple\u0027, \u0027any\u0027),"},{"line_number":181,"context_line":"            \u0027invert\u0027: cond_json.get(\u0027invert\u0027, False),"}],"source_content_type":"text/x-python","patch_set":15,"id":"76c37868_bec1d24c","line":178,"in_reply_to":"20bde38c_6c2c33bc","updated":"2024-09-20 09:44:04.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":331,"context_line":""},{"line_number":332,"context_line":"    @METRICS.timer(\u0027InspectionRuleController.get_one\u0027)"},{"line_number":333,"context_line":"    @method.expose()"},{"line_number":334,"context_line":"    @args.validate(runbook_ident\u003dargs.uuid_or_name, fields\u003dargs.string_list)"},{"line_number":335,"context_line":"    def get_one(self, inspection_rule_ident, fields\u003dNone):"},{"line_number":336,"context_line":"        \"\"\"Retrieve information about the given inspection rule."},{"line_number":337,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"2a4e24e0_f7a01537","line":334,"updated":"2024-09-12 10:36:13.000000000","message":"runbook_ident","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":false,"context_lines":[{"line_number":331,"context_line":""},{"line_number":332,"context_line":"    @METRICS.timer(\u0027InspectionRuleController.get_one\u0027)"},{"line_number":333,"context_line":"    @method.expose()"},{"line_number":334,"context_line":"    @args.validate(runbook_ident\u003dargs.uuid_or_name, fields\u003dargs.string_list)"},{"line_number":335,"context_line":"    def get_one(self, inspection_rule_ident, fields\u003dNone):"},{"line_number":336,"context_line":"        \"\"\"Retrieve information about the given inspection rule."},{"line_number":337,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"fcf94501_a381905a","line":334,"in_reply_to":"2a4e24e0_f7a01537","updated":"2024-09-17 11:41:10.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":335,"context_line":"    def get_one(self, inspection_rule_ident, fields\u003dNone):"},{"line_number":336,"context_line":"        \"\"\"Retrieve information about the given inspection rule."},{"line_number":337,"context_line":""},{"line_number":338,"context_line":"        :param runbook_ident: UUID or logical name of a inspection rule."},{"line_number":339,"context_line":"        :param fields: Optional, a list with a specified set of fields"},{"line_number":340,"context_line":"            of the resource to be returned."},{"line_number":341,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":15,"id":"056e29a4_af7ec4fb","line":338,"updated":"2024-09-12 10:36:13.000000000","message":"\u0027inspection_rule_ident\u0027 instead of \u0027runbook_ident\u0027 :)\nAlso, \u0027an inspection rule\u0027","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":false,"context_lines":[{"line_number":335,"context_line":"    def get_one(self, inspection_rule_ident, fields\u003dNone):"},{"line_number":336,"context_line":"        \"\"\"Retrieve information about the given inspection rule."},{"line_number":337,"context_line":""},{"line_number":338,"context_line":"        :param runbook_ident: UUID or logical name of a inspection rule."},{"line_number":339,"context_line":"        :param fields: Optional, a list with a specified set of fields"},{"line_number":340,"context_line":"            of the resource to be returned."},{"line_number":341,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":15,"id":"44e5a508_a3279532","line":338,"in_reply_to":"056e29a4_af7ec4fb","updated":"2024-09-17 11:41:10.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":true,"context_lines":[{"line_number":87,"context_line":"                        \"description\": \"Arguments for the condition\","},{"line_number":88,"context_line":"                        \"type\": [\"array\", \"object\"]"},{"line_number":89,"context_line":"                    },"},{"line_number":90,"context_line":"                    \"field\": {"},{"line_number":91,"context_line":"                        \"description\": \"JSON path to field for matching\","},{"line_number":92,"context_line":"                        \"type\": \"string\""},{"line_number":93,"context_line":"                    },"}],"source_content_type":"text/x-python","patch_set":18,"id":"027878ec_d5b31fe8","line":90,"updated":"2024-09-17 11:41:10.000000000","message":"I believe \u0027field\u0027 needs to be dropped (it got replaced by args)","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d77b316d2ede916f32f502d2d4671d60556781de","unresolved":false,"context_lines":[{"line_number":87,"context_line":"                        \"description\": \"Arguments for the condition\","},{"line_number":88,"context_line":"                        \"type\": [\"array\", \"object\"]"},{"line_number":89,"context_line":"                    },"},{"line_number":90,"context_line":"                    \"field\": {"},{"line_number":91,"context_line":"                        \"description\": \"JSON path to field for matching\","},{"line_number":92,"context_line":"                        \"type\": \"string\""},{"line_number":93,"context_line":"                    },"}],"source_content_type":"text/x-python","patch_set":18,"id":"50fde07f_d01edfbf","line":90,"in_reply_to":"027878ec_d5b31fe8","updated":"2024-09-20 09:37:56.000000000","message":"Done","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":true,"context_lines":[{"line_number":94,"context_line":"                    \"multiple\": {"},{"line_number":95,"context_line":"                        \"description\": \"how to treat multiple values\","},{"line_number":96,"context_line":"                        \"enum\": [\"any\", \"all\", \"first\", \"last\"]"},{"line_number":97,"context_line":"                    },"},{"line_number":98,"context_line":"                },"},{"line_number":99,"context_line":"                # other properties are validated by plugins"},{"line_number":100,"context_line":"                \"additionalProperties\": True"}],"source_content_type":"text/x-python","patch_set":18,"id":"b9ac967d_45a960af","line":97,"updated":"2024-09-17 11:41:10.000000000","message":"I think we also need to add the loop field in both conditions and actions, IIUC","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":true,"context_lines":[{"line_number":118,"context_line":"                \"required\": [\"op\", \"args\"],"},{"line_number":119,"context_line":"                \"properties\": {"},{"line_number":120,"context_line":"                    \"op\": {"},{"line_number":121,"context_line":"                        \"description\": \"condition operator\","},{"line_number":122,"context_line":"                        \"enum\": action_plugins"},{"line_number":123,"context_line":"                    },"},{"line_number":124,"context_line":"                    \"args\": {"}],"source_content_type":"text/x-python","patch_set":18,"id":"345bbc2e_cb9da2e5","line":121,"updated":"2024-09-17 11:41:10.000000000","message":"action operator","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"f75c78b00f5a99fda0543c9c0bbd1059bf151039","unresolved":false,"context_lines":[{"line_number":118,"context_line":"                \"required\": [\"op\", \"args\"],"},{"line_number":119,"context_line":"                \"properties\": {"},{"line_number":120,"context_line":"                    \"op\": {"},{"line_number":121,"context_line":"                        \"description\": \"condition operator\","},{"line_number":122,"context_line":"                        \"enum\": action_plugins"},{"line_number":123,"context_line":"                    },"},{"line_number":124,"context_line":"                    \"args\": {"}],"source_content_type":"text/x-python","patch_set":18,"id":"1e873430_9a611822","line":121,"in_reply_to":"345bbc2e_cb9da2e5","updated":"2024-09-19 17:53:38.000000000","message":"Acknowledged","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"5ffa7531da551c6bf57dca8682962809e9a6515f","unresolved":true,"context_lines":[{"line_number":49,"context_line":"        condition_plugins \u003d [x.name for x"},{"line_number":50,"context_line":"                             in plugins.rule_conditions_manager()]"},{"line_number":51,"context_line":"        _INSPECTION_RULE_CONDITIONS_SCHEMA \u003d {"},{"line_number":52,"context_line":"            \"title\": \"Inspector rule conditions schema\","},{"line_number":53,"context_line":"            \"type\": \"array\","},{"line_number":54,"context_line":"            # we can have rules that always apply"},{"line_number":55,"context_line":"            \"minItems\": 0,"}],"source_content_type":"text/x-python","patch_set":20,"id":"529ccad3_7197815d","line":52,"updated":"2024-10-09 13:38:50.000000000","message":"nit: \u0027Inspection rule\u0027 instead of \u0027Inspector rule\u0027","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        condition_plugins \u003d [x.name for x"},{"line_number":50,"context_line":"                             in plugins.rule_conditions_manager()]"},{"line_number":51,"context_line":"        _INSPECTION_RULE_CONDITIONS_SCHEMA \u003d {"},{"line_number":52,"context_line":"            \"title\": \"Inspector rule conditions schema\","},{"line_number":53,"context_line":"            \"type\": \"array\","},{"line_number":54,"context_line":"            # we can have rules that always apply"},{"line_number":55,"context_line":"            \"minItems\": 0,"}],"source_content_type":"text/x-python","patch_set":20,"id":"9c15ff09_c739f2ab","line":52,"in_reply_to":"529ccad3_7197815d","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":66,"context_line":"                        \"type\": [\"array\", \"object\"]"},{"line_number":67,"context_line":"                    },"},{"line_number":68,"context_line":"                    \"multiple\": {"},{"line_number":69,"context_line":"                        \"description\": \"how to treat multiple values\","},{"line_number":70,"context_line":"                        \"enum\": [\"any\", \"all\", \"first\", \"last\"]"},{"line_number":71,"context_line":"                    },"},{"line_number":72,"context_line":"                },"}],"source_content_type":"text/x-python","patch_set":20,"id":"afdbaf64_565ac3f9","line":69,"updated":"2024-09-26 15:27:50.000000000","message":"nit: inconsistent case (Arguments vs how)","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":66,"context_line":"                        \"type\": [\"array\", \"object\"]"},{"line_number":67,"context_line":"                    },"},{"line_number":68,"context_line":"                    \"multiple\": {"},{"line_number":69,"context_line":"                        \"description\": \"how to treat multiple values\","},{"line_number":70,"context_line":"                        \"enum\": [\"any\", \"all\", \"first\", \"last\"]"},{"line_number":71,"context_line":"                    },"},{"line_number":72,"context_line":"                },"}],"source_content_type":"text/x-python","patch_set":20,"id":"ac9a8d9e_994cd2c0","line":69,"in_reply_to":"afdbaf64_565ac3f9","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":68,"context_line":"                    \"multiple\": {"},{"line_number":69,"context_line":"                        \"description\": \"how to treat multiple values\","},{"line_number":70,"context_line":"                        \"enum\": [\"any\", \"all\", \"first\", \"last\"]"},{"line_number":71,"context_line":"                    },"},{"line_number":72,"context_line":"                },"},{"line_number":73,"context_line":"                # other properties are validated by plugins"},{"line_number":74,"context_line":"                \"additionalProperties\": True"}],"source_content_type":"text/x-python","patch_set":20,"id":"c3862d2d_18535aa6","line":71,"updated":"2024-09-26 15:27:50.000000000","message":"missing loop","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"5ffa7531da551c6bf57dca8682962809e9a6515f","unresolved":true,"context_lines":[{"line_number":84,"context_line":"        action_plugins \u003d [x.name for x"},{"line_number":85,"context_line":"                          in plugins.rule_actions_manager()]"},{"line_number":86,"context_line":"        _INSPECTION_RULE_ACTIONS_SCHEMA \u003d {"},{"line_number":87,"context_line":"            \"title\": \"Inspector rule actions schema\","},{"line_number":88,"context_line":"            \"type\": \"array\","},{"line_number":89,"context_line":"            \"minItems\": 1,"},{"line_number":90,"context_line":"            \"items\": {"}],"source_content_type":"text/x-python","patch_set":20,"id":"99f75a3f_ee1c5d7d","line":87,"updated":"2024-10-09 13:38:50.000000000","message":"nit: \u0027Inspection rule\u0027 instead of \u0027Inspector rule\u0027","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        action_plugins \u003d [x.name for x"},{"line_number":85,"context_line":"                          in plugins.rule_actions_manager()]"},{"line_number":86,"context_line":"        _INSPECTION_RULE_ACTIONS_SCHEMA \u003d {"},{"line_number":87,"context_line":"            \"title\": \"Inspector rule actions schema\","},{"line_number":88,"context_line":"            \"type\": \"array\","},{"line_number":89,"context_line":"            \"minItems\": 1,"},{"line_number":90,"context_line":"            \"items\": {"}],"source_content_type":"text/x-python","patch_set":20,"id":"f0107549_366f43b9","line":87,"in_reply_to":"99f75a3f_ee1c5d7d","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":98,"context_line":"                    \"args\": {"},{"line_number":99,"context_line":"                        \"description\": \"Arguments for the action\","},{"line_number":100,"context_line":"                        \"type\": [\"array\", \"object\"]"},{"line_number":101,"context_line":"                    },"},{"line_number":102,"context_line":"                },"},{"line_number":103,"context_line":"                # other properties are validated by plugins"},{"line_number":104,"context_line":"                \"additionalProperties\": True"}],"source_content_type":"text/x-python","patch_set":20,"id":"24e78091_6e6d178c","line":101,"updated":"2024-09-26 15:27:50.000000000","message":"missing loop too","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":246,"context_line":"        :param detail: Optional, boolean to indicate whether retrieve a list"},{"line_number":247,"context_line":"                       of inspection rules with detail."},{"line_number":248,"context_line":"        \"\"\""},{"line_number":249,"context_line":"        if not api_utils.allow_inspection_rules():"},{"line_number":250,"context_line":"            raise exception.NotFound()"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"        api_utils.check_allowed_fields(fields)"}],"source_content_type":"text/x-python","patch_set":20,"id":"f423984e_d1d87d50","line":249,"updated":"2024-09-26 15:27:50.000000000","message":"These instances of allow_inspection_rules are not needed given the implementation of _route above.","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":246,"context_line":"        :param detail: Optional, boolean to indicate whether retrieve a list"},{"line_number":247,"context_line":"                       of inspection rules with detail."},{"line_number":248,"context_line":"        \"\"\""},{"line_number":249,"context_line":"        if not api_utils.allow_inspection_rules():"},{"line_number":250,"context_line":"            raise exception.NotFound()"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"        api_utils.check_allowed_fields(fields)"}],"source_content_type":"text/x-python","patch_set":20,"id":"c23d24a6_cc4ed3c7","line":249,"in_reply_to":"f423984e_d1d87d50","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":248,"context_line":"        \"\"\""},{"line_number":249,"context_line":"        if not api_utils.allow_inspection_rules():"},{"line_number":250,"context_line":"            raise exception.NotFound()"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"        api_utils.check_allowed_fields(fields)"},{"line_number":253,"context_line":"        api_utils.check_allowed_fields([sort_key])"},{"line_number":254,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"aff38a13_f2545ac8","line":251,"updated":"2024-09-26 15:27:50.000000000","message":"missing check_policy call","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":248,"context_line":"        \"\"\""},{"line_number":249,"context_line":"        if not api_utils.allow_inspection_rules():"},{"line_number":250,"context_line":"            raise exception.NotFound()"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"        api_utils.check_allowed_fields(fields)"},{"line_number":253,"context_line":"        api_utils.check_allowed_fields([sort_key])"},{"line_number":254,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"3c1e6ebb_37ed8406","line":251,"in_reply_to":"aff38a13_f2545ac8","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":282,"context_line":""},{"line_number":283,"context_line":"    @METRICS.timer(\u0027InspectionRuleController.get_one\u0027)"},{"line_number":284,"context_line":"    @method.expose()"},{"line_number":285,"context_line":"    @args.validate(inspection_rule_ident\u003dargs.uuid_or_name,"},{"line_number":286,"context_line":"                   fields\u003dargs.string_list)"},{"line_number":287,"context_line":"    def get_one(self, inspection_rule_ident, fields\u003dNone):"},{"line_number":288,"context_line":"        \"\"\"Retrieve information about the given inspection rule."}],"source_content_type":"text/x-python","patch_set":20,"id":"5368b89d_3909a512","line":285,"updated":"2024-09-26 15:27:50.000000000","message":"There is no name support, I believe, so it should be just uuid","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":282,"context_line":""},{"line_number":283,"context_line":"    @METRICS.timer(\u0027InspectionRuleController.get_one\u0027)"},{"line_number":284,"context_line":"    @method.expose()"},{"line_number":285,"context_line":"    @args.validate(inspection_rule_ident\u003dargs.uuid_or_name,"},{"line_number":286,"context_line":"                   fields\u003dargs.string_list)"},{"line_number":287,"context_line":"    def get_one(self, inspection_rule_ident, fields\u003dNone):"},{"line_number":288,"context_line":"        \"\"\"Retrieve information about the given inspection rule."}],"source_content_type":"text/x-python","patch_set":20,"id":"eca2b0cf_9794a28b","line":285,"in_reply_to":"5368b89d_3909a512","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":296,"context_line":"            raise exception.NotFound()"},{"line_number":297,"context_line":""},{"line_number":298,"context_line":"        api_utils.check_policy(\u0027baremetal:inspection_rule:get\u0027)"},{"line_number":299,"context_line":"        rpc_rule \u003d api_utils.get_inspection_rule(inspection_rule_ident)"},{"line_number":300,"context_line":""},{"line_number":301,"context_line":"        api_utils.check_allowed_fields(fields)"},{"line_number":302,"context_line":"        return convert_with_links(rpc_rule, fields\u003dfields)"}],"source_content_type":"text/x-python","patch_set":20,"id":"240fc1a1_9dc7a797","line":299,"updated":"2024-09-26 15:27:50.000000000","message":"objects.InspectionRule.get_by_uuid","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":296,"context_line":"            raise exception.NotFound()"},{"line_number":297,"context_line":""},{"line_number":298,"context_line":"        api_utils.check_policy(\u0027baremetal:inspection_rule:get\u0027)"},{"line_number":299,"context_line":"        rpc_rule \u003d api_utils.get_inspection_rule(inspection_rule_ident)"},{"line_number":300,"context_line":""},{"line_number":301,"context_line":"        api_utils.check_allowed_fields(fields)"},{"line_number":302,"context_line":"        return convert_with_links(rpc_rule, fields\u003dfields)"}],"source_content_type":"text/x-python","patch_set":20,"id":"320a87b9_9a015314","line":299,"in_reply_to":"240fc1a1_9dc7a797","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":304,"context_line":"    @METRICS.timer(\u0027InspectionRuleController.post\u0027)"},{"line_number":305,"context_line":"    @method.expose(status_code\u003dhttp_client.CREATED)"},{"line_number":306,"context_line":"    @method.body(\u0027inspection_rule\u0027)"},{"line_number":307,"context_line":"    def post(self, inspection_rule):"},{"line_number":308,"context_line":"        \"\"\"Create a new inspection rule."},{"line_number":309,"context_line":""},{"line_number":310,"context_line":"        :param inspection_rule: a inspection rule within the request body."}],"source_content_type":"text/x-python","patch_set":20,"id":"7e37b818_a53c7d3e","line":307,"updated":"2024-09-26 15:27:50.000000000","message":"inspection rule not validated (should have a schema of its own)","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":304,"context_line":"    @METRICS.timer(\u0027InspectionRuleController.post\u0027)"},{"line_number":305,"context_line":"    @method.expose(status_code\u003dhttp_client.CREATED)"},{"line_number":306,"context_line":"    @method.body(\u0027inspection_rule\u0027)"},{"line_number":307,"context_line":"    def post(self, inspection_rule):"},{"line_number":308,"context_line":"        \"\"\"Create a new inspection rule."},{"line_number":309,"context_line":""},{"line_number":310,"context_line":"        :param inspection_rule: a inspection rule within the request body."}],"source_content_type":"text/x-python","patch_set":20,"id":"555de145_c9aabc8e","line":307,"in_reply_to":"7e37b818_a53c7d3e","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8ac093b99d4088b796948d68be69f7677a3739bf","unresolved":true,"context_lines":[{"line_number":13,"context_line":"import enum"},{"line_number":14,"context_line":"from http import client as http_client"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from ironic_lib import metrics_utils"},{"line_number":17,"context_line":"import jsonschema"},{"line_number":18,"context_line":"from oslo_log import log"},{"line_number":19,"context_line":"from oslo_utils import uuidutils"}],"source_content_type":"text/x-python","patch_set":29,"id":"fb2b3b61_d85a2184","line":16,"updated":"2024-12-11 19:46:31.000000000","message":"These have been moved into Ironic proper.","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"eea8011dd479693e4b717a28aa60480a23776ec3","unresolved":true,"context_lines":[{"line_number":13,"context_line":"import enum"},{"line_number":14,"context_line":"from http import client as http_client"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from ironic_lib import metrics_utils"},{"line_number":17,"context_line":"import jsonschema"},{"line_number":18,"context_line":"from oslo_log import log"},{"line_number":19,"context_line":"from oslo_utils import uuidutils"}],"source_content_type":"text/x-python","patch_set":29,"id":"2efd390e_8aa9b878","line":16,"in_reply_to":"ebc60693_1d3036c0","updated":"2024-12-19 22:04:08.000000000","message":"I\u0027m working on the change to migrate out ironic_lib now; I thought metrics had already been done but I was wrong. Sorry for the wrong pointer!","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"565dd44cf708e98acd1bd17c35de29e782f41bfa","unresolved":true,"context_lines":[{"line_number":13,"context_line":"import enum"},{"line_number":14,"context_line":"from http import client as http_client"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from ironic_lib import metrics_utils"},{"line_number":17,"context_line":"import jsonschema"},{"line_number":18,"context_line":"from oslo_log import log"},{"line_number":19,"context_line":"from oslo_utils import uuidutils"}],"source_content_type":"text/x-python","patch_set":29,"id":"ebc60693_1d3036c0","line":16,"in_reply_to":"fb2b3b61_d85a2184","updated":"2024-12-16 08:08:19.000000000","message":"I couldn\u0027t make this import from Ironic","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8ac093b99d4088b796948d68be69f7677a3739bf","unresolved":true,"context_lines":[{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    :param rule: The inspection rule to validate."},{"line_number":177,"context_line":"    :raises: Invalid if the rule is invalid."},{"line_number":178,"context_line":"    \"\"\""},{"line_number":179,"context_line":"    try:"},{"line_number":180,"context_line":"        jsonschema.validate(rule, INSPECTION_RULE_SCHEMA)"},{"line_number":181,"context_line":"    except jsonschema.ValidationError as e:"}],"source_content_type":"text/x-python","patch_set":29,"id":"8ffd40b0_f2222e26","line":178,"updated":"2024-12-11 19:46:31.000000000","message":"We should consider gathering all possible errors and returning them all, instead of one at a time. We could assign the exceptions we create to a array, then return a meta-exception if the array is \u003d\u003e2 (or just the plain exception if 1, or nothing if 0)","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"565dd44cf708e98acd1bd17c35de29e782f41bfa","unresolved":false,"context_lines":[{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    :param rule: The inspection rule to validate."},{"line_number":177,"context_line":"    :raises: Invalid if the rule is invalid."},{"line_number":178,"context_line":"    \"\"\""},{"line_number":179,"context_line":"    try:"},{"line_number":180,"context_line":"        jsonschema.validate(rule, INSPECTION_RULE_SCHEMA)"},{"line_number":181,"context_line":"    except jsonschema.ValidationError as e:"}],"source_content_type":"text/x-python","patch_set":29,"id":"4bffaff2_9206ccfe","line":178,"in_reply_to":"8ffd40b0_f2222e26","updated":"2024-12-16 08:08:19.000000000","message":"Acknowledged","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8ac093b99d4088b796948d68be69f7677a3739bf","unresolved":true,"context_lines":[{"line_number":428,"context_line":"        sensitive_patch \u003d api_utils.get_patch_values(patch, \u0027/sensitive\u0027)"},{"line_number":429,"context_line":"        if (not sensitive_patch) and (sensitive_patch is not None):"},{"line_number":430,"context_line":"            if rpc_rule[\u0027sensitive\u0027]:"},{"line_number":431,"context_line":"                msg \u003d _(\"This rule cannot be made insensitive\")"},{"line_number":432,"context_line":"                raise exception.PatchError(patch\u003dpatch, reason\u003dmsg)"},{"line_number":433,"context_line":""},{"line_number":434,"context_line":"        if \u0027built_in\u0027 in patch:"}],"source_content_type":"text/x-python","patch_set":29,"id":"c24f094b_05a9904d","line":431,"updated":"2024-12-11 19:46:31.000000000","message":"This is awkward wording.\n\nConsider something like: \"Inspection rules cannot have the sensitive flag unset.\"","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"4486962842795d7b78b0e31c452d4af7c867de4c","unresolved":false,"context_lines":[{"line_number":428,"context_line":"        sensitive_patch \u003d api_utils.get_patch_values(patch, \u0027/sensitive\u0027)"},{"line_number":429,"context_line":"        if (not sensitive_patch) and (sensitive_patch is not None):"},{"line_number":430,"context_line":"            if rpc_rule[\u0027sensitive\u0027]:"},{"line_number":431,"context_line":"                msg \u003d _(\"This rule cannot be made insensitive\")"},{"line_number":432,"context_line":"                raise exception.PatchError(patch\u003dpatch, reason\u003dmsg)"},{"line_number":433,"context_line":""},{"line_number":434,"context_line":"        if \u0027built_in\u0027 in patch:"}],"source_content_type":"text/x-python","patch_set":29,"id":"cd657b26_c5a6af4c","line":431,"in_reply_to":"c24f094b_05a9904d","updated":"2024-12-14 09:49:05.000000000","message":"Acknowledged","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8ac093b99d4088b796948d68be69f7677a3739bf","unresolved":true,"context_lines":[{"line_number":464,"context_line":"        context \u003d api.request.context"},{"line_number":465,"context_line":"        if not inspection_rule_uuid:"},{"line_number":466,"context_line":"            api_utils.check_policy(\u0027baremetal:inspection_rule:delete_all\u0027)"},{"line_number":467,"context_line":"            if not confirm or confirm.lower() !\u003d \u0027true\u0027:"},{"line_number":468,"context_line":"                raise webob_exc.HTTPBadRequest("},{"line_number":469,"context_line":"                    _(\"Bulk deletion requires confirmation. \""},{"line_number":470,"context_line":"                      \"Please add \u0027?confirm\u003dtrue\u0027 to the request.\"))"}],"source_content_type":"text/x-python","patch_set":29,"id":"ab354d44_bffd77ba","line":467,"updated":"2024-12-11 19:46:31.000000000","message":"While I share your fear over needing to confirm this, https://specs.openstack.org/openstack/ironic-specs/specs/not-implemented/inspection-rules.html the spec does not reference this field, and therefore it probably be added. This may be worth considering implementing when we write client side support for this.","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"4486962842795d7b78b0e31c452d4af7c867de4c","unresolved":false,"context_lines":[{"line_number":464,"context_line":"        context \u003d api.request.context"},{"line_number":465,"context_line":"        if not inspection_rule_uuid:"},{"line_number":466,"context_line":"            api_utils.check_policy(\u0027baremetal:inspection_rule:delete_all\u0027)"},{"line_number":467,"context_line":"            if not confirm or confirm.lower() !\u003d \u0027true\u0027:"},{"line_number":468,"context_line":"                raise webob_exc.HTTPBadRequest("},{"line_number":469,"context_line":"                    _(\"Bulk deletion requires confirmation. \""},{"line_number":470,"context_line":"                      \"Please add \u0027?confirm\u003dtrue\u0027 to the request.\"))"}],"source_content_type":"text/x-python","patch_set":29,"id":"3d473ee8_dec8b21e","line":467,"in_reply_to":"ab354d44_bffd77ba","updated":"2024-12-14 09:49:05.000000000","message":"Acknowledged","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":50,"context_line":"    MAIN \u003d \u0027main\u0027"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"OPERATORS \u003d {"},{"line_number":54,"context_line":"    \"eq\": operators.EqOperator,"},{"line_number":55,"context_line":"    \"lt\": operators.LtOperator,"},{"line_number":56,"context_line":"    \"gt\": operators.GtOperator,"}],"source_content_type":"text/x-python","patch_set":43,"id":"db0e0dee_9cbee8f8","line":53,"updated":"2025-01-08 13:32:17.000000000","message":"I already wrote it somewhere else, but OPERATORS and ACTIONS are a part of the engine, not the API, so they should be moved somewhere to ironic.common.inspection_rules.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    MAIN \u003d \u0027main\u0027"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"OPERATORS \u003d {"},{"line_number":54,"context_line":"    \"eq\": operators.EqOperator,"},{"line_number":55,"context_line":"    \"lt\": operators.LtOperator,"},{"line_number":56,"context_line":"    \"gt\": operators.GtOperator,"}],"source_content_type":"text/x-python","patch_set":43,"id":"f1e85bea_28405b6a","line":53,"in_reply_to":"db0e0dee_9cbee8f8","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"}],"ironic/api/controllers/v1/utils.py":[{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":1640,"context_line":""},{"line_number":1641,"context_line":""},{"line_number":1642,"context_line":"def allow_inspection_rules():"},{"line_number":1643,"context_line":"    \"\"\"Check if accessing rule endpoints is allowed."},{"line_number":1644,"context_line":""},{"line_number":1645,"context_line":"    Version 1.93 of the API exposed rule endpoints."},{"line_number":1646,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":15,"id":"9b5f0582_4b07af56","line":1643,"updated":"2024-09-12 10:36:13.000000000","message":"Nit: Add \u0027inspection\u0027 before rule","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":false,"context_lines":[{"line_number":1640,"context_line":""},{"line_number":1641,"context_line":""},{"line_number":1642,"context_line":"def allow_inspection_rules():"},{"line_number":1643,"context_line":"    \"\"\"Check if accessing rule endpoints is allowed."},{"line_number":1644,"context_line":""},{"line_number":1645,"context_line":"    Version 1.93 of the API exposed rule endpoints."},{"line_number":1646,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":15,"id":"bbba33b0_c4f6861e","line":1643,"in_reply_to":"9b5f0582_4b07af56","updated":"2024-09-17 11:41:10.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":2252,"context_line":"    :raises: InvalidUuidOrName if the name or uuid provided is not valid."},{"line_number":2253,"context_line":"    :raises: InspectionRuleNotFound if the rule is not found."},{"line_number":2254,"context_line":"    \"\"\""},{"line_number":2255,"context_line":"    # If runbook_ident is instead a valid UUID, treat it as a UUID."},{"line_number":2256,"context_line":"    if uuidutils.is_uuid_like(rule_ident):"},{"line_number":2257,"context_line":"        return objects.InspectionRule.get_by_uuid(api.request.context,"},{"line_number":2258,"context_line":"                                                  rule_ident)"}],"source_content_type":"text/x-python","patch_set":15,"id":"e4e8b0c3_54c5d2bd","line":2255,"updated":"2024-09-12 10:36:13.000000000","message":"rule_ident instead of runbook_ident","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"4cb2f4f605fcdbb84bdd27939ce1a26db1a261e8","unresolved":false,"context_lines":[{"line_number":2252,"context_line":"    :raises: InvalidUuidOrName if the name or uuid provided is not valid."},{"line_number":2253,"context_line":"    :raises: InspectionRuleNotFound if the rule is not found."},{"line_number":2254,"context_line":"    \"\"\""},{"line_number":2255,"context_line":"    # If runbook_ident is instead a valid UUID, treat it as a UUID."},{"line_number":2256,"context_line":"    if uuidutils.is_uuid_like(rule_ident):"},{"line_number":2257,"context_line":"        return objects.InspectionRule.get_by_uuid(api.request.context,"},{"line_number":2258,"context_line":"                                                  rule_ident)"}],"source_content_type":"text/x-python","patch_set":15,"id":"6add695b_008ed2e4","line":2255,"in_reply_to":"e4e8b0c3_54c5d2bd","updated":"2024-09-26 12:02:27.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":2257,"context_line":"        return objects.InspectionRule.get_by_uuid(api.request.context,"},{"line_number":2258,"context_line":"                                                  rule_ident)"},{"line_number":2259,"context_line":""},{"line_number":2260,"context_line":"    # Else, we can refer to runbooks by their name too"},{"line_number":2261,"context_line":"    if utils.is_valid_logical_name(rule_ident):"},{"line_number":2262,"context_line":"        return objects.InspectionRule.get_by_name(api.request.context,"},{"line_number":2263,"context_line":"                                                  rule_ident)"}],"source_content_type":"text/x-python","patch_set":15,"id":"239838e7_bdaa8af4","line":2260,"updated":"2024-09-12 10:36:13.000000000","message":"inspection rules instead of runbooks","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"4cb2f4f605fcdbb84bdd27939ce1a26db1a261e8","unresolved":false,"context_lines":[{"line_number":2257,"context_line":"        return objects.InspectionRule.get_by_uuid(api.request.context,"},{"line_number":2258,"context_line":"                                                  rule_ident)"},{"line_number":2259,"context_line":""},{"line_number":2260,"context_line":"    # Else, we can refer to runbooks by their name too"},{"line_number":2261,"context_line":"    if utils.is_valid_logical_name(rule_ident):"},{"line_number":2262,"context_line":"        return objects.InspectionRule.get_by_name(api.request.context,"},{"line_number":2263,"context_line":"                                                  rule_ident)"}],"source_content_type":"text/x-python","patch_set":15,"id":"4b2e76f5_c96400b8","line":2260,"in_reply_to":"239838e7_bdaa8af4","updated":"2024-09-26 12:02:27.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":true,"context_lines":[{"line_number":1625,"context_line":"            \u0027op\u0027: condition[\u0027op\u0027],"},{"line_number":1626,"context_line":"            \u0027args\u0027: condition.get(\u0027args\u0027, {}),"},{"line_number":1627,"context_line":"            \u0027multiple\u0027: condition.get(\u0027multiple\u0027, \u0027any\u0027),"},{"line_number":1628,"context_line":"            \u0027field\u0027: condition.get(\u0027field\u0027),"},{"line_number":1629,"context_line":"        }"},{"line_number":1630,"context_line":""},{"line_number":1631,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"548d8f28_d98dda6b","line":1628,"updated":"2024-09-17 11:41:10.000000000","message":"\u0027field\u0027 needs to be dropped","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"f75c78b00f5a99fda0543c9c0bbd1059bf151039","unresolved":false,"context_lines":[{"line_number":1625,"context_line":"            \u0027op\u0027: condition[\u0027op\u0027],"},{"line_number":1626,"context_line":"            \u0027args\u0027: condition.get(\u0027args\u0027, {}),"},{"line_number":1627,"context_line":"            \u0027multiple\u0027: condition.get(\u0027multiple\u0027, \u0027any\u0027),"},{"line_number":1628,"context_line":"            \u0027field\u0027: condition.get(\u0027field\u0027),"},{"line_number":1629,"context_line":"        }"},{"line_number":1630,"context_line":""},{"line_number":1631,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"7a395cde_06600b1f","line":1628,"in_reply_to":"548d8f28_d98dda6b","updated":"2024-09-19 17:53:38.000000000","message":"Acknowledged","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":1625,"context_line":"            \u0027op\u0027: condition[\u0027op\u0027],"},{"line_number":1626,"context_line":"            \u0027args\u0027: condition.get(\u0027args\u0027, {}),"},{"line_number":1627,"context_line":"            \u0027multiple\u0027: condition.get(\u0027multiple\u0027, \u0027any\u0027),"},{"line_number":1628,"context_line":"        }"},{"line_number":1629,"context_line":""},{"line_number":1630,"context_line":""},{"line_number":1631,"context_line":"def allow_runbooks():"}],"source_content_type":"text/x-python","patch_set":20,"id":"7245b04b_6c0f018e","line":1628,"updated":"2024-09-26 15:27:50.000000000","message":"I suggest these two calls stay in inspection_rules.py since other modules are unlikely to use them","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":1625,"context_line":"            \u0027op\u0027: condition[\u0027op\u0027],"},{"line_number":1626,"context_line":"            \u0027args\u0027: condition.get(\u0027args\u0027, {}),"},{"line_number":1627,"context_line":"            \u0027multiple\u0027: condition.get(\u0027multiple\u0027, \u0027any\u0027),"},{"line_number":1628,"context_line":"        }"},{"line_number":1629,"context_line":""},{"line_number":1630,"context_line":""},{"line_number":1631,"context_line":"def allow_runbooks():"}],"source_content_type":"text/x-python","patch_set":20,"id":"cf94643d_ca1db67a","line":1628,"in_reply_to":"7245b04b_6c0f018e","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":2240,"context_line":"    return api.request.version.minor \u003e\u003d versions.MINOR_93_GET_VMEDIA"},{"line_number":2241,"context_line":""},{"line_number":2242,"context_line":""},{"line_number":2243,"context_line":"def get_inspection_rule(rule_ident):"},{"line_number":2244,"context_line":"    \"\"\"Get the RPC inspection rule by the UUID."},{"line_number":2245,"context_line":""},{"line_number":2246,"context_line":"    :param rule_ident: the UUID of a rule."}],"source_content_type":"text/x-python","patch_set":20,"id":"99ebacb1_81486c08","line":2243,"updated":"2024-09-26 15:27:50.000000000","message":"Since there is no name support, this function seems redundant","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":2240,"context_line":"    return api.request.version.minor \u003e\u003d versions.MINOR_93_GET_VMEDIA"},{"line_number":2241,"context_line":""},{"line_number":2242,"context_line":""},{"line_number":2243,"context_line":"def get_inspection_rule(rule_ident):"},{"line_number":2244,"context_line":"    \"\"\"Get the RPC inspection rule by the UUID."},{"line_number":2245,"context_line":""},{"line_number":2246,"context_line":"    :param rule_ident: the UUID of a rule."}],"source_content_type":"text/x-python","patch_set":20,"id":"0ff92088_0d680ee1","line":2243,"in_reply_to":"99ebacb1_81486c08","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8ac093b99d4088b796948d68be69f7677a3739bf","unresolved":true,"context_lines":[{"line_number":12,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":13,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import collections"},{"line_number":17,"context_line":"import copy"},{"line_number":18,"context_line":"from http import client as http_client"}],"source_content_type":"text/x-python","patch_set":29,"id":"3c1159e3_a0addbc9","side":"PARENT","line":15,"updated":"2024-12-11 19:46:31.000000000","message":"unrelated whitespace change?","commit_id":"afd59e3da9780a56e0b633fa131b89bc47cca35e"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"4486962842795d7b78b0e31c452d4af7c867de4c","unresolved":false,"context_lines":[{"line_number":12,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":13,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import collections"},{"line_number":17,"context_line":"import copy"},{"line_number":18,"context_line":"from http import client as http_client"}],"source_content_type":"text/x-python","patch_set":29,"id":"67711826_c1592923","side":"PARENT","line":15,"in_reply_to":"3c1159e3_a0addbc9","updated":"2024-12-14 09:49:05.000000000","message":"Acknowledged","commit_id":"afd59e3da9780a56e0b633fa131b89bc47cca35e"}],"ironic/common/exception.py":[{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":true,"context_lines":[{"line_number":917,"context_line":"    _msg_fmt \u003d _(\"Rule %(uuid)s could not be found.\")"},{"line_number":918,"context_line":""},{"line_number":919,"context_line":""},{"line_number":920,"context_line":"class InvalidImage(ImageUnacceptable):"},{"line_number":921,"context_line":"    _msg_fmt \u003d _(\"The requested image is not valid for use.\")"}],"source_content_type":"text/x-python","patch_set":18,"id":"7bebb67b_78f1a023","line":920,"updated":"2024-09-17 11:41:10.000000000","message":"Lets see if this exception gets used in the full patch, and if we already have an ironic equivalent for it","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d77b316d2ede916f32f502d2d4671d60556781de","unresolved":false,"context_lines":[{"line_number":917,"context_line":"    _msg_fmt \u003d _(\"Rule %(uuid)s could not be found.\")"},{"line_number":918,"context_line":""},{"line_number":919,"context_line":""},{"line_number":920,"context_line":"class InvalidImage(ImageUnacceptable):"},{"line_number":921,"context_line":"    _msg_fmt \u003d _(\"The requested image is not valid for use.\")"}],"source_content_type":"text/x-python","patch_set":18,"id":"bfc17dfb_89125f89","line":920,"in_reply_to":"0b7794c6_a22b69ba","updated":"2024-09-20 09:37:56.000000000","message":"Done","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"f75c78b00f5a99fda0543c9c0bbd1059bf151039","unresolved":true,"context_lines":[{"line_number":917,"context_line":"    _msg_fmt \u003d _(\"Rule %(uuid)s could not be found.\")"},{"line_number":918,"context_line":""},{"line_number":919,"context_line":""},{"line_number":920,"context_line":"class InvalidImage(ImageUnacceptable):"},{"line_number":921,"context_line":"    _msg_fmt \u003d _(\"The requested image is not valid for use.\")"}],"source_content_type":"text/x-python","patch_set":18,"id":"0b7794c6_a22b69ba","line":920,"in_reply_to":"7bebb67b_78f1a023","updated":"2024-09-19 17:53:38.000000000","message":"This is unrelated to this change, it might have snuck in from a merge conflict resolution.","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8ac093b99d4088b796948d68be69f7677a3739bf","unresolved":true,"context_lines":[{"line_number":935,"context_line":""},{"line_number":936,"context_line":"class InspectionRuleAlreadyExists(Conflict):"},{"line_number":937,"context_line":"    \"\"\"Rule requested already exists in the database.\"\"\""},{"line_number":938,"context_line":"    _msg_fmt \u003d _(\"A Rule with UUID %(uuid)s already exists.\")"},{"line_number":939,"context_line":""},{"line_number":940,"context_line":""},{"line_number":941,"context_line":"class InspectionRuleNotFound(NotFound):"}],"source_content_type":"text/x-python","patch_set":29,"id":"f18f526d_8a175172","line":938,"updated":"2024-12-11 19:46:31.000000000","message":"nit: lowercase \"Rule\" -\u003e \"rule\"","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"4486962842795d7b78b0e31c452d4af7c867de4c","unresolved":false,"context_lines":[{"line_number":935,"context_line":""},{"line_number":936,"context_line":"class InspectionRuleAlreadyExists(Conflict):"},{"line_number":937,"context_line":"    \"\"\"Rule requested already exists in the database.\"\"\""},{"line_number":938,"context_line":"    _msg_fmt \u003d _(\"A Rule with UUID %(uuid)s already exists.\")"},{"line_number":939,"context_line":""},{"line_number":940,"context_line":""},{"line_number":941,"context_line":"class InspectionRuleNotFound(NotFound):"}],"source_content_type":"text/x-python","patch_set":29,"id":"123b2bf9_4c7666c1","line":938,"in_reply_to":"f18f526d_8a175172","updated":"2024-12-14 09:49:05.000000000","message":"Acknowledged","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"}],"ironic/common/inspection_rule_plugins.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":25,"id":"9378ad89_324540e2","updated":"2024-11-12 13:23:23.000000000","message":"Code organization: let\u0027s create a new package ironic.common.inspection_rules and put separate modules under it: actions.py with actions, operators.py with operators and engine.py (?) with the rules engine.","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":199,"context_line":"            self(task, action, inventory, plugin_data)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"class SimpleCondition(RuleConditionPlugin):"},{"line_number":203,"context_line":"    op \u003d None"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"    def check(self, node, condition, inventory, plugin_data):"}],"source_content_type":"text/x-python","patch_set":25,"id":"037a5f7e_bdc53436","line":202,"updated":"2024-11-12 13:23:23.000000000","message":"Nit on naming: these are operators, not conditions.","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"}],"ironic/common/inspection_rules.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"_INSPECTION_RULE_CONDITIONS_SCHEMA \u003d None"},{"line_number":33,"context_line":"_INSPECTION_RULE_ACTIONS_SCHEMA \u003d None"},{"line_number":34,"context_line":"VALID_INSPECTION_PHASES \u003d [\u0027early\u0027, \u0027preprocess\u0027, \u0027main\u0027]"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"def _load_plugin(full_name):"}],"source_content_type":"text/x-python","patch_set":25,"id":"cd3c7d18_a54425b2","line":34,"updated":"2024-11-12 13:23:23.000000000","message":"Let\u0027s create named constants (bonus for a Python enum) for each of these.","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":34,"context_line":"VALID_INSPECTION_PHASES \u003d [\u0027early\u0027, \u0027preprocess\u0027, \u0027main\u0027]"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"def _load_plugin(full_name):"},{"line_number":38,"context_line":"    \"\"\"Dynamically load a plugin class.\"\"\""},{"line_number":39,"context_line":"    module_name, class_name \u003d full_name.rsplit(\":\", 1)"},{"line_number":40,"context_line":"    module \u003d importlib.import_module(module_name)"}],"source_content_type":"text/x-python","patch_set":25,"id":"b50bc0e8_5b9b1a45","line":37,"updated":"2024-11-12 13:23:23.000000000","message":"Let\u0027s not do this. There is little point in going through the import machinery for hardcoded conditions. You can literally do things like:\n\n OPERATORS \u003d {\n    \"eq\": operators.EqOp,\n    \"lt\": operators.LtOp,\n }\n \netc","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"dfb6fd874fcb164de1caa01dde9ce8d4a6b5dcfb","unresolved":false,"context_lines":[{"line_number":34,"context_line":"VALID_INSPECTION_PHASES \u003d [\u0027early\u0027, \u0027preprocess\u0027, \u0027main\u0027]"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"def _load_plugin(full_name):"},{"line_number":38,"context_line":"    \"\"\"Dynamically load a plugin class.\"\"\""},{"line_number":39,"context_line":"    module_name, class_name \u003d full_name.rsplit(\":\", 1)"},{"line_number":40,"context_line":"    module \u003d importlib.import_module(module_name)"}],"source_content_type":"text/x-python","patch_set":25,"id":"af87f8fa_3956f21f","line":37,"in_reply_to":"b50bc0e8_5b9b1a45","updated":"2024-11-13 01:16:00.000000000","message":"Acknowledged","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":107,"context_line":"    }"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"def conditions_schema():"},{"line_number":111,"context_line":"    global _INSPECTION_RULE_CONDITIONS_SCHEMA"},{"line_number":112,"context_line":"    if _INSPECTION_RULE_CONDITIONS_SCHEMA is None:"},{"line_number":113,"context_line":"        condition_plugins \u003d [x for x in _get_condition_operators().keys()]"}],"source_content_type":"text/x-python","patch_set":25,"id":"f9ca5bd8_7964f5a1","line":110,"updated":"2024-11-12 13:23:23.000000000","message":"Nit on code organization: the schemas should probably stay within the API","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":110,"context_line":"def conditions_schema():"},{"line_number":111,"context_line":"    global _INSPECTION_RULE_CONDITIONS_SCHEMA"},{"line_number":112,"context_line":"    if _INSPECTION_RULE_CONDITIONS_SCHEMA is None:"},{"line_number":113,"context_line":"        condition_plugins \u003d [x for x in _get_condition_operators().keys()]"},{"line_number":114,"context_line":"        _INSPECTION_RULE_CONDITIONS_SCHEMA \u003d {"},{"line_number":115,"context_line":"            \"title\": \"Inspection rule conditions schema\","},{"line_number":116,"context_line":"            \"type\": \"array\","}],"source_content_type":"text/x-python","patch_set":25,"id":"090da970_baf07e88","line":113,"updated":"2024-11-12 13:23:23.000000000","message":"This is just\n\n list(_get_condition_operators())","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"dfb6fd874fcb164de1caa01dde9ce8d4a6b5dcfb","unresolved":false,"context_lines":[{"line_number":110,"context_line":"def conditions_schema():"},{"line_number":111,"context_line":"    global _INSPECTION_RULE_CONDITIONS_SCHEMA"},{"line_number":112,"context_line":"    if _INSPECTION_RULE_CONDITIONS_SCHEMA is None:"},{"line_number":113,"context_line":"        condition_plugins \u003d [x for x in _get_condition_operators().keys()]"},{"line_number":114,"context_line":"        _INSPECTION_RULE_CONDITIONS_SCHEMA \u003d {"},{"line_number":115,"context_line":"            \"title\": \"Inspection rule conditions schema\","},{"line_number":116,"context_line":"            \"type\": \"array\","}],"source_content_type":"text/x-python","patch_set":25,"id":"56c9a245_e6f2400b","line":113,"in_reply_to":"090da970_baf07e88","updated":"2024-11-13 01:16:00.000000000","message":"Acknowledged","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":147,"context_line":"def actions_schema():"},{"line_number":148,"context_line":"    global _INSPECTION_RULE_ACTIONS_SCHEMA"},{"line_number":149,"context_line":"    if _INSPECTION_RULE_ACTIONS_SCHEMA is None:"},{"line_number":150,"context_line":"        action_plugins \u003d [x for x in _get_action_operators().keys()]"},{"line_number":151,"context_line":"        _INSPECTION_RULE_ACTIONS_SCHEMA \u003d {"},{"line_number":152,"context_line":"            \"title\": \"Inspection rule actions schema\","},{"line_number":153,"context_line":"            \"type\": \"array\","}],"source_content_type":"text/x-python","patch_set":25,"id":"4ff1ca62_b09c67fa","line":150,"updated":"2024-11-12 13:23:23.000000000","message":"list(_get_action_operators())","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"dfb6fd874fcb164de1caa01dde9ce8d4a6b5dcfb","unresolved":false,"context_lines":[{"line_number":147,"context_line":"def actions_schema():"},{"line_number":148,"context_line":"    global _INSPECTION_RULE_ACTIONS_SCHEMA"},{"line_number":149,"context_line":"    if _INSPECTION_RULE_ACTIONS_SCHEMA is None:"},{"line_number":150,"context_line":"        action_plugins \u003d [x for x in _get_action_operators().keys()]"},{"line_number":151,"context_line":"        _INSPECTION_RULE_ACTIONS_SCHEMA \u003d {"},{"line_number":152,"context_line":"            \"title\": \"Inspection rule actions schema\","},{"line_number":153,"context_line":"            \"type\": \"array\","}],"source_content_type":"text/x-python","patch_set":25,"id":"ce57392b_e0515aba","line":150,"in_reply_to":"4ff1ca62_b09c67fa","updated":"2024-11-13 01:16:00.000000000","message":"Acknowledged","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":227,"context_line":"            raise exception.Invalid("},{"line_number":228,"context_line":"                _(\u0027Unsupported condition operator: %s\u0027) % condition[\u0027op\u0027])"},{"line_number":229,"context_line":"        try:"},{"line_number":230,"context_line":"            print(\u0027condition passed to validator: \u0027, condition)"},{"line_number":231,"context_line":"            plugin.validate(condition[\u0027args\u0027])"},{"line_number":232,"context_line":"        except ValueError as exc:"},{"line_number":233,"context_line":"            raise exception.Invalid("}],"source_content_type":"text/x-python","patch_set":25,"id":"b2b94bf7_ad6912ab","line":230,"updated":"2024-11-12 13:23:23.000000000","message":"To be deleted in the final version (other prints below)","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"dfb6fd874fcb164de1caa01dde9ce8d4a6b5dcfb","unresolved":false,"context_lines":[{"line_number":227,"context_line":"            raise exception.Invalid("},{"line_number":228,"context_line":"                _(\u0027Unsupported condition operator: %s\u0027) % condition[\u0027op\u0027])"},{"line_number":229,"context_line":"        try:"},{"line_number":230,"context_line":"            print(\u0027condition passed to validator: \u0027, condition)"},{"line_number":231,"context_line":"            plugin.validate(condition[\u0027args\u0027])"},{"line_number":232,"context_line":"        except ValueError as exc:"},{"line_number":233,"context_line":"            raise exception.Invalid("}],"source_content_type":"text/x-python","patch_set":25,"id":"0dada5b8_b5f27811","line":230,"in_reply_to":"b2b94bf7_ad6912ab","updated":"2024-11-13 01:16:00.000000000","message":"Acknowledged","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":263,"context_line":"        return built_in_rules"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    try:"},{"line_number":266,"context_line":"        path \u003d os.path.join(built_in_rules_dir)"},{"line_number":267,"context_line":"        with open(path, \u0027r\u0027) as f:"},{"line_number":268,"context_line":"            rules_data \u003d yaml.safe_load(f)"},{"line_number":269,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"6f5ae27d_718b14b7","line":266,"updated":"2024-11-12 13:23:23.000000000","message":"Not sure what this does, os.path.join only makes sense with 2+ arguments. Did you intend to list the directory with something like glob.glob?","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":284,"context_line":"                built_in_rules.append(rule)"},{"line_number":285,"context_line":"            except Exception as e:"},{"line_number":286,"context_line":"                LOG.error(_(\"Error parsing built-in rule: %s\"), str(e))"},{"line_number":287,"context_line":"    except FileNotFoundError:"},{"line_number":288,"context_line":"        LOG.error(_(\"Built-in rules file not found: %s\"),"},{"line_number":289,"context_line":"                  built_in_rules_dir)"},{"line_number":290,"context_line":"    except yaml.YAMLError as e:"}],"source_content_type":"text/x-python","patch_set":25,"id":"6bc47a96_6fd32bee","line":287,"updated":"2024-11-12 13:23:23.000000000","message":"These errors should not be silently ignored, we need to refuse to start Ironic in this case. It\u0027s good to log them but we need to propagate the exception further.","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"dfb6fd874fcb164de1caa01dde9ce8d4a6b5dcfb","unresolved":false,"context_lines":[{"line_number":284,"context_line":"                built_in_rules.append(rule)"},{"line_number":285,"context_line":"            except Exception as e:"},{"line_number":286,"context_line":"                LOG.error(_(\"Error parsing built-in rule: %s\"), str(e))"},{"line_number":287,"context_line":"    except FileNotFoundError:"},{"line_number":288,"context_line":"        LOG.error(_(\"Built-in rules file not found: %s\"),"},{"line_number":289,"context_line":"                  built_in_rules_dir)"},{"line_number":290,"context_line":"    except yaml.YAMLError as e:"}],"source_content_type":"text/x-python","patch_set":25,"id":"6370152d_f3ddc15e","line":287,"in_reply_to":"6bc47a96_6fd32bee","updated":"2024-11-13 01:16:00.000000000","message":"Acknowledged","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":297,"context_line":"    return built_in_rules"},{"line_number":298,"context_line":""},{"line_number":299,"context_line":""},{"line_number":300,"context_line":"def check_inspection_rule_condition(task, condition, inventory, plugin_data):"},{"line_number":301,"context_line":"    \"\"\"Check a single condition using the appropriate plugin.\"\"\""},{"line_number":302,"context_line":"    try:"},{"line_number":303,"context_line":"        plugin \u003d _get_condition_operators().get(condition[\u0027op\u0027])"}],"source_content_type":"text/x-python","patch_set":25,"id":"d700e691_3c6dd7b4","line":300,"updated":"2024-11-12 13:23:23.000000000","message":"Note on naming (applies to other functions too): you\u0027re in a module called inspection_rules, you don\u0027t need to repeat inspection_rule in all names. This one could be check_condition, for instance.","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":312,"context_line":"    \"\"\"Apply a single action using the appropriate plugin.\"\"\""},{"line_number":313,"context_line":"    try:"},{"line_number":314,"context_line":"        plugin \u003d _get_action_operators().get(action[\u0027op\u0027])"},{"line_number":315,"context_line":"        if task.node.provision_state \u003d\u003d states.INSPECTING:"},{"line_number":316,"context_line":"            plugin(task, action, inventory, plugin_data)"},{"line_number":317,"context_line":"        else:"},{"line_number":318,"context_line":"            plugin.call_early(action, inventory, plugin_data)"}],"source_content_type":"text/x-python","patch_set":25,"id":"3f881abe_a3439c33","line":315,"updated":"2024-11-12 13:23:23.000000000","message":"It\u0027s always INSPECTING when the rules are called, not sure what the intention is. I think you need to accept the phase as an argument.","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":320,"context_line":"        LOG.error(\"Error applying action: %s\", err)"},{"line_number":321,"context_line":"        raise"},{"line_number":322,"context_line":"    except Exception:"},{"line_number":323,"context_line":"        LOG.exception(\"Unexpected error applying action\")"}],"source_content_type":"text/x-python","patch_set":25,"id":"500b7cec_9260a2da","line":323,"updated":"2024-11-12 13:23:23.000000000","message":"Needs raise","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"dfb6fd874fcb164de1caa01dde9ce8d4a6b5dcfb","unresolved":false,"context_lines":[{"line_number":320,"context_line":"        LOG.error(\"Error applying action: %s\", err)"},{"line_number":321,"context_line":"        raise"},{"line_number":322,"context_line":"    except Exception:"},{"line_number":323,"context_line":"        LOG.exception(\"Unexpected error applying action\")"}],"source_content_type":"text/x-python","patch_set":25,"id":"f260bf1a_fdb0dbbe","line":323,"in_reply_to":"500b7cec_9260a2da","updated":"2024-11-13 01:16:00.000000000","message":"Acknowledged","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"}],"ironic/common/inspection_rules/actions.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":true,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from oslo_log import log"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from ironic.api.controllers.v1 import inspection_rule as insp_rules"},{"line_number":22,"context_line":"from ironic.common import exception"},{"line_number":23,"context_line":"from ironic.common.i18n import _"},{"line_number":24,"context_line":"from ironic.common.inspection_rules import base"}],"source_content_type":"text/x-python","patch_set":43,"id":"3c6f35cf_2314236a","line":21,"updated":"2025-01-02 16:28:09.000000000","message":"The ironic.common layer should not import ironic.api.controllers (it\u0027s usually the other way around). Whatever you need from there should be moved to under ironic.common.inspection_rules.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from oslo_log import log"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from ironic.api.controllers.v1 import inspection_rule as insp_rules"},{"line_number":22,"context_line":"from ironic.common import exception"},{"line_number":23,"context_line":"from ironic.common.i18n import _"},{"line_number":24,"context_line":"from ironic.common.inspection_rules import base"}],"source_content_type":"text/x-python","patch_set":43,"id":"cd305678_d78fe75b","line":21,"in_reply_to":"3c6f35cf_2314236a","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":34,"context_line":"    return d"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"class InspectionRuleActionBase(base.BaseInspectionRule,"},{"line_number":38,"context_line":"                               metaclass\u003dabc.ABCMeta):"},{"line_number":39,"context_line":"    \"\"\"Abstract base class for rule action plugins.\"\"\""},{"line_number":40,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"96a5900d_312ec6d1","line":37,"updated":"2025-01-08 13:32:17.000000000","message":"nit: no need for InspectionRule in class names, the context is clear here","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    return d"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"class InspectionRuleActionBase(base.BaseInspectionRule,"},{"line_number":38,"context_line":"                               metaclass\u003dabc.ABCMeta):"},{"line_number":39,"context_line":"    \"\"\"Abstract base class for rule action plugins.\"\"\""},{"line_number":40,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"eb767338_f12d1822","line":37,"in_reply_to":"96a5900d_312ec6d1","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":39,"context_line":"    \"\"\"Abstract base class for rule action plugins.\"\"\""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    OPTIONAL_ARGS \u003d {\u0027loop\u0027}"},{"line_number":42,"context_line":"    REQUIRED_ARGS \u003d {\u0027op\u0027, \u0027args\u0027}"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    required_keys \u003d {}"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"641b5515_a512805f","line":42,"updated":"2025-01-08 13:32:17.000000000","message":"These are not valid: OPTIONAL_ARGS and REQUIRED_ARGS are components of the \"args\" dictionary (or dictionaries).","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    \"\"\"Abstract base class for rule action plugins.\"\"\""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    OPTIONAL_ARGS \u003d {\u0027loop\u0027}"},{"line_number":42,"context_line":"    REQUIRED_ARGS \u003d {\u0027op\u0027, \u0027args\u0027}"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    required_keys \u003d {}"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"8232bf1a_73505f90","line":42,"in_reply_to":"641b5515_a512805f","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":41,"context_line":"    OPTIONAL_ARGS \u003d {\u0027loop\u0027}"},{"line_number":42,"context_line":"    REQUIRED_ARGS \u003d {\u0027op\u0027, \u0027args\u0027}"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    required_keys \u003d {}"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    formatted_params \u003d []"},{"line_number":47,"context_line":"    \"\"\"List of params to be formatted with python format.\"\"\""}],"source_content_type":"text/x-python","patch_set":43,"id":"29b61ae7_90c83e24","line":44,"updated":"2025-01-08 13:32:17.000000000","message":"Duplicate of REQUIRED_ARGS","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    OPTIONAL_ARGS \u003d {\u0027loop\u0027}"},{"line_number":42,"context_line":"    REQUIRED_ARGS \u003d {\u0027op\u0027, \u0027args\u0027}"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    required_keys \u003d {}"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    formatted_params \u003d []"},{"line_number":47,"context_line":"    \"\"\"List of params to be formatted with python format.\"\"\""}],"source_content_type":"text/x-python","patch_set":43,"id":"f3a2d16a_5cbb8bdc","line":44,"in_reply_to":"29b61ae7_90c83e24","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":51,"context_line":"        raise NotImplementedError"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    @abc.abstractmethod"},{"line_number":54,"context_line":"    def __call__(self, task, action, *args, **kwargs):"},{"line_number":55,"context_line":"        \"\"\"Run action on successful rule match.\"\"\""},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def execute_action(self, task, action, inventory, plugin_data):"}],"source_content_type":"text/x-python","patch_set":43,"id":"4c39636a_a782129d","line":54,"updated":"2025-01-08 13:32:17.000000000","message":"Incorrect signature in both cases: the 3rd argument is the entire \"rule\", not the \"action\"","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        raise NotImplementedError"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    @abc.abstractmethod"},{"line_number":54,"context_line":"    def __call__(self, task, action, *args, **kwargs):"},{"line_number":55,"context_line":"        \"\"\"Run action on successful rule match.\"\"\""},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def execute_action(self, task, action, inventory, plugin_data):"}],"source_content_type":"text/x-python","patch_set":43,"id":"00341c9e_06a1d269","line":54,"in_reply_to":"4c39636a_a782129d","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":70,"context_line":"        processed_args \u003d self._process_args(task.node, inventory, plugin_data,"},{"line_number":71,"context_line":"                                            action\u003daction)"},{"line_number":72,"context_line":"        action[\u0027args\u0027] \u003d processed_args"},{"line_number":73,"context_line":"        return self(task, action, inventory, plugin_data)"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def _execute_with_loop(self, task, action, inventory, plugin_data):"},{"line_number":76,"context_line":"        processed_args \u003d self._process_args(task.node, inventory, plugin_data,"}],"source_content_type":"text/x-python","patch_set":43,"id":"d6fb69d8_3d01f64d","line":73,"updated":"2025-01-08 13:32:17.000000000","message":"You\u0027re not passing *args or **kwargs, instead of action you need to pass the entire rule object (at least per spec - we can discuss)","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":70,"context_line":"        processed_args \u003d self._process_args(task.node, inventory, plugin_data,"},{"line_number":71,"context_line":"                                            action\u003daction)"},{"line_number":72,"context_line":"        action[\u0027args\u0027] \u003d processed_args"},{"line_number":73,"context_line":"        return self(task, action, inventory, plugin_data)"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def _execute_with_loop(self, task, action, inventory, plugin_data):"},{"line_number":76,"context_line":"        processed_args \u003d self._process_args(task.node, inventory, plugin_data,"}],"source_content_type":"text/x-python","patch_set":43,"id":"47b2305d_b02fa24f","line":73,"in_reply_to":"d6fb69d8_3d01f64d","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def _execute_with_loop(self, task, action, inventory, plugin_data):"},{"line_number":76,"context_line":"        processed_args \u003d self._process_args(task.node, inventory, plugin_data,"},{"line_number":77,"context_line":"                                            action\u003daction)"},{"line_number":78,"context_line":"        for item in processed_args:"},{"line_number":79,"context_line":"            args \u003d self._process_args(task.node, inventory, plugin_data,"},{"line_number":80,"context_line":"                                      action\u003daction)"}],"source_content_type":"text/x-python","patch_set":43,"id":"20899f7d_06d86745","line":77,"updated":"2025-01-08 13:32:17.000000000","message":"Here you need to valid that processes_args is actually a list, otherwise you\u0027re going to iterate over keys of a dictionary.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def _execute_with_loop(self, task, action, inventory, plugin_data):"},{"line_number":76,"context_line":"        processed_args \u003d self._process_args(task.node, inventory, plugin_data,"},{"line_number":77,"context_line":"                                            action\u003daction)"},{"line_number":78,"context_line":"        for item in processed_args:"},{"line_number":79,"context_line":"            args \u003d self._process_args(task.node, inventory, plugin_data,"},{"line_number":80,"context_line":"                                      action\u003daction)"}],"source_content_type":"text/x-python","patch_set":43,"id":"ff620b91_ce2a73f4","line":77,"in_reply_to":"20899f7d_06d86745","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":79,"context_line":"            args \u003d self._process_args(task.node, inventory, plugin_data,"},{"line_number":80,"context_line":"                                      action\u003daction)"},{"line_number":81,"context_line":"            action[\u0027args\u0027] \u003d args"},{"line_number":82,"context_line":"            self(task, action, inventory, plugin_data)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"class FailAction(InspectionRuleActionBase):"}],"source_content_type":"text/x-python","patch_set":43,"id":"da0167be_04574978","line":82,"updated":"2025-01-08 13:32:17.000000000","message":"same","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":79,"context_line":"            args \u003d self._process_args(task.node, inventory, plugin_data,"},{"line_number":80,"context_line":"                                      action\u003daction)"},{"line_number":81,"context_line":"            action[\u0027args\u0027] \u003d args"},{"line_number":82,"context_line":"            self(task, action, inventory, plugin_data)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"class FailAction(InspectionRuleActionBase):"}],"source_content_type":"text/x-python","patch_set":43,"id":"4bd4c104_7f3c0d2a","line":82,"in_reply_to":"da0167be_04574978","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":83,"context_line":""},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"class FailAction(InspectionRuleActionBase):"},{"line_number":86,"context_line":"    required_keys \u003d {\u0027msg\u0027}"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def __call__(self, task, action, *args, **kwargs):"},{"line_number":89,"context_line":"        msg \u003d _(\u0027%(msg)s, %(node)s\u0027) % {"}],"source_content_type":"text/x-python","patch_set":43,"id":"6ab8740f_ff269078","line":86,"updated":"2025-01-08 13:32:17.000000000","message":"REQUIRED_ARGS (same below)","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":83,"context_line":""},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"class FailAction(InspectionRuleActionBase):"},{"line_number":86,"context_line":"    required_keys \u003d {\u0027msg\u0027}"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def __call__(self, task, action, *args, **kwargs):"},{"line_number":89,"context_line":"        msg \u003d _(\u0027%(msg)s, %(node)s\u0027) % {"}],"source_content_type":"text/x-python","patch_set":43,"id":"a8828fc7_125149d7","line":86,"in_reply_to":"6ab8740f_ff269078","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":86,"context_line":"    required_keys \u003d {\u0027msg\u0027}"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def __call__(self, task, action, *args, **kwargs):"},{"line_number":89,"context_line":"        msg \u003d _(\u0027%(msg)s, %(node)s\u0027) % {"},{"line_number":90,"context_line":"            \u0027msg\u0027: action[\u0027args\u0027][\u0027msg\u0027], \u0027node\u0027: task.node}"},{"line_number":91,"context_line":"        raise exception.Invalid(msg)"},{"line_number":92,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"4538ed46_c0cca568","line":89,"updated":"2025-01-08 13:32:17.000000000","message":"I don\u0027t think we should include the node UUID here: the higher-level code will catch this exception and convert it into an inspection failure.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":86,"context_line":"    required_keys \u003d {\u0027msg\u0027}"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def __call__(self, task, action, *args, **kwargs):"},{"line_number":89,"context_line":"        msg \u003d _(\u0027%(msg)s, %(node)s\u0027) % {"},{"line_number":90,"context_line":"            \u0027msg\u0027: action[\u0027args\u0027][\u0027msg\u0027], \u0027node\u0027: task.node}"},{"line_number":91,"context_line":"        raise exception.Invalid(msg)"},{"line_number":92,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"419dc274_427bfa2e","line":89,"in_reply_to":"4538ed46_c0cca568","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":95,"context_line":"    formatted_params \u003d [\u0027value\u0027]"},{"line_number":96,"context_line":"    required_keys \u003d {\u0027path\u0027, \u0027value\u0027}"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def __call__(self, task, action, *args, **kwargs):"},{"line_number":99,"context_line":"        path \u003d action[\u0027args\u0027][\u0027path\u0027]"},{"line_number":100,"context_line":"        value \u003d action[\u0027args\u0027][\u0027value\u0027]"},{"line_number":101,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"5cadf5ae_5790bfa0","line":98,"updated":"2025-01-08 13:32:17.000000000","message":"The signature is supposed to be `__call__(self, task, rule, path, value)`\n\nSimilar problem in other actions","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":95,"context_line":"    formatted_params \u003d [\u0027value\u0027]"},{"line_number":96,"context_line":"    required_keys \u003d {\u0027path\u0027, \u0027value\u0027}"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def __call__(self, task, action, *args, **kwargs):"},{"line_number":99,"context_line":"        path \u003d action[\u0027args\u0027][\u0027path\u0027]"},{"line_number":100,"context_line":"        value \u003d action[\u0027args\u0027][\u0027value\u0027]"},{"line_number":101,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"74eac880_d95dbf31","line":98,"in_reply_to":"5cadf5ae_5790bfa0","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"}],"ironic/common/inspection_rules/base.py":[{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8ac093b99d4088b796948d68be69f7677a3739bf","unresolved":true,"context_lines":[{"line_number":16,"context_line":"from ironic.common.i18n import _"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"class BaseInspectionRule:"},{"line_number":20,"context_line":"    @staticmethod"},{"line_number":21,"context_line":"    def interpolate_variables(value, node, inventory, plugin_data):"},{"line_number":22,"context_line":"        if isinstance(value, str):"}],"source_content_type":"text/x-python","patch_set":29,"id":"daf996b9_8dbd9083","line":19,"updated":"2024-12-11 19:46:31.000000000","message":"we should subclass from object or not consistently throughout this file (AIUI this is effectively BaseInspectionRule(object))","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"4486962842795d7b78b0e31c452d4af7c867de4c","unresolved":false,"context_lines":[{"line_number":16,"context_line":"from ironic.common.i18n import _"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"class BaseInspectionRule:"},{"line_number":20,"context_line":"    @staticmethod"},{"line_number":21,"context_line":"    def interpolate_variables(value, node, inventory, plugin_data):"},{"line_number":22,"context_line":"        if isinstance(value, str):"}],"source_content_type":"text/x-python","patch_set":29,"id":"c3571348_58185128","line":19,"in_reply_to":"daf996b9_8dbd9083","updated":"2024-12-14 09:49:05.000000000","message":"Acknowledged","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":true,"context_lines":[{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from ironic.common.i18n import _"},{"line_number":17,"context_line":"from oslo_log import log"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"LOG \u003d log.getLogger(__name__)"}],"source_content_type":"text/x-python","patch_set":43,"id":"7dd1edb6_1327eac4","line":17,"updated":"2025-01-02 16:28:09.000000000","message":"I don\u0027t know why the pep8 job does not complain, but the order of imports is wrong here: 3rd party libraries should be in a separate group from ironic imports.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from ironic.common.i18n import _"},{"line_number":17,"context_line":"from oslo_log import log"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"LOG \u003d log.getLogger(__name__)"}],"source_content_type":"text/x-python","patch_set":43,"id":"c6583b02_8377a5d7","line":17,"in_reply_to":"7dd1edb6_1327eac4","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":32,"context_line":"    \"\"\"Set with names of required args keys.\"\"\""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    @staticmethod"},{"line_number":35,"context_line":"    def parse_inverted_op(op):"},{"line_number":36,"context_line":"        \"\"\"Handle inverted operators.\"\"\""},{"line_number":37,"context_line":"        is_inverted \u003d op.startswith(\u0027!\u0027)"},{"line_number":38,"context_line":"        op \u003d op.lstrip(\u0027!\u0027).strip()"}],"source_content_type":"text/x-python","patch_set":43,"id":"1e74c0fd_cdbfccfe","line":35,"updated":"2025-01-08 13:32:17.000000000","message":"This static method should be just a function somewhere (otherwise, you invoke it in the API code in a very verbose way)","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    \"\"\"Set with names of required args keys.\"\"\""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    @staticmethod"},{"line_number":35,"context_line":"    def parse_inverted_op(op):"},{"line_number":36,"context_line":"        \"\"\"Handle inverted operators.\"\"\""},{"line_number":37,"context_line":"        is_inverted \u003d op.startswith(\u0027!\u0027)"},{"line_number":38,"context_line":"        op \u003d op.lstrip(\u0027!\u0027).strip()"}],"source_content_type":"text/x-python","patch_set":43,"id":"ef58cf99_57fd083b","line":35,"in_reply_to":"1e74c0fd_cdbfccfe","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":35,"context_line":"    def parse_inverted_op(op):"},{"line_number":36,"context_line":"        \"\"\"Handle inverted operators.\"\"\""},{"line_number":37,"context_line":"        is_inverted \u003d op.startswith(\u0027!\u0027)"},{"line_number":38,"context_line":"        op \u003d op.lstrip(\u0027!\u0027).strip()"},{"line_number":39,"context_line":"        return op, is_inverted"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    def validate(self, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":43,"id":"377e6690_f1af25c2","line":38,"updated":"2025-01-08 13:32:17.000000000","message":"Technically, this code allows any number of exclamation marks, not just one. I\u0027d rather prevent that to avoid assumptions of what !! means","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    def parse_inverted_op(op):"},{"line_number":36,"context_line":"        \"\"\"Handle inverted operators.\"\"\""},{"line_number":37,"context_line":"        is_inverted \u003d op.startswith(\u0027!\u0027)"},{"line_number":38,"context_line":"        op \u003d op.lstrip(\u0027!\u0027).strip()"},{"line_number":39,"context_line":"        return op, is_inverted"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    def validate(self, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":43,"id":"36f792dc_ab45d3cc","line":38,"in_reply_to":"377e6690_f1af25c2","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":78,"context_line":"            except (AttributeError, KeyError, ValueError, IndexError,"},{"line_number":79,"context_line":"                    TypeError) as e:"},{"line_number":80,"context_line":"                LOG.warning(\"Interpolation failed due to missing attribute: \""},{"line_number":81,"context_line":"                            \"%s\", e)"},{"line_number":82,"context_line":"                return value"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def _process_args(self, node, inventory, plugin_data, action\u003dNone,"}],"source_content_type":"text/x-python","patch_set":43,"id":"58ce8fa3_36e952fb","line":81,"updated":"2025-01-08 13:32:17.000000000","message":"This is probably not the only possible cause. Let\u0027s at least log `e.__class__.__name__` in addition to just e","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            except (AttributeError, KeyError, ValueError, IndexError,"},{"line_number":79,"context_line":"                    TypeError) as e:"},{"line_number":80,"context_line":"                LOG.warning(\"Interpolation failed due to missing attribute: \""},{"line_number":81,"context_line":"                            \"%s\", e)"},{"line_number":82,"context_line":"                return value"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def _process_args(self, node, inventory, plugin_data, action\u003dNone,"}],"source_content_type":"text/x-python","patch_set":43,"id":"1be3aa50_42cbc3e6","line":81,"in_reply_to":"58ce8fa3_36e952fb","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":92,"context_line":"            args \u003d action.get(\u0027args\u0027)"},{"line_number":93,"context_line":"        elif condition:"},{"line_number":94,"context_line":"            op \u003d condition.get(\u0027op\u0027)"},{"line_number":95,"context_line":"            args \u003d condition.get(\u0027args\u0027)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        if not op:"},{"line_number":98,"context_line":"            msg \u003d \"Either \u0027action\u0027 or \u0027condition\u0027 parameter must be provided.\""}],"source_content_type":"text/x-python","patch_set":43,"id":"fbc8f97d_e4f35559","line":95,"updated":"2025-01-08 13:32:17.000000000","message":"Why not pass one argument for both cases?","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":92,"context_line":"            args \u003d action.get(\u0027args\u0027)"},{"line_number":93,"context_line":"        elif condition:"},{"line_number":94,"context_line":"            op \u003d condition.get(\u0027op\u0027)"},{"line_number":95,"context_line":"            args \u003d condition.get(\u0027args\u0027)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        if not op:"},{"line_number":98,"context_line":"            msg \u003d \"Either \u0027action\u0027 or \u0027condition\u0027 parameter must be provided.\""}],"source_content_type":"text/x-python","patch_set":43,"id":"5770248c_cd2dde9e","line":95,"in_reply_to":"fbc8f97d_e4f35559","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":95,"context_line":"            args \u003d condition.get(\u0027args\u0027)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        if not op:"},{"line_number":98,"context_line":"            msg \u003d \"Either \u0027action\u0027 or \u0027condition\u0027 parameter must be provided.\""},{"line_number":99,"context_line":"            raise ValueError(msg)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"        op, invtd \u003d self.parse_inverted_op(op)"}],"source_content_type":"text/x-python","patch_set":43,"id":"bafa8b6a_b9ce3fba","line":98,"updated":"2025-01-08 13:32:17.000000000","message":"... then you won\u0027t need this","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":95,"context_line":"            args \u003d condition.get(\u0027args\u0027)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        if not op:"},{"line_number":98,"context_line":"            msg \u003d \"Either \u0027action\u0027 or \u0027condition\u0027 parameter must be provided.\""},{"line_number":99,"context_line":"            raise ValueError(msg)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"        op, invtd \u003d self.parse_inverted_op(op)"}],"source_content_type":"text/x-python","patch_set":43,"id":"51d51033_7ee9b1b4","line":98,"in_reply_to":"bafa8b6a_b9ce3fba","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":101,"context_line":"        op, invtd \u003d self.parse_inverted_op(op)"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"        if isinstance(args, list):"},{"line_number":104,"context_line":"            if op in [\u0027is-true\u0027, \u0027is-false\u0027, \u0027is-none\u0027, \u0027is-empty\u0027]:"},{"line_number":105,"context_line":"                args \u003d {\"value\": args[0] if len(args) \u003e 0 else None}"},{"line_number":106,"context_line":"            elif op in [\u0027eq\u0027, \u0027lt\u0027, \u0027gt\u0027]:"},{"line_number":107,"context_line":"                args \u003d {\"values\": args}"}],"source_content_type":"text/x-python","patch_set":43,"id":"d215316a_ea1ab858","line":104,"updated":"2025-01-08 13:32:17.000000000","message":"Could you codify this logic in operators or conditions themselves rather than maintaining a complete list here? I.e. it seems to be a job for the child class.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":101,"context_line":"        op, invtd \u003d self.parse_inverted_op(op)"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"        if isinstance(args, list):"},{"line_number":104,"context_line":"            if op in [\u0027is-true\u0027, \u0027is-false\u0027, \u0027is-none\u0027, \u0027is-empty\u0027]:"},{"line_number":105,"context_line":"                args \u003d {\"value\": args[0] if len(args) \u003e 0 else None}"},{"line_number":106,"context_line":"            elif op in [\u0027eq\u0027, \u0027lt\u0027, \u0027gt\u0027]:"},{"line_number":107,"context_line":"                args \u003d {\"values\": args}"}],"source_content_type":"text/x-python","patch_set":43,"id":"34d9f0e1_501d994d","line":104,"in_reply_to":"d215316a_ea1ab858","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":133,"context_line":"                    \"value\": args[2] if len(args) \u003e 2 else None"},{"line_number":134,"context_line":"                }"},{"line_number":135,"context_line":"            else:"},{"line_number":136,"context_line":"                raise ValueError(\u0027Unsupported operator %s\u0027, op)"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"        provided_arg_keys \u003d {k for k in args.keys()}"},{"line_number":139,"context_line":"        missing_keys \u003d self.required_keys - provided_arg_keys"}],"source_content_type":"text/x-python","patch_set":43,"id":"db9ab145_69ffa4c6","line":136,"updated":"2025-01-08 13:32:17.000000000","message":"Also a user-visible message","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":133,"context_line":"                    \"value\": args[2] if len(args) \u003e 2 else None"},{"line_number":134,"context_line":"                }"},{"line_number":135,"context_line":"            else:"},{"line_number":136,"context_line":"                raise ValueError(\u0027Unsupported operator %s\u0027, op)"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"        provided_arg_keys \u003d {k for k in args.keys()}"},{"line_number":139,"context_line":"        missing_keys \u003d self.required_keys - provided_arg_keys"}],"source_content_type":"text/x-python","patch_set":43,"id":"df0ed192_e4f6295d","line":136,"in_reply_to":"db9ab145_69ffa4c6","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":143,"context_line":"                             \", \".join(missing_keys))"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        return {k: self.interpolate_variables("},{"line_number":146,"context_line":"            v, node, inventory, plugin_data) for k, v in args.items()}"}],"source_content_type":"text/x-python","patch_set":43,"id":"28085be4_dc88be34","line":146,"updated":"2025-01-08 13:32:17.000000000","message":"IIRC only the ones from `formatted_params` (which I guess I should have called `formatted_args`) should be formatted","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":143,"context_line":"                             \", \".join(missing_keys))"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        return {k: self.interpolate_variables("},{"line_number":146,"context_line":"            v, node, inventory, plugin_data) for k, v in args.items()}"}],"source_content_type":"text/x-python","patch_set":43,"id":"86806066_7007cfc9","line":146,"in_reply_to":"28085be4_dc88be34","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"}],"ironic/common/inspection_rules/engine.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":true,"context_lines":[{"line_number":16,"context_line":"import os"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo_log import log"},{"line_number":19,"context_line":"import yaml"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from ironic.api.controllers.v1 import inspection_rule as insp_rules"},{"line_number":22,"context_line":"from ironic.common import exception"}],"source_content_type":"text/x-python","patch_set":43,"id":"4f2bd10a_767d3934","line":19,"updated":"2025-01-02 16:28:09.000000000","message":"pyyaml is not currently a direct dependency and needs to be added to requirements.txt","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":16,"context_line":"import os"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo_log import log"},{"line_number":19,"context_line":"import yaml"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from ironic.api.controllers.v1 import inspection_rule as insp_rules"},{"line_number":22,"context_line":"from ironic.common import exception"}],"source_content_type":"text/x-python","patch_set":43,"id":"cb1b1bc0_a9bd2bed","line":19,"in_reply_to":"4f2bd10a_767d3934","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":true,"context_lines":[{"line_number":18,"context_line":"from oslo_log import log"},{"line_number":19,"context_line":"import yaml"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from ironic.api.controllers.v1 import inspection_rule as insp_rules"},{"line_number":22,"context_line":"from ironic.common import exception"},{"line_number":23,"context_line":"from ironic.common.i18n import _"},{"line_number":24,"context_line":"from ironic.conf import CONF"}],"source_content_type":"text/x-python","patch_set":43,"id":"72194cba_2f043f5f","line":21,"updated":"2025-01-02 16:28:09.000000000","message":"Same","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from oslo_log import log"},{"line_number":19,"context_line":"import yaml"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from ironic.api.controllers.v1 import inspection_rule as insp_rules"},{"line_number":22,"context_line":"from ironic.common import exception"},{"line_number":23,"context_line":"from ironic.common.i18n import _"},{"line_number":24,"context_line":"from ironic.conf import CONF"}],"source_content_type":"text/x-python","patch_set":43,"id":"14e75371_94dd6b16","line":21,"in_reply_to":"72194cba_2f043f5f","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":36,"context_line":"        return built_in_rules"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    try:"},{"line_number":39,"context_line":"        path \u003d os.path.join(built_in_rules_dir)"},{"line_number":40,"context_line":"        with open(path, \u0027r\u0027) as f:"},{"line_number":41,"context_line":"            rules_data \u003d yaml.safe_load(f)"},{"line_number":42,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"6f2a1310_467a536d","line":39,"updated":"2025-01-08 13:32:17.000000000","message":"Passing 1 argument to os.path.join never makes sense. Did you intend to use glob.glob or something like that to iterate on files there?","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        return built_in_rules"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    try:"},{"line_number":39,"context_line":"        path \u003d os.path.join(built_in_rules_dir)"},{"line_number":40,"context_line":"        with open(path, \u0027r\u0027) as f:"},{"line_number":41,"context_line":"            rules_data \u003d yaml.safe_load(f)"},{"line_number":42,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"82a1b72e_596e3271","line":39,"in_reply_to":"6f2a1310_467a536d","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":55,"context_line":"                }"},{"line_number":56,"context_line":"                insp_rules.validate_inspection_rule(rule)"},{"line_number":57,"context_line":"                built_in_rules.append(rule)"},{"line_number":58,"context_line":"            except Exception as e:"},{"line_number":59,"context_line":"                LOG.error(_(\"Error parsing built-in rule: %s\"), str(e))"},{"line_number":60,"context_line":"    except FileNotFoundError:"},{"line_number":61,"context_line":"        LOG.error(_(\"Built-in rules file not found: %s\"),"}],"source_content_type":"text/x-python","patch_set":43,"id":"e4332f6c_62eba264","line":58,"updated":"2025-01-08 13:32:17.000000000","message":"This exception is now silenced, is it intentional? I think it should be propagated too.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":55,"context_line":"                }"},{"line_number":56,"context_line":"                insp_rules.validate_inspection_rule(rule)"},{"line_number":57,"context_line":"                built_in_rules.append(rule)"},{"line_number":58,"context_line":"            except Exception as e:"},{"line_number":59,"context_line":"                LOG.error(_(\"Error parsing built-in rule: %s\"), str(e))"},{"line_number":60,"context_line":"    except FileNotFoundError:"},{"line_number":61,"context_line":"        LOG.error(_(\"Built-in rules file not found: %s\"),"}],"source_content_type":"text/x-python","patch_set":43,"id":"f7db1830_db64aaff","line":58,"in_reply_to":"e4332f6c_62eba264","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":true,"context_lines":[{"line_number":56,"context_line":"                insp_rules.validate_inspection_rule(rule)"},{"line_number":57,"context_line":"                built_in_rules.append(rule)"},{"line_number":58,"context_line":"            except Exception as e:"},{"line_number":59,"context_line":"                LOG.error(_(\"Error parsing built-in rule: %s\"), str(e))"},{"line_number":60,"context_line":"    except FileNotFoundError:"},{"line_number":61,"context_line":"        LOG.error(_(\"Built-in rules file not found: %s\"),"},{"line_number":62,"context_line":"                  built_in_rules_dir)"}],"source_content_type":"text/x-python","patch_set":43,"id":"36eadea0_588114b0","line":59,"updated":"2025-01-02 16:28:09.000000000","message":"nit: str() is not needed (implied by %s), also _() is not needed for log messages (we only translate user-visible strings). Same below","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":56,"context_line":"                insp_rules.validate_inspection_rule(rule)"},{"line_number":57,"context_line":"                built_in_rules.append(rule)"},{"line_number":58,"context_line":"            except Exception as e:"},{"line_number":59,"context_line":"                LOG.error(_(\"Error parsing built-in rule: %s\"), str(e))"},{"line_number":60,"context_line":"    except FileNotFoundError:"},{"line_number":61,"context_line":"        LOG.error(_(\"Built-in rules file not found: %s\"),"},{"line_number":62,"context_line":"                  built_in_rules_dir)"}],"source_content_type":"text/x-python","patch_set":43,"id":"892477b3_ca13cf67","line":59,"in_reply_to":"36eadea0_588114b0","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":73,"context_line":"    return built_in_rules"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"def check_inspection_rule_condition(task, condition, inventory, plugin_data):"},{"line_number":77,"context_line":"    \"\"\"Check a single condition using the appropriate plugin.\"\"\""},{"line_number":78,"context_line":"    try:"},{"line_number":79,"context_line":"        op, invtd \u003d ("}],"source_content_type":"text/x-python","patch_set":43,"id":"b20df5c9_f751f706","line":76,"updated":"2025-01-08 13:32:17.000000000","message":"nit: There is no need to duplicate \"inspection_rule\" in function names: we\u0027re already in the package called ironic.common.inspection_rules","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":73,"context_line":"    return built_in_rules"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"def check_inspection_rule_condition(task, condition, inventory, plugin_data):"},{"line_number":77,"context_line":"    \"\"\"Check a single condition using the appropriate plugin.\"\"\""},{"line_number":78,"context_line":"    try:"},{"line_number":79,"context_line":"        op, invtd \u003d ("}],"source_content_type":"text/x-python","patch_set":43,"id":"abd952e4_72de2141","line":76,"in_reply_to":"b20df5c9_f751f706","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"}],"ironic/common/inspection_rules/operators.py":[{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8ac093b99d4088b796948d68be69f7677a3739bf","unresolved":true,"context_lines":[{"line_number":151,"context_line":"        try:"},{"line_number":152,"context_line":"            netaddr.IPNetwork(args[\u0027value\u0027])"},{"line_number":153,"context_line":"        except netaddr.AddrFormatError as exc:"},{"line_number":154,"context_line":"            raise ValueError(\u0027invalid value: %s\u0027 % exc)"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    def check(self, condition, *args, **kwargs):"},{"line_number":157,"context_line":"        network \u003d netaddr.IPNetwork(condition.args[\u0027value\u0027])"}],"source_content_type":"text/x-python","patch_set":29,"id":"6f02fb87_9c97fc74","line":154,"updated":"2024-12-11 19:46:31.000000000","message":"This is not a error we can expose to the user; is it being caught above this?","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"565dd44cf708e98acd1bd17c35de29e782f41bfa","unresolved":false,"context_lines":[{"line_number":151,"context_line":"        try:"},{"line_number":152,"context_line":"            netaddr.IPNetwork(args[\u0027value\u0027])"},{"line_number":153,"context_line":"        except netaddr.AddrFormatError as exc:"},{"line_number":154,"context_line":"            raise ValueError(\u0027invalid value: %s\u0027 % exc)"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    def check(self, condition, *args, **kwargs):"},{"line_number":157,"context_line":"        network \u003d netaddr.IPNetwork(condition.args[\u0027value\u0027])"}],"source_content_type":"text/x-python","patch_set":29,"id":"d0a54d99_31853ffd","line":154,"in_reply_to":"6f02fb87_9c97fc74","updated":"2024-12-16 08:08:19.000000000","message":"Acknowledged","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":true,"context_lines":[{"line_number":17,"context_line":"import operator"},{"line_number":18,"context_line":"import re"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"import netaddr"},{"line_number":21,"context_line":"from oslo_log import log"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"from ironic.api.controllers.v1 import inspection_rule as insp_rules"}],"source_content_type":"text/x-python","patch_set":43,"id":"76d8e13d_a63ffc08","line":20,"updated":"2025-01-02 16:28:09.000000000","message":"(Can be done in a follow-up if you prefer) netaddr is not maintained any more, we should replace it with something else","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":true,"context_lines":[{"line_number":20,"context_line":"import netaddr"},{"line_number":21,"context_line":"from oslo_log import log"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"from ironic.api.controllers.v1 import inspection_rule as insp_rules"},{"line_number":24,"context_line":"from ironic.common.i18n import _"},{"line_number":25,"context_line":"from ironic.common.inspection_rules import base"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"f5812bdf_059889a9","line":23,"updated":"2025-01-02 16:28:09.000000000","message":"same re importing api.controllers","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":20,"context_line":"import netaddr"},{"line_number":21,"context_line":"from oslo_log import log"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"from ironic.api.controllers.v1 import inspection_rule as insp_rules"},{"line_number":24,"context_line":"from ironic.common.i18n import _"},{"line_number":25,"context_line":"from ironic.common.inspection_rules import base"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"12ec08b5_6ddd43d6","line":23,"in_reply_to":"f5812bdf_059889a9","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"}],"ironic/common/plugins.py":[{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":106,"context_line":"    def check(self, node_info, field, params, **kwargs):"},{"line_number":107,"context_line":"        \"\"\"Check if condition holds for a given field."},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        :param node_info: NodeInfo object"},{"line_number":110,"context_line":"        :param field: field value"},{"line_number":111,"context_line":"        :param params: parameters as a dictionary, changing it here will change"},{"line_number":112,"context_line":"                       what will be stored in database"}],"source_content_type":"text/x-python","patch_set":15,"id":"e42427a0_56e64271","line":109,"updated":"2024-09-12 10:36:13.000000000","message":"I highly suspect that we don\u0027t have the NodeInfo object in ironic (this was part of Inspector), and here we will just use Node directly.","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"4cb2f4f605fcdbb84bdd27939ce1a26db1a261e8","unresolved":false,"context_lines":[{"line_number":106,"context_line":"    def check(self, node_info, field, params, **kwargs):"},{"line_number":107,"context_line":"        \"\"\"Check if condition holds for a given field."},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        :param node_info: NodeInfo object"},{"line_number":110,"context_line":"        :param field: field value"},{"line_number":111,"context_line":"        :param params: parameters as a dictionary, changing it here will change"},{"line_number":112,"context_line":"                       what will be stored in database"}],"source_content_type":"text/x-python","patch_set":15,"id":"3ccb049e_77f9fbde","line":109,"in_reply_to":"2d1a9c52_ed5ccb00","updated":"2024-09-26 12:02:27.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":true,"context_lines":[{"line_number":106,"context_line":"    def check(self, node_info, field, params, **kwargs):"},{"line_number":107,"context_line":"        \"\"\"Check if condition holds for a given field."},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        :param node_info: NodeInfo object"},{"line_number":110,"context_line":"        :param field: field value"},{"line_number":111,"context_line":"        :param params: parameters as a dictionary, changing it here will change"},{"line_number":112,"context_line":"                       what will be stored in database"}],"source_content_type":"text/x-python","patch_set":15,"id":"2d1a9c52_ed5ccb00","line":109,"in_reply_to":"e42427a0_56e64271","updated":"2024-09-17 11:41:10.000000000","message":"Just the param description needs to be updated as well 😊","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":true,"context_lines":[{"line_number":126,"context_line":"    def apply(self, node, args, **kwargs):"},{"line_number":127,"context_line":"        \"\"\"Run action on successful rule match."},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        :param node: NodeInfo object"},{"line_number":130,"context_line":"        :param args: parameters as a dictionary"},{"line_number":131,"context_line":"        :param kwargs: used for extensibility without breaking existing plugins"},{"line_number":132,"context_line":"        :raises: Invalid on failure"}],"source_content_type":"text/x-python","patch_set":18,"id":"2407e8a9_374e6eeb","line":129,"updated":"2024-09-17 11:41:10.000000000","message":"Same here","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"4cb2f4f605fcdbb84bdd27939ce1a26db1a261e8","unresolved":false,"context_lines":[{"line_number":126,"context_line":"    def apply(self, node, args, **kwargs):"},{"line_number":127,"context_line":"        \"\"\"Run action on successful rule match."},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        :param node: NodeInfo object"},{"line_number":130,"context_line":"        :param args: parameters as a dictionary"},{"line_number":131,"context_line":"        :param kwargs: used for extensibility without breaking existing plugins"},{"line_number":132,"context_line":"        :raises: Invalid on failure"}],"source_content_type":"text/x-python","patch_set":18,"id":"fa1268ac_714540b7","line":129,"in_reply_to":"2407e8a9_374e6eeb","updated":"2024-09-26 12:02:27.000000000","message":"Done","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":true,"context_lines":[{"line_number":241,"context_line":"            # TODO(dtantsur): remove support for old ironicclient and Queens"},{"line_number":242,"context_line":"            if \u0027reset_interfaces\u0027 in args:"},{"line_number":243,"context_line":"                # An explicit request, report an error."},{"line_number":244,"context_line":"                raise exception.Invalid("},{"line_number":245,"context_line":"                    _(\u0027Cannot pass reset_interfaces to set-attribute, \u0027"},{"line_number":246,"context_line":"                      \u0027requires API 1.46 and ironicclient \u003e\u003d 2.5.0\u0027))"},{"line_number":247,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"44298b1d_e8d28ef4","line":244,"updated":"2024-09-17 11:41:10.000000000","message":"Inspection rules support is being added in the latest API version in this patch, so this might no longer be valid IIUC","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":20,"id":"97dc0a76_026f766b","updated":"2024-09-26 15:27:50.000000000","message":"This file should be named more specific (e.g. inspection_rules).","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":114,"context_line":"        :returns: True if check succeeded, otherwise False"},{"line_number":115,"context_line":"        \"\"\""},{"line_number":116,"context_line":""},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"class RuleActionPlugin(WithValidation, metaclass\u003dabc.ABCMeta):  # pragma: no cover # noqa"},{"line_number":119,"context_line":"    \"\"\"Abstract base class for rule action plugins.\"\"\""},{"line_number":120,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"2cda9d0f_44a31631","line":117,"updated":"2024-09-26 15:27:50.000000000","message":"The classes here don\u0027t seem to follow the spec: https://specs.openstack.org/openstack/ironic-specs/specs/not-implemented/inspection-rules.html#developer-impact","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"}],"ironic/common/policy.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":2018,"context_line":"rule_policies \u003d ["},{"line_number":2019,"context_line":"    policy.DocumentedRuleDefault("},{"line_number":2020,"context_line":"        name\u003d\u0027baremetal:inspection_rule:get\u0027,"},{"line_number":2021,"context_line":"        check_str\u003dADMIN,"},{"line_number":2022,"context_line":"        description\u003d\u0027Get inspection rule(s)\u0027,"},{"line_number":2023,"context_line":"        operations\u003d[{\u0027path\u0027: \u0027/rules\u0027, \u0027method\u0027: \u0027GET\u0027},"},{"line_number":2024,"context_line":"                    {\u0027path\u0027: \u0027/rules/{rule_id}\u0027, \u0027method\u0027: \u0027GET\u0027}],"}],"source_content_type":"text/x-python","patch_set":20,"id":"0dd78666_5b4f883a","line":2021,"updated":"2024-09-26 15:27:50.000000000","message":"This has to be SYSTEM_READER","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":2018,"context_line":"rule_policies \u003d ["},{"line_number":2019,"context_line":"    policy.DocumentedRuleDefault("},{"line_number":2020,"context_line":"        name\u003d\u0027baremetal:inspection_rule:get\u0027,"},{"line_number":2021,"context_line":"        check_str\u003dADMIN,"},{"line_number":2022,"context_line":"        description\u003d\u0027Get inspection rule(s)\u0027,"},{"line_number":2023,"context_line":"        operations\u003d[{\u0027path\u0027: \u0027/rules\u0027, \u0027method\u0027: \u0027GET\u0027},"},{"line_number":2024,"context_line":"                    {\u0027path\u0027: \u0027/rules/{rule_id}\u0027, \u0027method\u0027: \u0027GET\u0027}],"}],"source_content_type":"text/x-python","patch_set":20,"id":"213581ec_786041ac","line":2021,"in_reply_to":"0dd78666_5b4f883a","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":2025,"context_line":"    ),"},{"line_number":2026,"context_line":"    policy.DocumentedRuleDefault("},{"line_number":2027,"context_line":"        name\u003d\u0027baremetal:inspection_rule:create\u0027,"},{"line_number":2028,"context_line":"        check_str\u003dADMIN,"},{"line_number":2029,"context_line":"        description\u003d\u0027Create inspection rule\u0027,"},{"line_number":2030,"context_line":"        operations\u003d[{\u0027path\u0027: \u0027/rules\u0027, \u0027method\u0027: \u0027POST\u0027}],"},{"line_number":2031,"context_line":"    ),"}],"source_content_type":"text/x-python","patch_set":20,"id":"22d5397f_ce8e8401","line":2028,"updated":"2024-09-26 15:27:50.000000000","message":"And these two SYSTEM_ADMIN. I\u0027m not sure why you need the new ADMIN (and I\u0027m not sure it\u0027s correct).","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":2025,"context_line":"    ),"},{"line_number":2026,"context_line":"    policy.DocumentedRuleDefault("},{"line_number":2027,"context_line":"        name\u003d\u0027baremetal:inspection_rule:create\u0027,"},{"line_number":2028,"context_line":"        check_str\u003dADMIN,"},{"line_number":2029,"context_line":"        description\u003d\u0027Create inspection rule\u0027,"},{"line_number":2030,"context_line":"        operations\u003d[{\u0027path\u0027: \u0027/rules\u0027, \u0027method\u0027: \u0027POST\u0027}],"},{"line_number":2031,"context_line":"    ),"}],"source_content_type":"text/x-python","patch_set":20,"id":"c8220ccc_942a78e5","line":2028,"in_reply_to":"22d5397f_ce8e8401","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"}],"ironic/common/utils.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":707,"context_line":"    return USING_SQLITE"},{"line_number":708,"context_line":""},{"line_number":709,"context_line":""},{"line_number":710,"context_line":"def is_supported_inspect_interface(inspect_interface):"},{"line_number":711,"context_line":"    pattern \u003d CONF.inspection_rules.supported_interfaces"},{"line_number":712,"context_line":"    return re.match(pattern, inspect_interface) is not None"}],"source_content_type":"text/x-python","patch_set":25,"id":"f016ee1f_7dc16446","line":710,"updated":"2024-11-12 13:23:23.000000000","message":"You have the same function in inspection_rules.py where it belongs","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"}],"ironic/conductor/inspection.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":125,"context_line":"        inspection_rules.apply_rules(task, inventory, plugin_data,"},{"line_number":126,"context_line":"                                     \u0027early\u0027)"},{"line_number":127,"context_line":"        inspection_rules.apply_rules(task, inventory, plugin_data,"},{"line_number":128,"context_line":"                                     \u0027preprocess\u0027)"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"        result \u003d task.driver.inspect.continue_inspection("},{"line_number":131,"context_line":"            task, inventory, plugin_data)"}],"source_content_type":"text/x-python","patch_set":25,"id":"f4dea933_55a82c72","line":128,"updated":"2024-11-12 13:23:23.000000000","message":"The process phase cannot happen here because the difference between preprocess and main phases only exists inside the inspection implementation. I\u0027m all for having the early phase where it is, probably the main too. But the preprocess phase has to migrate into the driver (which makes me wonder if all phases have to be handled there - just for consistency).","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"}],"ironic/conductor/inspection_rules.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"cb2da71a83e41182b8b757a166dc941e8470318b","unresolved":true,"context_lines":[{"line_number":35,"context_line":"              {\u0027count\u0027: len(rules), \u0027node\u0027: node.uuid})"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    for rule in rules:"},{"line_number":38,"context_line":"        if rule.phase and rule.phase !\u003d node.provision_state:"},{"line_number":39,"context_line":"            LOG.debug(\"Skipping rule %(rule)s due to phase mismatch: \""},{"line_number":40,"context_line":"                      \"%(rule_phase)s !\u003d %(node_phase)s\","},{"line_number":41,"context_line":"                      {\u0027rule\u0027: rule.uuid, \u0027rule_phase\u0027: rule.phase,"}],"source_content_type":"text/x-python","patch_set":20,"id":"cf8e496a_3869a59a","line":38,"updated":"2024-09-26 15:29:17.000000000","message":"Phase is not a provision state: https://specs.openstack.org/openstack/ironic-specs/specs/not-implemented/inspection-rules.html#proposed-change. You probably need to accept a phase as an argument.\n\nyou need to check the scope here","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":25,"id":"bf51d1a7_8c9d4fcf","updated":"2024-11-12 13:23:23.000000000","message":"Note on organization: if you create ironic.common.inspection_rules package as I suggested, this file should be moved there out of ironic.conductor. Maybe it should become the engine.py I referred to earlier. It does not use anything from ironic.conductor though.","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":74,"context_line":"    # NOTE(cid): For auto-discovered nodes, use the auto-discovery inspection"},{"line_number":75,"context_line":"    # scope, or, fall back to the node\u0027s properties if available."},{"line_number":76,"context_line":"    if (CONF.auto_discovery.enabled"},{"line_number":77,"context_line":"        and \u0027inspection_scope\u0027 in CONF.auto_discovery):"},{"line_number":78,"context_line":"        node_scope \u003d CONF.auto_discovery.inspection_scope"},{"line_number":79,"context_line":"    node_scope \u003d node_scope or node.properties.get(\u0027inspection_scope\u0027)"},{"line_number":80,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"f686558d_ff6100ae","line":77,"updated":"2024-11-12 13:23:23.000000000","message":"You don\u0027t need to check this: configuration options always exist if defined.","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"dfb6fd874fcb164de1caa01dde9ce8d4a6b5dcfb","unresolved":false,"context_lines":[{"line_number":74,"context_line":"    # NOTE(cid): For auto-discovered nodes, use the auto-discovery inspection"},{"line_number":75,"context_line":"    # scope, or, fall back to the node\u0027s properties if available."},{"line_number":76,"context_line":"    if (CONF.auto_discovery.enabled"},{"line_number":77,"context_line":"        and \u0027inspection_scope\u0027 in CONF.auto_discovery):"},{"line_number":78,"context_line":"        node_scope \u003d CONF.auto_discovery.inspection_scope"},{"line_number":79,"context_line":"    node_scope \u003d node_scope or node.properties.get(\u0027inspection_scope\u0027)"},{"line_number":80,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"f98c4054_61bed4fd","line":77,"in_reply_to":"f686558d_ff6100ae","updated":"2024-11-13 01:16:00.000000000","message":"Acknowledged","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    for rule in rules:"},{"line_number":82,"context_line":"        rule_scope \u003d rule[\u0027scope\u0027]"},{"line_number":83,"context_line":"        if not rule[\u0027built_in\u0027]:"},{"line_number":84,"context_line":"            rule_scope \u003d rule[\u0027scope\u0027] or default_scope"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"        if rule_scope and (not node_scope or rule[\u0027scope\u0027] !\u003d node_scope):"}],"source_content_type":"text/x-python","patch_set":25,"id":"d663cadc_32de912d","line":83,"updated":"2024-11-12 13:23:23.000000000","message":"I think default_scope should apply to all rules, built-in or not.","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"ee5c1ab1c66f067fb478906f6055bee777770324","unresolved":false,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    for rule in rules:"},{"line_number":82,"context_line":"        rule_scope \u003d rule[\u0027scope\u0027]"},{"line_number":83,"context_line":"        if not rule[\u0027built_in\u0027]:"},{"line_number":84,"context_line":"            rule_scope \u003d rule[\u0027scope\u0027] or default_scope"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"        if rule_scope and (not node_scope or rule[\u0027scope\u0027] !\u003d node_scope):"}],"source_content_type":"text/x-python","patch_set":25,"id":"8276b6e4_34921cbc","line":83,"in_reply_to":"85911d2e_94291322","updated":"2024-11-12 14:33:29.000000000","message":"Hmm, I assume I had reasons to explicitly write it this way... If only I remembered them :D Okay, let\u0027s leave it this way.","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"f4190539841e8fbd1ad98d4d14c5fb14dfae52c2","unresolved":true,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    for rule in rules:"},{"line_number":82,"context_line":"        rule_scope \u003d rule[\u0027scope\u0027]"},{"line_number":83,"context_line":"        if not rule[\u0027built_in\u0027]:"},{"line_number":84,"context_line":"            rule_scope \u003d rule[\u0027scope\u0027] or default_scope"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"        if rule_scope and (not node_scope or rule[\u0027scope\u0027] !\u003d node_scope):"}],"source_content_type":"text/x-python","patch_set":25,"id":"85911d2e_94291322","line":83,"in_reply_to":"d663cadc_32de912d","updated":"2024-11-12 13:52:45.000000000","message":"This was adhering to this part of the spec: ``default_scope`` IS The default value for scope for all rules where this field is not set (excluding built-in ones).","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":92,"context_line":"        try:"},{"line_number":93,"context_line":"            if all(insp_rules.check_inspection_rule_condition("},{"line_number":94,"context_line":"                task, condition, inventory, plugin_data"},{"line_number":95,"context_line":"            ) for condition in rule[\u0027conditions\u0027]):"},{"line_number":96,"context_line":"                LOG.info(\"Applying actions for rule %(rule)s to node %(node)s\","},{"line_number":97,"context_line":"                         {\u0027rule\u0027: rule[\u0027uuid\u0027], \u0027node\u0027: node.uuid})"},{"line_number":98,"context_line":"                for action in rule[\u0027actions\u0027]:"}],"source_content_type":"text/x-python","patch_set":25,"id":"f7385d7f_bc0db518","line":95,"updated":"2024-11-12 13:23:23.000000000","message":"nit: it would be useful to log which condition did not match (unless we already do it inside check_inspection_rule_condition)","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"dfb6fd874fcb164de1caa01dde9ce8d4a6b5dcfb","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        try:"},{"line_number":93,"context_line":"            if all(insp_rules.check_inspection_rule_condition("},{"line_number":94,"context_line":"                task, condition, inventory, plugin_data"},{"line_number":95,"context_line":"            ) for condition in rule[\u0027conditions\u0027]):"},{"line_number":96,"context_line":"                LOG.info(\"Applying actions for rule %(rule)s to node %(node)s\","},{"line_number":97,"context_line":"                         {\u0027rule\u0027: rule[\u0027uuid\u0027], \u0027node\u0027: node.uuid})"},{"line_number":98,"context_line":"                for action in rule[\u0027actions\u0027]:"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a71a2c9_0962dee5","line":95,"in_reply_to":"f7385d7f_bc0db518","updated":"2024-11-13 01:16:00.000000000","message":"Acknowledged","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":107,"context_line":"                LOG.error(\"Error applying rule %(rule)s to node \""},{"line_number":108,"context_line":"                          \"%(node)s: %(error)s\","},{"line_number":109,"context_line":"                          {\u0027rule\u0027: rule[\u0027uuid\u0027], \u0027node\u0027: node.uuid,"},{"line_number":110,"context_line":"                           \u0027error\u0027: str(e)})"},{"line_number":111,"context_line":"        except Exception as e:"},{"line_number":112,"context_line":"            LOG.exception(\"Unexpected error %(error)s applying rule %(rule)s \""},{"line_number":113,"context_line":"                          \"to node %(node)s\", {\u0027rule\u0027: rule[\u0027uuid\u0027],"}],"source_content_type":"text/x-python","patch_set":25,"id":"e7184000_90c7cd74","line":110,"updated":"2024-11-12 13:23:23.000000000","message":"nit: str() unnecessary (%s implies str())","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"dfb6fd874fcb164de1caa01dde9ce8d4a6b5dcfb","unresolved":false,"context_lines":[{"line_number":107,"context_line":"                LOG.error(\"Error applying rule %(rule)s to node \""},{"line_number":108,"context_line":"                          \"%(node)s: %(error)s\","},{"line_number":109,"context_line":"                          {\u0027rule\u0027: rule[\u0027uuid\u0027], \u0027node\u0027: node.uuid,"},{"line_number":110,"context_line":"                           \u0027error\u0027: str(e)})"},{"line_number":111,"context_line":"        except Exception as e:"},{"line_number":112,"context_line":"            LOG.exception(\"Unexpected error %(error)s applying rule %(rule)s \""},{"line_number":113,"context_line":"                          \"to node %(node)s\", {\u0027rule\u0027: rule[\u0027uuid\u0027],"}],"source_content_type":"text/x-python","patch_set":25,"id":"dc719e51_e60d0246","line":110,"in_reply_to":"e7184000_90c7cd74","updated":"2024-11-13 01:16:00.000000000","message":"Acknowledged","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87538ee5b5ec9cb8205c73dc19cc645db1322acf","unresolved":true,"context_lines":[{"line_number":111,"context_line":"        except Exception as e:"},{"line_number":112,"context_line":"            LOG.exception(\"Unexpected error %(error)s applying rule %(rule)s \""},{"line_number":113,"context_line":"                          \"to node %(node)s\", {\u0027rule\u0027: rule[\u0027uuid\u0027],"},{"line_number":114,"context_line":"                                               \u0027node\u0027: node.uuid, \u0027error\u0027: e})"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    LOG.info(\"Finished applying inspection rules to node %s\", node.uuid)"}],"source_content_type":"text/x-python","patch_set":25,"id":"47a67db0_189b78c3","line":114,"updated":"2024-11-12 13:23:23.000000000","message":"We need to re-raise both types of exceptions, not just silence them","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"dfb6fd874fcb164de1caa01dde9ce8d4a6b5dcfb","unresolved":false,"context_lines":[{"line_number":111,"context_line":"        except Exception as e:"},{"line_number":112,"context_line":"            LOG.exception(\"Unexpected error %(error)s applying rule %(rule)s \""},{"line_number":113,"context_line":"                          \"to node %(node)s\", {\u0027rule\u0027: rule[\u0027uuid\u0027],"},{"line_number":114,"context_line":"                                               \u0027node\u0027: node.uuid, \u0027error\u0027: e})"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    LOG.info(\"Finished applying inspection rules to node %s\", node.uuid)"}],"source_content_type":"text/x-python","patch_set":25,"id":"af3da04e_4745db89","line":114,"in_reply_to":"47a67db0_189b78c3","updated":"2024-11-13 01:16:00.000000000","message":"Acknowledged","commit_id":"12332d912bda90a3c2e46754fd996441134a3222"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8ac093b99d4088b796948d68be69f7677a3739bf","unresolved":true,"context_lines":[{"line_number":29,"context_line":"                for key, value in data.items()}"},{"line_number":30,"context_line":"    elif isinstance(data, list):"},{"line_number":31,"context_line":"        return [_mask_sensitive_data(item) for item in data]"},{"line_number":32,"context_line":"    return data"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"def apply_rules(task, inventory, plugin_data, inspection_phase):"}],"source_content_type":"text/x-python","patch_set":29,"id":"97fb3efc_dd3b6c76","line":32,"updated":"2024-12-11 19:46:31.000000000","message":"Are we cleaning this up twice? In API controller set certain fields to None if sensitive is set; are those already redacted at that point?","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"21d272a1c6a1d76c7995003ac1095cf781220c4a","unresolved":true,"context_lines":[{"line_number":29,"context_line":"                for key, value in data.items()}"},{"line_number":30,"context_line":"    elif isinstance(data, list):"},{"line_number":31,"context_line":"        return [_mask_sensitive_data(item) for item in data]"},{"line_number":32,"context_line":"    return data"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"def apply_rules(task, inventory, plugin_data, inspection_phase):"}],"source_content_type":"text/x-python","patch_set":29,"id":"09cde281_56415744","line":32,"in_reply_to":"97fb3efc_dd3b6c76","updated":"2024-12-12 10:28:10.000000000","message":"We are not, they are doing different things. In the API, we strip out the values for `actions` and `conditions`, depending on the truthiness of the rule\u0027s `sensitive` field, as per the spec.\n\nHere, we mask out sensitive fields in `inventory` and `plugin_data` based on the value of `CONF.inspection_rules.mask_secrets`.","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8ac093b99d4088b796948d68be69f7677a3739bf","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        for rule in rules:"},{"line_number":58,"context_line":"            if not rule.get(\u0027sensitive\u0027, False):"},{"line_number":59,"context_line":"                inventory \u003d _mask_sensitive_data(inventory)"},{"line_number":60,"context_line":"                plugin_data \u003d _mask_sensitive_data(plugin_data)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    rules.sort(key\u003dlambda rule: rule[\u0027priority\u0027])"},{"line_number":63,"context_line":"    LOG.debug(\"Applying %(count)d inspection rules to node %(node)s\","}],"source_content_type":"text/x-python","patch_set":29,"id":"b3b0af8d_cdf5d384","line":60,"updated":"2024-12-11 19:46:31.000000000","message":"The above mentioned API code does not respect this CONF","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"21d272a1c6a1d76c7995003ac1095cf781220c4a","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        for rule in rules:"},{"line_number":58,"context_line":"            if not rule.get(\u0027sensitive\u0027, False):"},{"line_number":59,"context_line":"                inventory \u003d _mask_sensitive_data(inventory)"},{"line_number":60,"context_line":"                plugin_data \u003d _mask_sensitive_data(plugin_data)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    rules.sort(key\u003dlambda rule: rule[\u0027priority\u0027])"},{"line_number":63,"context_line":"    LOG.debug(\"Applying %(count)d inspection rules to node %(node)s\","}],"source_content_type":"text/x-python","patch_set":29,"id":"abf98b4a_a9e692ac","line":60,"in_reply_to":"b3b0af8d_cdf5d384","updated":"2024-12-12 10:28:10.000000000","message":"That might have been intentional.","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8ac093b99d4088b796948d68be69f7677a3739bf","unresolved":true,"context_lines":[{"line_number":67,"context_line":"        try:"},{"line_number":68,"context_line":"            for condition in rule[\u0027conditions\u0027]:"},{"line_number":69,"context_line":"                if not engine.check_inspection_rule_condition("},{"line_number":70,"context_line":"                    task, condition, inventory, plugin_data"},{"line_number":71,"context_line":"                ):"},{"line_number":72,"context_line":"                    LOG.debug(\"Skipping rule %(rule)s on node %(node)s: \""},{"line_number":73,"context_line":"                              \"condition \u0027%(condition)s\u0027 failed \","}],"source_content_type":"text/x-python","patch_set":29,"id":"e2475c42_d613d951","line":70,"updated":"2024-12-11 19:46:31.000000000","message":"the plugin_data and inventory passed here have already been; is that intentional?\n\nSeems like yes; the sensitive flag/conf is more about keeping the inspection rule from SEEING sensitive node information than it is about santizing secrets in the rule itself on the way out","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"21d272a1c6a1d76c7995003ac1095cf781220c4a","unresolved":true,"context_lines":[{"line_number":67,"context_line":"        try:"},{"line_number":68,"context_line":"            for condition in rule[\u0027conditions\u0027]:"},{"line_number":69,"context_line":"                if not engine.check_inspection_rule_condition("},{"line_number":70,"context_line":"                    task, condition, inventory, plugin_data"},{"line_number":71,"context_line":"                ):"},{"line_number":72,"context_line":"                    LOG.debug(\"Skipping rule %(rule)s on node %(node)s: \""},{"line_number":73,"context_line":"                              \"condition \u0027%(condition)s\u0027 failed \","}],"source_content_type":"text/x-python","patch_set":29,"id":"46fbacef_0d8643da","line":70,"in_reply_to":"e2475c42_d613d951","updated":"2024-12-12 10:28:10.000000000","message":"Indeed! Whether to mask anything or pass full node objects to all rules.","commit_id":"2007e0d22bc5de425ffd338bbaf3b3c6ab4082c3"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":true,"context_lines":[{"line_number":32,"context_line":"    return data"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"def apply_rules(task, inventory, plugin_data, inspection_phase):"},{"line_number":36,"context_line":"    \"\"\"Apply inspection rules to a node.\"\"\""},{"line_number":37,"context_line":"    node \u003d task.node"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"aae63194_a80c68ad","line":35,"updated":"2025-01-02 16:28:09.000000000","message":"Another code organization comment: I wonder if we actually need this new module under ironic.conductor. It does not use anything else from the conductor, I think it can be moved to ironic.common.inspection_rules as well.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    return data"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"def apply_rules(task, inventory, plugin_data, inspection_phase):"},{"line_number":36,"context_line":"    \"\"\"Apply inspection rules to a node.\"\"\""},{"line_number":37,"context_line":"    node \u003d task.node"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"93031ec5_adfd92ec","line":35,"in_reply_to":"aae63194_a80c68ad","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":true,"context_lines":[{"line_number":41,"context_line":"        filters\u003d{\u0027phase\u0027: inspection_phase})"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    built_in_rules \u003d engine.get_built_in_rules()"},{"line_number":44,"context_line":"    rules \u003d all_rules + built_in_rules"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    if not rules:"},{"line_number":47,"context_line":"        LOG.debug(\"No inspection rules to apply for phase \u0027%s\u0027\","}],"source_content_type":"text/x-python","patch_set":43,"id":"b4e95e9c_d776fa96","line":44,"updated":"2025-01-02 16:28:09.000000000","message":"nit: I wonder which rules should go first. I guess we need to wait for priorities first..","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    if not rules:"},{"line_number":47,"context_line":"        LOG.debug(\"No inspection rules to apply for phase \u0027%s\u0027\","},{"line_number":48,"context_line":"                  inspection_phase)"},{"line_number":49,"context_line":"        return"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    mask_secrets \u003d CONF.inspection_rules.mask_secrets"}],"source_content_type":"text/x-python","patch_set":43,"id":"32e1ef50_0195956f","line":48,"updated":"2025-01-08 13:32:17.000000000","message":"nit: log the node UUID","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    if not rules:"},{"line_number":47,"context_line":"        LOG.debug(\"No inspection rules to apply for phase \u0027%s\u0027\","},{"line_number":48,"context_line":"                  inspection_phase)"},{"line_number":49,"context_line":"        return"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    mask_secrets \u003d CONF.inspection_rules.mask_secrets"}],"source_content_type":"text/x-python","patch_set":43,"id":"732a7cd9_48b91e38","line":48,"in_reply_to":"32e1ef50_0195956f","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        for rule in rules:"},{"line_number":58,"context_line":"            if not rule.get(\u0027sensitive\u0027, False):"},{"line_number":59,"context_line":"                inventory \u003d _mask_sensitive_data(inventory)"},{"line_number":60,"context_line":"                plugin_data \u003d _mask_sensitive_data(plugin_data)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    rules.sort(key\u003dlambda rule: rule[\u0027priority\u0027])"},{"line_number":63,"context_line":"    LOG.debug(\"Applying %(count)d inspection rules to node %(node)s\","}],"source_content_type":"text/x-python","patch_set":43,"id":"36ed27eb_a61abd51","line":60,"updated":"2025-01-02 16:28:09.000000000","message":"nit: You may want to add a \"break\" here to stop looping over rules. It probably won\u0027t harm to mask the secrets several times, but it\u0027s also pointless.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        for rule in rules:"},{"line_number":58,"context_line":"            if not rule.get(\u0027sensitive\u0027, False):"},{"line_number":59,"context_line":"                inventory \u003d _mask_sensitive_data(inventory)"},{"line_number":60,"context_line":"                plugin_data \u003d _mask_sensitive_data(plugin_data)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    rules.sort(key\u003dlambda rule: rule[\u0027priority\u0027])"},{"line_number":63,"context_line":"    LOG.debug(\"Applying %(count)d inspection rules to node %(node)s\","}],"source_content_type":"text/x-python","patch_set":43,"id":"3412c459_3a02eeee","line":60,"in_reply_to":"36ed27eb_a61abd51","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"02d2d689327173d35674389c5b41410ae84516a8","unresolved":true,"context_lines":[{"line_number":59,"context_line":"                inventory \u003d _mask_sensitive_data(inventory)"},{"line_number":60,"context_line":"                plugin_data \u003d _mask_sensitive_data(plugin_data)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    rules.sort(key\u003dlambda rule: rule[\u0027priority\u0027])"},{"line_number":63,"context_line":"    LOG.debug(\"Applying %(count)d inspection rules to node %(node)s\","},{"line_number":64,"context_line":"              {\u0027count\u0027: len(rules), \u0027node\u0027: node.uuid})"},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"19586319_59a2772f","line":62,"updated":"2025-01-08 13:32:17.000000000","message":"This is an unfortunate omission from the spec, but higher priorities should be run first, not last. This is consistent with priority on steps: https://opendev.org/openstack/ironic/src/branch/master/ironic/conductor/steps.py#L132","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":59,"context_line":"                inventory \u003d _mask_sensitive_data(inventory)"},{"line_number":60,"context_line":"                plugin_data \u003d _mask_sensitive_data(plugin_data)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    rules.sort(key\u003dlambda rule: rule[\u0027priority\u0027])"},{"line_number":63,"context_line":"    LOG.debug(\"Applying %(count)d inspection rules to node %(node)s\","},{"line_number":64,"context_line":"              {\u0027count\u0027: len(rules), \u0027node\u0027: node.uuid})"},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"58b8de09_c8717122","line":62,"in_reply_to":"19586319_59a2772f","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":true,"context_lines":[{"line_number":84,"context_line":"        except exception.IronicException as e:"},{"line_number":85,"context_line":"            if rule[\u0027sensitive\u0027]:"},{"line_number":86,"context_line":"                LOG.error(\"Error applying sensitive rule %(rule)s to node \""},{"line_number":87,"context_line":"                          \"%(node)s\","},{"line_number":88,"context_line":"                          {\u0027rule\u0027: rule[\u0027uuid\u0027], \u0027node\u0027: node.uuid})"},{"line_number":89,"context_line":"            else:"},{"line_number":90,"context_line":"                LOG.error(\"Error applying rule %(rule)s to node \""}],"source_content_type":"text/x-python","patch_set":43,"id":"18137f8c_9ec163fb","line":87,"updated":"2025-01-02 16:28:09.000000000","message":"I think we can log the actual error but maybe we need to prevent the error message from propagating up the stack.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0c7cdb51ab62e205e1c376a32a4d3aceada78aae","unresolved":true,"context_lines":[{"line_number":96,"context_line":"            LOG.exception(\"Unexpected error %(error)s applying rule %(rule)s \""},{"line_number":97,"context_line":"                          \"to node %(node)s\", {\u0027rule\u0027: rule[\u0027uuid\u0027],"},{"line_number":98,"context_line":"                                               \u0027node\u0027: node.uuid, \u0027error\u0027: e})"},{"line_number":99,"context_line":"            raise"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    LOG.info(\"Finished applying inspection rules to node %s\", node.uuid)"}],"source_content_type":"text/x-python","patch_set":43,"id":"e1847604_a1c0712e","line":99,"updated":"2025-01-02 16:28:09.000000000","message":"In this case, we should convert the unexpected exception into something inherited from IronicException with a reasonable message. Messages of some Python exceptions can be very confusing without context.","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"b228cd343cdaee68a043c1185e744f0ab9e11b6c","unresolved":false,"context_lines":[{"line_number":96,"context_line":"            LOG.exception(\"Unexpected error %(error)s applying rule %(rule)s \""},{"line_number":97,"context_line":"                          \"to node %(node)s\", {\u0027rule\u0027: rule[\u0027uuid\u0027],"},{"line_number":98,"context_line":"                                               \u0027node\u0027: node.uuid, \u0027error\u0027: e})"},{"line_number":99,"context_line":"            raise"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    LOG.info(\"Finished applying inspection rules to node %s\", node.uuid)"}],"source_content_type":"text/x-python","patch_set":43,"id":"9fa5e7a3_e55f981e","line":99,"in_reply_to":"e1847604_a1c0712e","updated":"2025-01-19 17:40:21.000000000","message":"Acknowledged","commit_id":"5fcffec50a43a7e8efb3dc94f5f29972f7e28608"}],"ironic/conductor/utils.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":1919,"context_line":"    node_cache_firmware_components(task)"},{"line_number":1920,"context_line":""},{"line_number":1921,"context_line":""},{"line_number":1922,"context_line":"def check_inspection_rule_condition(condition, node, inventory):"},{"line_number":1923,"context_line":"    \"\"\"Check a single condition using the appropriate plugin.\"\"\""},{"line_number":1924,"context_line":"    try:"},{"line_number":1925,"context_line":"        plugin \u003d plugins.rule_conditions_manager()[condition[\u0027op\u0027]].obj"}],"source_content_type":"text/x-python","patch_set":20,"id":"1ddd37f9_55be003f","line":1922,"updated":"2024-09-26 15:27:50.000000000","message":"Please don\u0027t add anything to conductor.utils that is not widely used by the conductor. These are very specific to inspection and should be inside ironic.common.inspection_rules most likely.","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":1919,"context_line":"    node_cache_firmware_components(task)"},{"line_number":1920,"context_line":""},{"line_number":1921,"context_line":""},{"line_number":1922,"context_line":"def check_inspection_rule_condition(condition, node, inventory):"},{"line_number":1923,"context_line":"    \"\"\"Check a single condition using the appropriate plugin.\"\"\""},{"line_number":1924,"context_line":"    try:"},{"line_number":1925,"context_line":"        plugin \u003d plugins.rule_conditions_manager()[condition[\u0027op\u0027]].obj"}],"source_content_type":"text/x-python","patch_set":20,"id":"4b46dc77_2ebf57de","line":1922,"in_reply_to":"1ddd37f9_55be003f","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":1927,"context_line":"                            inventory\u003dinventory)"},{"line_number":1928,"context_line":"    except Exception as err:"},{"line_number":1929,"context_line":"        LOG.error(\"Error checking condition on node %(node)s: %(err)s.\","},{"line_number":1930,"context_line":"                  {\u0027node\u0027: node.uuid, \u0027err\u0027: err})"},{"line_number":1931,"context_line":"        return False"},{"line_number":1932,"context_line":""},{"line_number":1933,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"ef41c8fb_ba7e1f09","line":1930,"updated":"2024-09-26 15:27:50.000000000","message":"I don\u0027t quite agree with ignoring errors like this.","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":true,"context_lines":[{"line_number":1927,"context_line":"                            inventory\u003dinventory)"},{"line_number":1928,"context_line":"    except Exception as err:"},{"line_number":1929,"context_line":"        LOG.error(\"Error checking condition on node %(node)s: %(err)s.\","},{"line_number":1930,"context_line":"                  {\u0027node\u0027: node.uuid, \u0027err\u0027: err})"},{"line_number":1931,"context_line":"        return False"},{"line_number":1932,"context_line":""},{"line_number":1933,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"aa3a617a_db366a39","line":1930,"in_reply_to":"ef41c8fb_ba7e1f09","updated":"2024-10-11 23:30:46.000000000","message":"I\u0027m raising the exception after logging now; not sure if that\u0027s what you meant.","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":1938,"context_line":"        plugin.apply(task.node, action, inventory\u003dinventory,"},{"line_number":1939,"context_line":"                     plugin_data\u003dplugin_data)"},{"line_number":1940,"context_line":"    except exception.IronicException as err:"},{"line_number":1941,"context_line":"        LOG.error(\"Error applying action: %s\", err)"},{"line_number":1942,"context_line":"    except Exception:"},{"line_number":1943,"context_line":"        LOG.exception(\"Unexpected error applying action\")"},{"line_number":1944,"context_line":"    return"}],"source_content_type":"text/x-python","patch_set":20,"id":"198f7300_9cc769bc","line":1941,"updated":"2024-09-26 15:27:50.000000000","message":"Very much the same","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":1938,"context_line":"        plugin.apply(task.node, action, inventory\u003dinventory,"},{"line_number":1939,"context_line":"                     plugin_data\u003dplugin_data)"},{"line_number":1940,"context_line":"    except exception.IronicException as err:"},{"line_number":1941,"context_line":"        LOG.error(\"Error applying action: %s\", err)"},{"line_number":1942,"context_line":"    except Exception:"},{"line_number":1943,"context_line":"        LOG.exception(\"Unexpected error applying action\")"},{"line_number":1944,"context_line":"    return"}],"source_content_type":"text/x-python","patch_set":20,"id":"58cee66f_3b75d714","line":1941,"in_reply_to":"198f7300_9cc769bc","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":1941,"context_line":"        LOG.error(\"Error applying action: %s\", err)"},{"line_number":1942,"context_line":"    except Exception:"},{"line_number":1943,"context_line":"        LOG.exception(\"Unexpected error applying action\")"},{"line_number":1944,"context_line":"    return"}],"source_content_type":"text/x-python","patch_set":20,"id":"8d15f4c0_357c91a0","line":1944,"updated":"2024-09-26 15:27:50.000000000","message":"nit: not needed","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":1941,"context_line":"        LOG.error(\"Error applying action: %s\", err)"},{"line_number":1942,"context_line":"    except Exception:"},{"line_number":1943,"context_line":"        LOG.exception(\"Unexpected error applying action\")"},{"line_number":1944,"context_line":"    return"}],"source_content_type":"text/x-python","patch_set":20,"id":"575e21c6_b6c69530","line":1944,"in_reply_to":"8d15f4c0_357c91a0","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"}],"ironic/db/api.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":1656,"context_line":"        \"\"\""},{"line_number":1657,"context_line":""},{"line_number":1658,"context_line":"    @abc.abstractmethod"},{"line_number":1659,"context_line":"    def get_inspection_rules_by_node(self, node_id, limit\u003dNone, marker\u003dNone,"},{"line_number":1660,"context_line":"                                     filters\u003dNone, sort_key\u003dNone,"},{"line_number":1661,"context_line":"                                     sort_dir\u003dNone):"},{"line_number":1662,"context_line":"        \"\"\"Retrieve a list of inspection rules for a node."}],"source_content_type":"text/x-python","patch_set":20,"id":"a2378a6f_3041ad5c","line":1659,"updated":"2024-09-26 15:27:50.000000000","message":"What do you mean by \"inspection rules by node\"? They are not linked.","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":1656,"context_line":"        \"\"\""},{"line_number":1657,"context_line":""},{"line_number":1658,"context_line":"    @abc.abstractmethod"},{"line_number":1659,"context_line":"    def get_inspection_rules_by_node(self, node_id, limit\u003dNone, marker\u003dNone,"},{"line_number":1660,"context_line":"                                     filters\u003dNone, sort_key\u003dNone,"},{"line_number":1661,"context_line":"                                     sort_dir\u003dNone):"},{"line_number":1662,"context_line":"        \"\"\"Retrieve a list of inspection rules for a node."}],"source_content_type":"text/x-python","patch_set":20,"id":"b0befd09_20100e98","line":1659,"in_reply_to":"a2378a6f_3041ad5c","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"5ffa7531da551c6bf57dca8682962809e9a6515f","unresolved":true,"context_lines":[{"line_number":1656,"context_line":"        \"\"\""},{"line_number":1657,"context_line":""},{"line_number":1658,"context_line":"    @abc.abstractmethod"},{"line_number":1659,"context_line":"    def get_inspection_rules_by_node(self, node_id, limit\u003dNone, marker\u003dNone,"},{"line_number":1660,"context_line":"                                     filters\u003dNone, sort_key\u003dNone,"},{"line_number":1661,"context_line":"                                     sort_dir\u003dNone):"},{"line_number":1662,"context_line":"        \"\"\"Retrieve a list of inspection rules for a node."}],"source_content_type":"text/x-python","patch_set":20,"id":"a62de1bd_38a4b07f","line":1659,"in_reply_to":"a2378a6f_3041ad5c","updated":"2024-10-09 13:38:50.000000000","message":"Looking at the implementation in ironic/db/sqlalchemy/api.py, this should be about matching the scope on the rule and node.","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":1694,"context_line":"        \"\"\""},{"line_number":1695,"context_line":""},{"line_number":1696,"context_line":"    @abc.abstractmethod"},{"line_number":1697,"context_line":"    def destroy_inspection_rules_for_node(self, node_id):"},{"line_number":1698,"context_line":"        \"\"\"Destroy inspection rules for a node."},{"line_number":1699,"context_line":""},{"line_number":1700,"context_line":"        :param node_id: ID of a node."}],"source_content_type":"text/x-python","patch_set":20,"id":"efc552c2_4b241aa1","line":1697,"updated":"2024-09-26 15:27:50.000000000","message":"Same","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":1694,"context_line":"        \"\"\""},{"line_number":1695,"context_line":""},{"line_number":1696,"context_line":"    @abc.abstractmethod"},{"line_number":1697,"context_line":"    def destroy_inspection_rules_for_node(self, node_id):"},{"line_number":1698,"context_line":"        \"\"\"Destroy inspection rules for a node."},{"line_number":1699,"context_line":""},{"line_number":1700,"context_line":"        :param node_id: ID of a node."}],"source_content_type":"text/x-python","patch_set":20,"id":"13dad13d_4cf5102e","line":1697,"in_reply_to":"efc552c2_4b241aa1","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"}],"ironic/db/sqlalchemy/alembic/versions/21c48150dea9_add_inspection_rules.py":[{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":"def upgrade():"},{"line_number":31,"context_line":"    op.create_table("},{"line_number":32,"context_line":"        \u0027inspection_rules\u0027,"},{"line_number":33,"context_line":"        sa.Column(\u0027version\u0027, sa.String(length\u003d15), nullable\u003dTrue),"},{"line_number":34,"context_line":"        sa.Column(\u0027created_at\u0027, sa.DateTime(), nullable\u003dTrue),"},{"line_number":35,"context_line":"        sa.Column(\u0027updated_at\u0027, sa.DateTime(), nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":15,"id":"b845b33b_8290751e","line":32,"updated":"2024-09-12 10:36:13.000000000","message":"Please update it as per the spec. conditions and actions become part of this table, and there are a few other changes.","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":false,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":"def upgrade():"},{"line_number":31,"context_line":"    op.create_table("},{"line_number":32,"context_line":"        \u0027inspection_rules\u0027,"},{"line_number":33,"context_line":"        sa.Column(\u0027version\u0027, sa.String(length\u003d15), nullable\u003dTrue),"},{"line_number":34,"context_line":"        sa.Column(\u0027created_at\u0027, sa.DateTime(), nullable\u003dTrue),"},{"line_number":35,"context_line":"        sa.Column(\u0027updated_at\u0027, sa.DateTime(), nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":15,"id":"4d513cb8_7073134e","line":32,"in_reply_to":"b845b33b_8290751e","updated":"2024-09-17 11:41:10.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"feab5c03b3d8730b301ec0a0b0da79d1ecc2674c","unresolved":true,"context_lines":[{"line_number":30,"context_line":"def upgrade():"},{"line_number":31,"context_line":"    op.create_table("},{"line_number":32,"context_line":"        \u0027inspection_rules\u0027,"},{"line_number":33,"context_line":"        sa.Column(\u0027version\u0027, sa.String(length\u003d15), nullable\u003dTrue),"},{"line_number":34,"context_line":"        sa.Column(\u0027created_at\u0027, sa.DateTime(), nullable\u003dTrue),"},{"line_number":35,"context_line":"        sa.Column(\u0027updated_at\u0027, sa.DateTime(), nullable\u003dTrue),"},{"line_number":36,"context_line":"        sa.Column(\u0027id\u0027, sa.Integer(), nullable\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":18,"id":"4e99c2ab_6ea1e1a9","line":33,"updated":"2024-09-17 11:41:10.000000000","message":"I don\u0027t think we need a version field","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d77b316d2ede916f32f502d2d4671d60556781de","unresolved":true,"context_lines":[{"line_number":30,"context_line":"def upgrade():"},{"line_number":31,"context_line":"    op.create_table("},{"line_number":32,"context_line":"        \u0027inspection_rules\u0027,"},{"line_number":33,"context_line":"        sa.Column(\u0027version\u0027, sa.String(length\u003d15), nullable\u003dTrue),"},{"line_number":34,"context_line":"        sa.Column(\u0027created_at\u0027, sa.DateTime(), nullable\u003dTrue),"},{"line_number":35,"context_line":"        sa.Column(\u0027updated_at\u0027, sa.DateTime(), nullable\u003dTrue),"},{"line_number":36,"context_line":"        sa.Column(\u0027id\u0027, sa.Integer(), nullable\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":18,"id":"9623ae11_594781dc","line":33,"in_reply_to":"42e8d192_10c9c2cb","updated":"2024-09-20 09:37:56.000000000","message":"I\u0027ll admit I don\u0027t know what its for","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"f75c78b00f5a99fda0543c9c0bbd1059bf151039","unresolved":true,"context_lines":[{"line_number":30,"context_line":"def upgrade():"},{"line_number":31,"context_line":"    op.create_table("},{"line_number":32,"context_line":"        \u0027inspection_rules\u0027,"},{"line_number":33,"context_line":"        sa.Column(\u0027version\u0027, sa.String(length\u003d15), nullable\u003dTrue),"},{"line_number":34,"context_line":"        sa.Column(\u0027created_at\u0027, sa.DateTime(), nullable\u003dTrue),"},{"line_number":35,"context_line":"        sa.Column(\u0027updated_at\u0027, sa.DateTime(), nullable\u003dTrue),"},{"line_number":36,"context_line":"        sa.Column(\u0027id\u0027, sa.Integer(), nullable\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":18,"id":"42e8d192_10c9c2cb","line":33,"in_reply_to":"4e99c2ab_6ea1e1a9","updated":"2024-09-19 17:53:38.000000000","message":"Erm, maybe we do!","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"f79f95266a6edd34798e44b43629bcf36ac423d3","unresolved":true,"context_lines":[{"line_number":30,"context_line":"def upgrade():"},{"line_number":31,"context_line":"    op.create_table("},{"line_number":32,"context_line":"        \u0027inspection_rules\u0027,"},{"line_number":33,"context_line":"        sa.Column(\u0027version\u0027, sa.String(length\u003d15), nullable\u003dTrue),"},{"line_number":34,"context_line":"        sa.Column(\u0027created_at\u0027, sa.DateTime(), nullable\u003dTrue),"},{"line_number":35,"context_line":"        sa.Column(\u0027updated_at\u0027, sa.DateTime(), nullable\u003dTrue),"},{"line_number":36,"context_line":"        sa.Column(\u0027id\u0027, sa.Integer(), nullable\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":18,"id":"d36dd8f5_64d67d4a","line":33,"in_reply_to":"9623ae11_594781dc","updated":"2024-09-23 12:05:12.000000000","message":"Besides that every table in Ironic has it and uses it for version checks, I\u0027ve heard it\u0027s a good practice generally, for the same reasons. (I might be terribly wrong!)","commit_id":"1b40ffc8677ae867d69f96dcf23f1816fbe17aee"}],"ironic/db/sqlalchemy/api.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":3152,"context_line":"    @oslo_db_api.retry_on_deadlock"},{"line_number":3153,"context_line":"    def create_inspection_rule(self, values):"},{"line_number":3154,"context_line":"        \"\"\"Create new rule\"\"\""},{"line_number":3155,"context_line":"        values[\u0027actions\u0027] \u003d [action for action in values.get(\u0027actions\u0027, [])]"},{"line_number":3156,"context_line":"        values[\u0027conditions\u0027] \u003d ["},{"line_number":3157,"context_line":"            condition for condition in values.get(\u0027conditions\u0027, [])]"},{"line_number":3158,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"9cfa81b4_2f05522e","line":3155,"updated":"2024-09-26 15:27:50.000000000","message":"This operation does nothing","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":3152,"context_line":"    @oslo_db_api.retry_on_deadlock"},{"line_number":3153,"context_line":"    def create_inspection_rule(self, values):"},{"line_number":3154,"context_line":"        \"\"\"Create new rule\"\"\""},{"line_number":3155,"context_line":"        values[\u0027actions\u0027] \u003d [action for action in values.get(\u0027actions\u0027, [])]"},{"line_number":3156,"context_line":"        values[\u0027conditions\u0027] \u003d ["},{"line_number":3157,"context_line":"            condition for condition in values.get(\u0027conditions\u0027, [])]"},{"line_number":3158,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"d8412501_684eb8ea","line":3155,"in_reply_to":"9cfa81b4_2f05522e","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":3154,"context_line":"        \"\"\"Create new rule\"\"\""},{"line_number":3155,"context_line":"        values[\u0027actions\u0027] \u003d [action for action in values.get(\u0027actions\u0027, [])]"},{"line_number":3156,"context_line":"        values[\u0027conditions\u0027] \u003d ["},{"line_number":3157,"context_line":"            condition for condition in values.get(\u0027conditions\u0027, [])]"},{"line_number":3158,"context_line":""},{"line_number":3159,"context_line":"        inspection_rule \u003d models.InspectionRule()"},{"line_number":3160,"context_line":"        inspection_rule.update(values)"}],"source_content_type":"text/x-python","patch_set":20,"id":"ebd9f6e6_6410933a","line":3157,"updated":"2024-09-26 15:27:50.000000000","message":"same","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":3154,"context_line":"        \"\"\"Create new rule\"\"\""},{"line_number":3155,"context_line":"        values[\u0027actions\u0027] \u003d [action for action in values.get(\u0027actions\u0027, [])]"},{"line_number":3156,"context_line":"        values[\u0027conditions\u0027] \u003d ["},{"line_number":3157,"context_line":"            condition for condition in values.get(\u0027conditions\u0027, [])]"},{"line_number":3158,"context_line":""},{"line_number":3159,"context_line":"        inspection_rule \u003d models.InspectionRule()"},{"line_number":3160,"context_line":"        inspection_rule.update(values)"}],"source_content_type":"text/x-python","patch_set":20,"id":"0a56835f_ed7de90b","line":3157,"in_reply_to":"ebd9f6e6_6410933a","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":3222,"context_line":"            query \u003d sa.select(models.InspectionRule).where("},{"line_number":3223,"context_line":"                or_("},{"line_number":3224,"context_line":"                    models.InspectionRule.scope.is_(None),"},{"line_number":3225,"context_line":"                    models.InspectionRule.scope \u003d\u003d node.uuid"},{"line_number":3226,"context_line":"                )"},{"line_number":3227,"context_line":"            )"},{"line_number":3228,"context_line":"            return _paginate_query(models.InspectionRule, limit, marker,"}],"source_content_type":"text/x-python","patch_set":20,"id":"7b1959de_15a50120","line":3225,"updated":"2024-09-26 15:27:50.000000000","message":"It should have been mentioned explicitly in the spec, but scope is not a node UUID: https://docs.openstack.org/ironic-inspector/latest/user/usage.html#scope","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":3222,"context_line":"            query \u003d sa.select(models.InspectionRule).where("},{"line_number":3223,"context_line":"                or_("},{"line_number":3224,"context_line":"                    models.InspectionRule.scope.is_(None),"},{"line_number":3225,"context_line":"                    models.InspectionRule.scope \u003d\u003d node.uuid"},{"line_number":3226,"context_line":"                )"},{"line_number":3227,"context_line":"            )"},{"line_number":3228,"context_line":"            return _paginate_query(models.InspectionRule, limit, marker,"}],"source_content_type":"text/x-python","patch_set":20,"id":"efae15fe_827ac69f","line":3225,"in_reply_to":"7b1959de_15a50120","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":3248,"context_line":"            sa.select(models.InspectionRule).where("},{"line_number":3249,"context_line":"                or_("},{"line_number":3250,"context_line":"                    models.InspectionRule.scope.is_(None),"},{"line_number":3251,"context_line":"                    models.InspectionRule.scope \u003d\u003d node_uuid"},{"line_number":3252,"context_line":"                )"},{"line_number":3253,"context_line":"            ).delete(synchronize_session\u003dFalse)"},{"line_number":3254,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"88585e47_4789fb84","line":3251,"updated":"2024-09-26 15:27:50.000000000","message":"same","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"02405b52bfcccf48dda23451fba87dafebf4caf1","unresolved":false,"context_lines":[{"line_number":3248,"context_line":"            sa.select(models.InspectionRule).where("},{"line_number":3249,"context_line":"                or_("},{"line_number":3250,"context_line":"                    models.InspectionRule.scope.is_(None),"},{"line_number":3251,"context_line":"                    models.InspectionRule.scope \u003d\u003d node_uuid"},{"line_number":3252,"context_line":"                )"},{"line_number":3253,"context_line":"            ).delete(synchronize_session\u003dFalse)"},{"line_number":3254,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"6a840268_be189910","line":3251,"in_reply_to":"88585e47_4789fb84","updated":"2024-10-11 23:30:46.000000000","message":"Acknowledged","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"}],"ironic/db/sqlalchemy/models.py":[{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"d8149f9d991c5a175692730cbf149fc8551cb255","unresolved":true,"context_lines":[{"line_number":561,"context_line":"    )"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":""},{"line_number":564,"context_line":"class InspectionRule(Base):"},{"line_number":565,"context_line":"    __tablename__ \u003d \u0027inspection_rules\u0027"},{"line_number":566,"context_line":"    __table_args__ \u003d ("},{"line_number":567,"context_line":"        schema.UniqueConstraint(\u0027uuid\u0027, name\u003d\u0027uniq_inspection_rules0uuid\u0027),"}],"source_content_type":"text/x-python","patch_set":15,"id":"24c32181_5f17fc9a","line":564,"updated":"2024-09-12 10:36:13.000000000","message":"Same here","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"},{"author":{"_account_id":35929,"name":"Mahnoor Asghar","display_name":"Mahnoor Asghar","email":"masghar@redhat.com","username":"mahnoorasghar"},"change_message_id":"78d17403219b9b4ed6612b2e6d4c9efae5cfea2f","unresolved":false,"context_lines":[{"line_number":561,"context_line":"    )"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":""},{"line_number":564,"context_line":"class InspectionRule(Base):"},{"line_number":565,"context_line":"    __tablename__ \u003d \u0027inspection_rules\u0027"},{"line_number":566,"context_line":"    __table_args__ \u003d ("},{"line_number":567,"context_line":"        schema.UniqueConstraint(\u0027uuid\u0027, name\u003d\u0027uniq_inspection_rules0uuid\u0027),"}],"source_content_type":"text/x-python","patch_set":15,"id":"3a2505ed_dee823c1","line":564,"in_reply_to":"24c32181_5f17fc9a","updated":"2024-09-20 09:49:51.000000000","message":"Done","commit_id":"b84d303ccaefda7bb3efbf19378d5b15bae406d7"}],"setup.cfg":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":201,"context_line":"    local-link-connection \u003d ironic.drivers.modules.inspector.hooks.local_link_connection:LocalLinkConnectionHook"},{"line_number":202,"context_line":"    parse-lldp \u003d ironic.drivers.modules.inspector.hooks.parse_lldp:ParseLLDPHook"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":"ironic.inspection_rules.conditions \u003d"},{"line_number":205,"context_line":"    eq \u003d ironic.common.plugins:EqCondition"},{"line_number":206,"context_line":"    lt \u003d ironic.common.plugins:LtCondition"},{"line_number":207,"context_line":"    gt \u003d ironic.common.plugins:GtCondition"}],"source_content_type":"text/x-ttcn-cfg","patch_set":20,"id":"6529039d_116b3f1b","line":204,"updated":"2024-09-26 15:27:50.000000000","message":"These are not supposed to be pluggable and also the names don\u0027t follow the spec: https://specs.openstack.org/openstack/ironic-specs/specs/not-implemented/inspection-rules.html#available-conditions","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"05f26bed146bc138c2ecd9f309ac910ac59766ba","unresolved":true,"context_lines":[{"line_number":213,"context_line":"    contains \u003d ironic.common.plugins:ContainsCondition"},{"line_number":214,"context_line":"    is-empty \u003d ironic.common.plugins:EmptyCondition"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"ironic.inspection_rules.actions \u003d"},{"line_number":217,"context_line":"    fail \u003d ironic.common.plugins:FailAction"},{"line_number":218,"context_line":"    set-attribute \u003d ironic.common.plugins:SetAttributeAction"},{"line_number":219,"context_line":"    set-capability \u003d ironic.common.plugins:SetCapabilityAction"}],"source_content_type":"text/x-ttcn-cfg","patch_set":20,"id":"adceae0d_c496715f","line":216,"updated":"2024-09-26 15:27:50.000000000","message":"Same https://specs.openstack.org/openstack/ironic-specs/specs/not-implemented/inspection-rules.html#available-actions","commit_id":"c64a225eedc5a9c20211ab75bd10b8f7765f23e5"}]}
