)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":38688,"name":"Nikita Vokhmintsev","email":"zedra5399@gmail.com","username":"nvoff"},"change_message_id":"816cb08653c10e3f216bac5e806e2515d6896c31","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"392e9474_17037297","updated":"2026-08-24 08:39:51.000000000","message":"Hi zhang.jingwei@algoblu.com and lazekteam@gmail.com\n, could you please review this change when you have a chance? Zuul checks have passed. Thank you!","commit_id":"bc766f04ff6dca70cf262bcf84fc9e781a25f546"},{"author":{"_account_id":38688,"name":"Nikita Vokhmintsev","email":"zedra5399@gmail.com","username":"nvoff"},"change_message_id":"c7de531748adf777d33afc9ff21e1bd8db448a36","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":1,"id":"cf13435e_a7da5ff2","in_reply_to":"392e9474_17037297","updated":"2026-08-24 08:40:14.000000000","message":"\u003e Hi zhang.jingwei@algoblu.com and lazekteam@gmail.com\n\u003e , could you please review this change when you have a chance? Zuul checks have passed. Thank you!","commit_id":"bc766f04ff6dca70cf262bcf84fc9e781a25f546"},{"author":{"_account_id":38688,"name":"Nikita Vokhmintsev","email":"zedra5399@gmail.com","username":"nvoff"},"change_message_id":"30ecabbc4ba86280748cd78b628e6e6b92674df3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"90f0b8e2_eb97d5fc","in_reply_to":"cf13435e_a7da5ff2","updated":"2026-09-10 07:48:30.000000000","message":"Done","commit_id":"bc766f04ff6dca70cf262bcf84fc9e781a25f546"}],"src/stores/magnum/clusters.js":[{"author":{"_account_id":30434,"name":"Jingwei.Zhang","email":"zhang.jingwei@algoblu.com","username":"jwzhang"},"change_message_id":"cbc751ffc47bf2fa68fa580205789c79624c462d","unresolved":true,"context_lines":[{"line_number":106,"context_line":"        fixedNetworkId ? this.networkClient.show(fixedNetworkId) : {},"},{"line_number":107,"context_line":"        fixedSubnetId ? this.subnetClient.show(fixedSubnetId) : {},"},{"line_number":108,"context_line":"        item.stack_id ? this.stackClient.list({ id: item.stack_id }) : {},"},{"line_number":109,"context_line":"        client.nova.servers.listDetail(),"},{"line_number":110,"context_line":"      ]);"},{"line_number":111,"context_line":"    if (kp.status \u003d\u003d\u003d \u0027fulfilled\u0027) {"},{"line_number":112,"context_line":"      const { keypairs \u003d [] } \u003d kp.value;"}],"source_content_type":"text/javascript","patch_set":1,"id":"22e739cc_88e0e162","line":109,"range":{"start_line":109,"start_character":8,"end_line":109,"end_character":41},"updated":"2026-09-01 05:42:05.000000000","message":"The `client.nova.servers.listDetail()` API returns a maximum of `osapi_max_limit` (1000 by default) virtual machines in a single call.\nIf there are more than 1000 virtual machines, some instances may be missed.\nIt is recommended to collect server IDs from the results returned by the API first, and then make batch calls to `skylineClient.extension.servers.list({fixed_addresses: \u0027xxx\u0027})` to assemble the final dataset.","commit_id":"bc766f04ff6dca70cf262bcf84fc9e781a25f546"},{"author":{"_account_id":38688,"name":"Nikita Vokhmintsev","email":"zedra5399@gmail.com","username":"nvoff"},"change_message_id":"332e60156c2dcf2010f80ddb6a267dd3785a9b4d","unresolved":true,"context_lines":[{"line_number":106,"context_line":"        fixedNetworkId ? this.networkClient.show(fixedNetworkId) : {},"},{"line_number":107,"context_line":"        fixedSubnetId ? this.subnetClient.show(fixedSubnetId) : {},"},{"line_number":108,"context_line":"        item.stack_id ? this.stackClient.list({ id: item.stack_id }) : {},"},{"line_number":109,"context_line":"        client.nova.servers.listDetail(),"},{"line_number":110,"context_line":"      ]);"},{"line_number":111,"context_line":"    if (kp.status \u003d\u003d\u003d \u0027fulfilled\u0027) {"},{"line_number":112,"context_line":"      const { keypairs \u003d [] } \u003d kp.value;"}],"source_content_type":"text/javascript","patch_set":1,"id":"c58e7cca_33f73665","line":109,"range":{"start_line":109,"start_character":8,"end_line":109,"end_character":41},"in_reply_to":"22e739cc_88e0e162","updated":"2026-09-03 08:47:59.000000000","message":"Thanks for pointing this out. Fixed in PS2.\n\nThe unfiltered client.nova.servers.listDetail() call has been removed, so the node lookup is no longer affected by osapi_max_limit.\n\nCluster node names are taken from health_status_reason, and the server query is filtered by the cluster stack_id. Returned servers are exact-matched against the Magnum node names, with limit/marker pagination if needed. This also avoids one API request per node.\n\nI checked the current skyline-console / skyline-apiserver master, but couldn\u0027t find extension.servers.list({ fixed_addresses: ... }) or a fixed_addresses parameter in the current extension API. If this refers to another or pending implementation, could you please point me to it?","commit_id":"bc766f04ff6dca70cf262bcf84fc9e781a25f546"},{"author":{"_account_id":38688,"name":"Nikita Vokhmintsev","email":"zedra5399@gmail.com","username":"nvoff"},"change_message_id":"db7da790339871c65ef141ae9230ff8f5636f773","unresolved":true,"context_lines":[{"line_number":106,"context_line":"        fixedNetworkId ? this.networkClient.show(fixedNetworkId) : {},"},{"line_number":107,"context_line":"        fixedSubnetId ? this.subnetClient.show(fixedSubnetId) : {},"},{"line_number":108,"context_line":"        item.stack_id ? this.stackClient.list({ id: item.stack_id }) : {},"},{"line_number":109,"context_line":"        client.nova.servers.listDetail(),"},{"line_number":110,"context_line":"      ]);"},{"line_number":111,"context_line":"    if (kp.status \u003d\u003d\u003d \u0027fulfilled\u0027) {"},{"line_number":112,"context_line":"      const { keypairs \u003d [] } \u003d kp.value;"}],"source_content_type":"text/javascript","patch_set":1,"id":"9bfdb3f9_d8f7569b","line":109,"range":{"start_line":109,"start_character":8,"end_line":109,"end_character":41},"in_reply_to":"7bfd01b5_a7c47341","updated":"2026-09-04 12:40:39.000000000","message":"Thanks for the clarification. Updated accordingly.\n\nThe unfiltered client.nova.servers.listDetail() call has been removed, so the lookup is no longer affected by osapi_max_limit.\n\nNode servers are now resolved through the Skyline extension/servers API using filtered queries. Fixed IP addresses use the ip filter. If Magnum exposes a floating IP, it is first resolved through Neutron to its fixed IP before querying extension/servers.\n\nFor CAPI-based clusters where Magnum exposes the Nova instance UUID in master_addresses / node_addresses, the uuid filter is used directly.\n\nAdmin cross-project cluster details are also handled using all_projects together with the cluster project_id.","commit_id":"bc766f04ff6dca70cf262bcf84fc9e781a25f546"},{"author":{"_account_id":38688,"name":"Nikita Vokhmintsev","email":"zedra5399@gmail.com","username":"nvoff"},"change_message_id":"4ece993b508f7c15c81f68ff26ad45f628f1c5fc","unresolved":true,"context_lines":[{"line_number":106,"context_line":"        fixedNetworkId ? this.networkClient.show(fixedNetworkId) : {},"},{"line_number":107,"context_line":"        fixedSubnetId ? this.subnetClient.show(fixedSubnetId) : {},"},{"line_number":108,"context_line":"        item.stack_id ? this.stackClient.list({ id: item.stack_id }) : {},"},{"line_number":109,"context_line":"        client.nova.servers.listDetail(),"},{"line_number":110,"context_line":"      ]);"},{"line_number":111,"context_line":"    if (kp.status \u003d\u003d\u003d \u0027fulfilled\u0027) {"},{"line_number":112,"context_line":"      const { keypairs \u003d [] } \u003d kp.value;"}],"source_content_type":"text/javascript","patch_set":1,"id":"ec7b21f7_5a8b0cb7","line":109,"range":{"start_line":109,"start_character":8,"end_line":109,"end_character":41},"in_reply_to":"9520ea0c_ed57e4a9","updated":"2026-09-07 05:04:38.000000000","message":"I got it , thank you","commit_id":"bc766f04ff6dca70cf262bcf84fc9e781a25f546"},{"author":{"_account_id":30434,"name":"Jingwei.Zhang","email":"zhang.jingwei@algoblu.com","username":"jwzhang"},"change_message_id":"55aff323d8cd3dd6fd365c988bc72fbf2f70f74f","unresolved":true,"context_lines":[{"line_number":106,"context_line":"        fixedNetworkId ? this.networkClient.show(fixedNetworkId) : {},"},{"line_number":107,"context_line":"        fixedSubnetId ? this.subnetClient.show(fixedSubnetId) : {},"},{"line_number":108,"context_line":"        item.stack_id ? this.stackClient.list({ id: item.stack_id }) : {},"},{"line_number":109,"context_line":"        client.nova.servers.listDetail(),"},{"line_number":110,"context_line":"      ]);"},{"line_number":111,"context_line":"    if (kp.status \u003d\u003d\u003d \u0027fulfilled\u0027) {"},{"line_number":112,"context_line":"      const { keypairs \u003d [] } \u003d kp.value;"}],"source_content_type":"text/javascript","patch_set":1,"id":"9520ea0c_ed57e4a9","line":109,"range":{"start_line":109,"start_character":8,"end_line":109,"end_character":41},"in_reply_to":"9bfdb3f9_d8f7569b","updated":"2026-09-07 04:53:17.000000000","message":"1. Resolving Nova servers by `cluster.stack_id` is invalid.\nIt is a Heat stack UUID which Nova cannot filter on.\nHeat templates name instances `\u003cOS::stack_name\u003e-node‑N` / `\u003cOS::stack_name\u003e-master‑N` (`kubecluster.yaml:1241‑1244,1472‑1475`). `OS::stack_name` looks like `mycluster‑abc123‑worker‑0` and contains no stack UUID, so fuzzy `name\u003d\u003cstack_id\u003e` queries find nothing.\nEach nodegroup has its own Heat stack, and the K8s‑node‑to‑Nova‑name mapping is only runtime‑defined without API stability guarantees.\n2. Lookup strategy adjustments:\n\n- Avoid the long lookup chain: Neutron floating‑IP → fixed‑IP → Nova server, it introduces extra API round trips.\n- Two feasible directions:\n  1. Primary direct per‑IP query, fallback to paginated full project server list on misses (no `stack_id` filter in fallback);\n  2. Accept partial resolution: omit the server link if IP lookup fails. Frontend does not need perfect resolution lacking stable identifiers.\n- When requesting servers by IP or fetching fallback lists, toggle `all_projects: true/false` dynamically based on current user admin permissions to decide whether to fetch servers from all projects.\n\nAlso fix ambiguous matching: do not pick the last server randomly. Select candidates deterministically by ACTIVE status, K8s node name, nodegroup labels and timestamps.","commit_id":"bc766f04ff6dca70cf262bcf84fc9e781a25f546"},{"author":{"_account_id":30434,"name":"Jingwei.Zhang","email":"zhang.jingwei@algoblu.com","username":"jwzhang"},"change_message_id":"3d70085bf070688c1c0cb754080aabbcf8637a2a","unresolved":true,"context_lines":[{"line_number":106,"context_line":"        fixedNetworkId ? this.networkClient.show(fixedNetworkId) : {},"},{"line_number":107,"context_line":"        fixedSubnetId ? this.subnetClient.show(fixedSubnetId) : {},"},{"line_number":108,"context_line":"        item.stack_id ? this.stackClient.list({ id: item.stack_id }) : {},"},{"line_number":109,"context_line":"        client.nova.servers.listDetail(),"},{"line_number":110,"context_line":"      ]);"},{"line_number":111,"context_line":"    if (kp.status \u003d\u003d\u003d \u0027fulfilled\u0027) {"},{"line_number":112,"context_line":"      const { keypairs \u003d [] } \u003d kp.value;"}],"source_content_type":"text/javascript","patch_set":1,"id":"7bfd01b5_a7c47341","line":109,"range":{"start_line":109,"start_character":8,"end_line":109,"end_character":41},"in_reply_to":"c58e7cca_33f73665","updated":"2026-09-04 01:57:40.000000000","message":"Sorry for my earlier mistake.\nThe `extension/servers` API has an IP query parameter defined at extension.py:120.\nThis parameter is forwarded as an IP filter to the Nova API at extension.py lines 171‑172, and it only matches fixed IPs, not floating IPs. `extension.servers.list({ ip: ... })`","commit_id":"bc766f04ff6dca70cf262bcf84fc9e781a25f546"},{"author":{"_account_id":30434,"name":"Jingwei.Zhang","email":"zhang.jingwei@algoblu.com","username":"jwzhang"},"change_message_id":"f6aec1ff6513dc03eee65ac95e50159df8349909","unresolved":false,"context_lines":[{"line_number":106,"context_line":"        fixedNetworkId ? this.networkClient.show(fixedNetworkId) : {},"},{"line_number":107,"context_line":"        fixedSubnetId ? this.subnetClient.show(fixedSubnetId) : {},"},{"line_number":108,"context_line":"        item.stack_id ? this.stackClient.list({ id: item.stack_id }) : {},"},{"line_number":109,"context_line":"        client.nova.servers.listDetail(),"},{"line_number":110,"context_line":"      ]);"},{"line_number":111,"context_line":"    if (kp.status \u003d\u003d\u003d \u0027fulfilled\u0027) {"},{"line_number":112,"context_line":"      const { keypairs \u003d [] } \u003d kp.value;"}],"source_content_type":"text/javascript","patch_set":1,"id":"8a560f89_ef1ec6db","line":109,"range":{"start_line":109,"start_character":8,"end_line":109,"end_character":41},"in_reply_to":"ec7b21f7_5a8b0cb7","updated":"2026-09-10 08:09:23.000000000","message":"Done","commit_id":"bc766f04ff6dca70cf262bcf84fc9e781a25f546"},{"author":{"_account_id":30434,"name":"Jingwei.Zhang","email":"zhang.jingwei@algoblu.com","username":"jwzhang"},"change_message_id":"f6aec1ff6513dc03eee65ac95e50159df8349909","unresolved":true,"context_lines":[{"line_number":233,"context_line":"    try {"},{"line_number":234,"context_line":"      const result \u003d await this.skylineClient.extension.servers({"},{"line_number":235,"context_line":"        ...this.getServerProjectParams(item, allProjects),"},{"line_number":236,"context_line":"        ...(ip ? { ip: `^${escapeRegExp(ip)}$` } : { uuid: reference }),"},{"line_number":237,"context_line":"        limit: 1000,"},{"line_number":238,"context_line":"        sort_keys: \u0027uuid\u0027,"},{"line_number":239,"context_line":"        sort_dirs: \u0027asc\u0027,"}],"source_content_type":"text/javascript","patch_set":6,"id":"9ab75d67_4cfbdd04","line":236,"range":{"start_line":236,"start_character":25,"end_line":236,"end_character":45},"updated":"2026-09-10 08:09:23.000000000","message":"Suggestion: Remove the ^...$ regex anchor and escaping; pass raw plain IP.\nReasoning:\nskyline-apiserver forwards the IP verbatim.\nNova has two IP filter paths. With Neutron\u0027s default ip-substring-filtering extension, Nova builds ip_address_substr for SQL LIKE \u0027%value%\u0027. Anchored regex like ^10\\.0\\.0\\.5$ becomes literal text and never matches.\nPlain IP works on both paths. The in-memory regex path may over-match (e.g. 10.0.0.50), but selectNodeServer(clusters.js:350-362) already applies exact normalized IP checks to discard false hits.\nKeeping the anchor returns empty results in default environments, triggering full project server fallback (getProjectServers) every time and ruining this optimization.\nConclusion: The regex anchor is unnecessary and breaks filtering. Pass raw IP; the escapeRegExp helper (only used here) can be removed.","commit_id":"f5931f6f56b494aea8a4cc6c67f90df4a8155f83"},{"author":{"_account_id":38688,"name":"Nikita Vokhmintsev","email":"zedra5399@gmail.com","username":"nvoff"},"change_message_id":"7ec60fe8ebe28e27e4db800aa3c1489a97bbaf38","unresolved":true,"context_lines":[{"line_number":233,"context_line":"    try {"},{"line_number":234,"context_line":"      const result \u003d await this.skylineClient.extension.servers({"},{"line_number":235,"context_line":"        ...this.getServerProjectParams(item, allProjects),"},{"line_number":236,"context_line":"        ...(ip ? { ip: `^${escapeRegExp(ip)}$` } : { uuid: reference }),"},{"line_number":237,"context_line":"        limit: 1000,"},{"line_number":238,"context_line":"        sort_keys: \u0027uuid\u0027,"},{"line_number":239,"context_line":"        sort_dirs: \u0027asc\u0027,"}],"source_content_type":"text/javascript","patch_set":6,"id":"d33cd516_8320f241","line":236,"range":{"start_line":236,"start_character":25,"end_line":236,"end_character":45},"in_reply_to":"9ab75d67_4cfbdd04","updated":"2026-09-10 09:48:20.000000000","message":"Thanks for the suggestion. Updated accordingly.\n\nThe `^...$` regex anchors and escaping have been removed, and the normalized plain IP is now passed directly to `extension.servers`:\n\n`...(ip ? { ip } : { uuid: reference })`\n\nThe unused `escapeRegExp` import was removed as well.\n\nExact IP matching is still handled in `selectNodeServer`, so any potential substring matches returned by Nova are filtered out before selecting the server.","commit_id":"f5931f6f56b494aea8a4cc6c67f90df4a8155f83"},{"author":{"_account_id":30434,"name":"Jingwei.Zhang","email":"zhang.jingwei@algoblu.com","username":"jwzhang"},"change_message_id":"e6851e952022143a688be84fd37b8f1608aff3ab","unresolved":false,"context_lines":[{"line_number":233,"context_line":"    try {"},{"line_number":234,"context_line":"      const result \u003d await this.skylineClient.extension.servers({"},{"line_number":235,"context_line":"        ...this.getServerProjectParams(item, allProjects),"},{"line_number":236,"context_line":"        ...(ip ? { ip: `^${escapeRegExp(ip)}$` } : { uuid: reference }),"},{"line_number":237,"context_line":"        limit: 1000,"},{"line_number":238,"context_line":"        sort_keys: \u0027uuid\u0027,"},{"line_number":239,"context_line":"        sort_dirs: \u0027asc\u0027,"}],"source_content_type":"text/javascript","patch_set":6,"id":"dcc5ff37_158977df","line":236,"range":{"start_line":236,"start_character":25,"end_line":236,"end_character":45},"in_reply_to":"d33cd516_8320f241","updated":"2026-09-11 08:04:05.000000000","message":"Done","commit_id":"f5931f6f56b494aea8a4cc6c67f90df4a8155f83"}]}
