)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"f5127aca21eb07ea2e64ea5fd4a7f4cd30d14d2d","unresolved":true,"context_lines":[{"line_number":17,"context_line":"  Audit.list, Audit.get, ActionPlan.get and Action.get. Callers"},{"line_number":18,"context_line":"  decide which version to use rather than the API layer."},{"line_number":19,"context_line":"- Views: Discover max version once per request using"},{"line_number":20,"context_line":"  @memoized.memoized_method and pass it to all API calls."},{"line_number":21,"context_line":"- forms.py: Discover max version before creating audits."},{"line_number":22,"context_line":"- Update tests to match new api_version plumbing and add"},{"line_number":23,"context_line":"  coverage for is_microversion_supported."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"0d9fc5e8_f5e26b77","line":20,"updated":"2026-02-27 15:20:53.000000000","message":"+1 that is a better approch\n\nwith that said views shoudl not have business logic in general so \n\nwe shoudl keep the logic in the views minimal\n\nthink MVC or MVVM patterns.\n\neven without a database we still have a model represented by the watcher api\n\nwe shoudl build a view model ( a view specific subset of the model) and the view shoudl just render the info form that view model.","commit_id":"049e166c2e6da638f422cc54c3ce8081dd3135a2"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"84be83121a0058f2e1d42751bff42f40177657c9","unresolved":true,"context_lines":[{"line_number":17,"context_line":"  Audit.list, Audit.get, ActionPlan.get and Action.get. Callers"},{"line_number":18,"context_line":"  decide which version to use rather than the API layer."},{"line_number":19,"context_line":"- Views: Discover max version once per request using"},{"line_number":20,"context_line":"  @memoized.memoized_method and pass it to all API calls."},{"line_number":21,"context_line":"- forms.py: Discover max version before creating audits."},{"line_number":22,"context_line":"- Update tests to match new api_version plumbing and add"},{"line_number":23,"context_line":"  coverage for is_microversion_supported."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"8bb9d14c_da13f7d6","line":20,"in_reply_to":"0d9fc5e8_f5e26b77","updated":"2026-03-02 07:21:47.000000000","message":"Yes totally agree here, Views should contain minimal logic. I saw you are already working on https://review.opendev.org/c/openstack/watcher-dashboard/+/978239/3/doc/source/contributor/microversions.rst Do we want to move towards this or continue with the current approach?\n\nBased on that, I will update the skip patch. Thank you!","commit_id":"049e166c2e6da638f422cc54c3ce8081dd3135a2"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"8b8103b5e7505eebeabbdeb005d7a1dddb9e5a69","unresolved":true,"context_lines":[{"line_number":17,"context_line":"  Audit.list, Audit.get, ActionPlan.get and Action.get. Callers"},{"line_number":18,"context_line":"  decide which version to use rather than the API layer."},{"line_number":19,"context_line":"- Views: Discover max version once per request using"},{"line_number":20,"context_line":"  @memoized.memoized_method and pass it to all API calls."},{"line_number":21,"context_line":"- forms.py: Discover max version before creating audits."},{"line_number":22,"context_line":"- Update tests to match new api_version plumbing and add"},{"line_number":23,"context_line":"  coverage for is_microversion_supported."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"f75cef0c_ab15fb76","line":20,"in_reply_to":"8bb9d14c_da13f7d6","updated":"2026-03-02 10:32:25.000000000","message":"the seriese i started i more for next release. i beasiclly implemented the spec i propopsed for this cycle and soem other clean up\n\n\nin terms of microverison i didnt actully get time to start on that so we cna proceed with your iniall work and then we can adapt it later as needed.","commit_id":"049e166c2e6da638f422cc54c3ce8081dd3135a2"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"f5127aca21eb07ea2e64ea5fd4a7f4cd30d14d2d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"3d074b0e_df61b246","updated":"2026-02-27 15:20:53.000000000","message":"better but the way your using microversion is still logiclly incorrect","commit_id":"701bd46b813fa60cbc8c9ba789c360be9d221df1"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"9b4b86e5410622f24bc8706a96a4de88af6c81dd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"c617b178_41ebe52b","updated":"2026-03-03 18:33:31.000000000","message":"lgtm","commit_id":"e6edaba67f6f9d333ad8151be6f7650cc0a53e95"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"8b8103b5e7505eebeabbdeb005d7a1dddb9e5a69","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"3172d7f9_0e38e40e","updated":"2026-03-02 10:32:25.000000000","message":"we could move forward with this version","commit_id":"e6edaba67f6f9d333ad8151be6f7650cc0a53e95"}],"watcher_dashboard/api/watcher.py":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"9b4b86e5410622f24bc8706a96a4de88af6c81dd","unresolved":true,"context_lines":[{"line_number":147,"context_line":"        ).audit.get(audit\u003daudit_id)"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"    @classmethod"},{"line_number":150,"context_line":"    def delete(cls, request, audit_id):"},{"line_number":151,"context_line":"        \"\"\"Delete an audit"},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"        :param request: request object"}],"source_content_type":"text/x-python","patch_set":3,"id":"4b6c46cb_79ae1bd4","line":150,"in_reply_to":"37ac0290_f5b2e938","updated":"2026-03-03 18:33:31.000000000","message":"+1, indeed is better to follow the pattern for all related methods","commit_id":"701bd46b813fa60cbc8c9ba789c360be9d221df1"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"f5127aca21eb07ea2e64ea5fd4a7f4cd30d14d2d","unresolved":true,"context_lines":[{"line_number":147,"context_line":"        ).audit.get(audit\u003daudit_id)"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"    @classmethod"},{"line_number":150,"context_line":"    def delete(cls, request, audit_id):"},{"line_number":151,"context_line":"        \"\"\"Delete an audit"},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"        :param request: request object"}],"source_content_type":"text/x-python","patch_set":3,"id":"37ac0290_f5b2e938","line":150,"in_reply_to":"67a0e47d_e3f54edb","updated":"2026-02-27 15:20:53.000000000","message":"since the scope of this chagne is intoducing microversion supprot it woudl be valid to also fix it here however we can defer this to a follow up","commit_id":"701bd46b813fa60cbc8c9ba789c360be9d221df1"}],"watcher_dashboard/common/client.py":[{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"f90747792c4e3f6eca4791fb266f480c4e9ed5e4","unresolved":true,"context_lines":[{"line_number":80,"context_line":"    return None"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"def is_microversion_supported(max_ver, required):"},{"line_number":84,"context_line":"    \"\"\"Check whether the server supports the required microversion."},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    :param max_ver: The server\u0027s max version string from"}],"source_content_type":"text/x-python","patch_set":2,"id":"bce298a4_c9878073","line":83,"range":{"start_line":83,"start_character":0,"end_line":83,"end_character":49},"updated":"2026-02-27 13:40:13.000000000","message":"I think this one is no longer needed, as get_max_version gets the maxium version.","commit_id":"01a52b8a86e3e9771bb72f355ca1d2a14d727d81"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"6d59d4d25859f25f784588503eabcb9ca4459964","unresolved":false,"context_lines":[{"line_number":80,"context_line":"    return None"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"def is_microversion_supported(max_ver, required):"},{"line_number":84,"context_line":"    \"\"\"Check whether the server supports the required microversion."},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    :param max_ver: The server\u0027s max version string from"}],"source_content_type":"text/x-python","patch_set":2,"id":"ebc3131d_72842f4b","line":83,"range":{"start_line":83,"start_character":0,"end_line":83,"end_character":49},"in_reply_to":"bce298a4_c9878073","updated":"2026-02-27 14:29:05.000000000","message":"ignore it.","commit_id":"01a52b8a86e3e9771bb72f355ca1d2a14d727d81"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"8b8103b5e7505eebeabbdeb005d7a1dddb9e5a69","unresolved":true,"context_lines":[{"line_number":61,"context_line":"    :param request: The current Django HTTP request."},{"line_number":62,"context_line":"    :returns: The max version string, or ``None`` on failure."},{"line_number":63,"context_line":"    \"\"\""},{"line_number":64,"context_line":"    try:"},{"line_number":65,"context_line":"        client \u003d get_client(request)"},{"line_number":66,"context_line":"        _resp, body \u003d client.http_client.json_request("},{"line_number":67,"context_line":"            \u0027GET\u0027, \u0027/\u0027)"},{"line_number":68,"context_line":"        version_info \u003d ("},{"line_number":69,"context_line":"            body.get(\u0027versions\u0027) or"},{"line_number":70,"context_line":"            body.get(\u0027version\u0027) or"},{"line_number":71,"context_line":"            body.get(\u0027default_version\u0027) or"},{"line_number":72,"context_line":"            {})"},{"line_number":73,"context_line":"        if isinstance(version_info, list) and version_info:"},{"line_number":74,"context_line":"            version_info \u003d version_info[0]"},{"line_number":75,"context_line":"        if isinstance(version_info, dict):"},{"line_number":76,"context_line":"            return version_info.get(\u0027max_version\u0027)"},{"line_number":77,"context_line":"    except wc_exc.ClientException:"},{"line_number":78,"context_line":"        LOG.debug(\u0027Microversion discovery failed\u0027,"},{"line_number":79,"context_line":"                  exc_info\u003dTrue)"},{"line_number":80,"context_line":"    return None"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"def is_microversion_supported(max_ver, required):"}],"source_content_type":"text/x-python","patch_set":5,"id":"1c7dfa49_6aba8138","line":80,"range":{"start_line":64,"start_character":0,"end_line":80,"end_character":15},"updated":"2026-03-02 10:32:25.000000000","message":"it should always be a list of dictionaries/objects  so we shoudl not have to check with isinstance like this.\n\nwe technially want the list item that has  \"status\": \"CURRENT\", rahter then the first althoug if there is only one then that is the same\n\nhttps://specs.openstack.org/openstack/api-wg/guidelines/microversion_specification.html#version-discovery\n```\nGET /\n{\n     \"versions\": [\n        {\n            \"id\": \"v2.1\",\n            \"links\": [\n                  {\n                    \"href\": \"http://localhost:8774/v2/\",\n                    \"rel\": \"self\"\n                }\n            ],\n            \"status\": \"CURRENT\",\n            \"max_version\": \"2.42\",\n            \"min_version\": \"2.1\",\n        },\n   ]\n}\n```\n\ntaking 0 is porbaly a good enough apoximation for now\n\nbut we shoudl really add a function for this to the watcher client or work on adding openstack sdk supprot next cycle.\n\n\n```\n    try:\n        client \u003d get_client(request)\n        _resp, body \u003d client.http_client.json_request(\n            \u0027GET\u0027, \u0027/\u0027)\n        version_info \u003d (body.get(\u0027versions\u0027, [{}])\n        # TODO: replace with a serach for the current version\n        version_info \u003d version_info[0]\n        return version_info.get(\u0027max_version\u0027, None)\n    except wc_exc.ClientException:\n        LOG.debug(\u0027Microversion discovery failed\u0027,\n                  exc_info\u003dTrue)\n    return None\n```","commit_id":"e6edaba67f6f9d333ad8151be6f7650cc0a53e95"}],"watcher_dashboard/content/action_plans/views.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"8b8103b5e7505eebeabbdeb005d7a1dddb9e5a69","unresolved":true,"context_lines":[{"line_number":125,"context_line":"            LOG.info(msg)"},{"line_number":126,"context_line":"            horizon.messages.warning(self.request, msg)"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        return efficacy_indicators"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def get_context_data(self, **kwargs):"},{"line_number":131,"context_line":"        context \u003d super().get_context_data(**kwargs)"}],"source_content_type":"text/x-python","patch_set":5,"id":"11d02b42_9c52162e","line":128,"in_reply_to":"0b2cd341_67a4c58d","updated":"2026-03-02 10:32:25.000000000","message":"if   action_plan \u003d self._get_data() raises efficacy_indicators is not defined and the return will raise. \n\nthis is a prexistign bug, its good to fix just notin this patch","commit_id":"e6edaba67f6f9d333ad8151be6f7650cc0a53e95"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"562874d8bc9674e563240ea44f7e93a089cff92b","unresolved":true,"context_lines":[{"line_number":125,"context_line":"            LOG.info(msg)"},{"line_number":126,"context_line":"            horizon.messages.warning(self.request, msg)"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        return efficacy_indicators"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def get_context_data(self, **kwargs):"},{"line_number":131,"context_line":"        context \u003d super().get_context_data(**kwargs)"}],"source_content_type":"text/x-python","patch_set":5,"id":"92f29310_9ee95969","line":128,"in_reply_to":"11d02b42_9c52162e","updated":"2026-03-02 11:36:33.000000000","message":"Addressed via https://review.opendev.org/c/openstack/watcher-dashboard/+/978438","commit_id":"e6edaba67f6f9d333ad8151be6f7650cc0a53e95"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"ba65f4d20e376b18c9b5b33891d062da8620622f","unresolved":false,"context_lines":[{"line_number":125,"context_line":"            LOG.info(msg)"},{"line_number":126,"context_line":"            horizon.messages.warning(self.request, msg)"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        return efficacy_indicators"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def get_context_data(self, **kwargs):"},{"line_number":131,"context_line":"        context \u003d super().get_context_data(**kwargs)"}],"source_content_type":"text/x-python","patch_set":5,"id":"426440e6_83b97b47","line":128,"in_reply_to":"92f29310_9ee95969","updated":"2026-03-03 10:20:08.000000000","message":"Acknowledged","commit_id":"e6edaba67f6f9d333ad8151be6f7650cc0a53e95"}],"watcher_dashboard/content/audit_templates/views.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"f5127aca21eb07ea2e64ea5fd4a7f4cd30d14d2d","unresolved":true,"context_lines":[{"line_number":121,"context_line":"            audit_template \u003d self._get_data()"},{"line_number":122,"context_line":"            audits \u003d watcher.Audit.list("},{"line_number":123,"context_line":"                self.request,"},{"line_number":124,"context_line":"                api_version\u003dself.max_version(),"},{"line_number":125,"context_line":"                audit_template\u003daudit_template.uuid)"},{"line_number":126,"context_line":"        except Exception as exc:"},{"line_number":127,"context_line":"            LOG.exception(exc)"}],"source_content_type":"text/x-python","patch_set":3,"id":"c474429e_70fd4486","line":124,"range":{"start_line":124,"start_character":27,"end_line":124,"end_character":47},"updated":"2026-02-27 15:20:53.000000000","message":"this is not really correct.\nwe do not want our request ot use the latest \"max\" value\nwe want them to use the newst value they supprot.\n\ni.e. if the dashboard plugin only supprot 1.5 it should not use 1.6 if that is supproted by the server.\n\nthere is no expectation that 1.6 is backward compatible with 1.5 that is the entire point of micro-version\nthe define the behaviour of the api for that request so you shoudl use the version you code supports\n\nif you are trying to supprot multipel version then you need to chek each version your client (the dashboad plugin in this case) supprots\n\nwhat you should be doing is geting the max version and the checkign if the rquired version is less then the max if  not fall back to the older api verison\n\nand then you pass it here so somethign liek this\n\n```\n server_version \u003d self.max_version()\n version \u003d constants.ACTION_SKIP if is_supported(\"1.5\") else constatns.OLDER_VERSION\n audits \u003d watcher.Audit.list(\n     self.request,\n     api_version\u003dversion,\n     audit_template\u003daudit_template.uuid)\n\n```","commit_id":"701bd46b813fa60cbc8c9ba789c360be9d221df1"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"8b8103b5e7505eebeabbdeb005d7a1dddb9e5a69","unresolved":false,"context_lines":[{"line_number":121,"context_line":"            audit_template \u003d self._get_data()"},{"line_number":122,"context_line":"            audits \u003d watcher.Audit.list("},{"line_number":123,"context_line":"                self.request,"},{"line_number":124,"context_line":"                api_version\u003dself.max_version(),"},{"line_number":125,"context_line":"                audit_template\u003daudit_template.uuid)"},{"line_number":126,"context_line":"        except Exception as exc:"},{"line_number":127,"context_line":"            LOG.exception(exc)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9d11a1c9_39c66973","line":124,"range":{"start_line":124,"start_character":27,"end_line":124,"end_character":47},"in_reply_to":"6498c56d_7887ac29","updated":"2026-03-02 10:32:25.000000000","message":"Done","commit_id":"701bd46b813fa60cbc8c9ba789c360be9d221df1"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"84be83121a0058f2e1d42751bff42f40177657c9","unresolved":true,"context_lines":[{"line_number":121,"context_line":"            audit_template \u003d self._get_data()"},{"line_number":122,"context_line":"            audits \u003d watcher.Audit.list("},{"line_number":123,"context_line":"                self.request,"},{"line_number":124,"context_line":"                api_version\u003dself.max_version(),"},{"line_number":125,"context_line":"                audit_template\u003daudit_template.uuid)"},{"line_number":126,"context_line":"        except Exception as exc:"},{"line_number":127,"context_line":"            LOG.exception(exc)"}],"source_content_type":"text/x-python","patch_set":3,"id":"6498c56d_7887ac29","line":124,"range":{"start_line":124,"start_character":27,"end_line":124,"end_character":47},"in_reply_to":"c474429e_70fd4486","updated":"2026-03-02 07:21:47.000000000","message":"Thank you for sharing the code, It is much simpler now by getting the max version then check whether it is supported or not then pass it to the Specific call.","commit_id":"701bd46b813fa60cbc8c9ba789c360be9d221df1"}],"watcher_dashboard/content/audits/views.py":[{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"6d59d4d25859f25f784588503eabcb9ca4459964","unresolved":true,"context_lines":[{"line_number":77,"context_line":"    def get_audits_count(self):"},{"line_number":78,"context_line":"        return len(self.get_data())"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def get_filters(self):"},{"line_number":81,"context_line":"        filters \u003d {}"},{"line_number":82,"context_line":"        filter_action \u003d self.table._meta._filter_action"},{"line_number":83,"context_line":"        if filter_action:"}],"source_content_type":"text/x-python","patch_set":2,"id":"be17cb77_729cc6a0","line":80,"in_reply_to":"897b0854_bf5eb7a3","updated":"2026-02-27 14:29:05.000000000","message":"\u003e Unused is_microversion_supported() function in views - Feature detection exists but isn\u0027t utilized in current view code.\n\u003e \n\u003e **Severity**: WARNING | **Confidence**: 0.7\n\u003e \n\u003e **Impact**: The is_microversion_supported() function exists but isn\u0027t called in view code, suggesting incomplete implementation.\n\u003e \n\u003e **Suggestion**:\n\u003e Either use is_microversion_supported() for version-based feature gating, add TODO comment for planned use, or remove if not needed.\n\nPlease fix.","commit_id":"01a52b8a86e3e9771bb72f355ca1d2a14d727d81"}]}
