)]}'
{"aetos/controllers/api/v1/label.py":[{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"66133ce33dae631e142d762f7443f1146ba0afe3","unresolved":true,"context_lines":[{"line_number":32,"context_line":"        \"\"\"Label endpoint\"\"\""},{"line_number":33,"context_line":"        target \u003d {\"project_id\": pecan.request.headers.get(\u0027X-Project-Id\u0027)}"},{"line_number":34,"context_line":"        try:"},{"line_number":35,"context_line":"            rbac.enforce(\u0027label:all_projects\u0027, pecan.request.headers,"},{"line_number":36,"context_line":"                         pecan.request.enforcer, target)"},{"line_number":37,"context_line":"            privileged \u003d True"},{"line_number":38,"context_line":"            LOG.debug("}],"source_content_type":"text/x-python","patch_set":1,"id":"cc766b6f_2fd929ed","line":35,"range":{"start_line":35,"start_character":32,"end_line":35,"end_character":44},"updated":"2025-06-10 11:44:36.000000000","message":"(This is applied to all endpoints, IIUC) I wonder if api should return resources across all projects only when that is explicitly requrested. The current behavior may kill admins if too many resources exist in the deployment.\n\nAdding the project_id filter, which may work for only admin would be also an option.","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":34975,"name":"Jaromír Wysoglad","email":"jwysogla@redhat.com","username":"jwysogla"},"change_message_id":"d4533c517e7b5a7eea60c259f986d4485e72b260","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        \"\"\"Label endpoint\"\"\""},{"line_number":33,"context_line":"        target \u003d {\"project_id\": pecan.request.headers.get(\u0027X-Project-Id\u0027)}"},{"line_number":34,"context_line":"        try:"},{"line_number":35,"context_line":"            rbac.enforce(\u0027label:all_projects\u0027, pecan.request.headers,"},{"line_number":36,"context_line":"                         pecan.request.enforcer, target)"},{"line_number":37,"context_line":"            privileged \u003d True"},{"line_number":38,"context_line":"            LOG.debug("}],"source_content_type":"text/x-python","patch_set":1,"id":"24660ac5_1df2cf22","line":35,"range":{"start_line":35,"start_character":32,"end_line":35,"end_character":44},"in_reply_to":"10ba9d83_9db54eb3","updated":"2025-06-11 08:38:21.000000000","message":"That\u0027s a good note. It\u0027s actually very near the top of my list to do after this. We might not need too much additional logic and restrictions. I think it would be enough if the code does the following:\n\n- non-admin user sends a query looking something like this: `ceilometer_cpu{project\u003d\u0027\u003cproject id of another project\u003e\u0027}`\n- this could be changed by Aetos and the observabilityclient into something like: `ceilometer_cpu{project\u003d\u0027\u003cproject id of another project\u003e\u0027, project\u003d\u0027\u003cproject id of current project\u003e\u0027}`\n- if Prometheus \"ands\" the 2 label selectors, then it should return empty result, because a metric can\u0027t have the same label with 2 different values (it can\u0027t belong to 2 different projects at once).\n\nThis is something I want to test thoroughly for all the endpoints and I\u0027ll add additional logic if needed.","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":34975,"name":"Jaromír Wysoglad","email":"jwysogla@redhat.com","username":"jwysogla"},"change_message_id":"48fbc118ba119bb03d8b72d0d542ddd599997009","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        \"\"\"Label endpoint\"\"\""},{"line_number":33,"context_line":"        target \u003d {\"project_id\": pecan.request.headers.get(\u0027X-Project-Id\u0027)}"},{"line_number":34,"context_line":"        try:"},{"line_number":35,"context_line":"            rbac.enforce(\u0027label:all_projects\u0027, pecan.request.headers,"},{"line_number":36,"context_line":"                         pecan.request.enforcer, target)"},{"line_number":37,"context_line":"            privileged \u003d True"},{"line_number":38,"context_line":"            LOG.debug("}],"source_content_type":"text/x-python","patch_set":1,"id":"2a530b5a_558e7470","line":35,"range":{"start_line":35,"start_character":32,"end_line":35,"end_character":44},"in_reply_to":"24660ac5_1df2cf22","updated":"2025-06-20 08:39:38.000000000","message":"I recently did some manual testing for all endpoints allowing to specify a project. And I can confirm, that it works as described above, so if non-admin requests metrics from a different project, then nothing gets returned, which seems like the correct behavior to me. I added a testcase for this situation in the observabilityclient https://review.opendev.org/c/openstack/python-observabilityclient/+/952963 . Another place where this should be tested is in an integration test inside a dsvm, maybe with tempest. I\u0027m currently in the middle of doing that, but I\u0027m waiting for the CI to be functional here https://review.opendev.org/c/openstack/devstack/+/951628","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":34975,"name":"Jaromír Wysoglad","email":"jwysogla@redhat.com","username":"jwysogla"},"change_message_id":"e9f85c1d0f8a39d4de9da6f5d17128207493d6d6","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        \"\"\"Label endpoint\"\"\""},{"line_number":33,"context_line":"        target \u003d {\"project_id\": pecan.request.headers.get(\u0027X-Project-Id\u0027)}"},{"line_number":34,"context_line":"        try:"},{"line_number":35,"context_line":"            rbac.enforce(\u0027label:all_projects\u0027, pecan.request.headers,"},{"line_number":36,"context_line":"                         pecan.request.enforcer, target)"},{"line_number":37,"context_line":"            privileged \u003d True"},{"line_number":38,"context_line":"            LOG.debug("}],"source_content_type":"text/x-python","patch_set":1,"id":"2b95ada5_93dff32b","line":35,"range":{"start_line":35,"start_character":32,"end_line":35,"end_character":44},"in_reply_to":"2a530b5a_558e7470","updated":"2025-06-20 08:51:54.000000000","message":"And to the original questions of adding project_id filtering, so that we don\u0027t kill admins. I created the following patch, which allows all users to use the match[] parameter. This way admins can restrict requests going into label/ and labels/ to only a single project (they can do more than just selecting a project with that) https://review.opendev.org/c/openstack/aetos/+/952813","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"e421abca6ad7691d99d4b0ff6118d98a09fee7b4","unresolved":true,"context_lines":[{"line_number":32,"context_line":"        \"\"\"Label endpoint\"\"\""},{"line_number":33,"context_line":"        target \u003d {\"project_id\": pecan.request.headers.get(\u0027X-Project-Id\u0027)}"},{"line_number":34,"context_line":"        try:"},{"line_number":35,"context_line":"            rbac.enforce(\u0027label:all_projects\u0027, pecan.request.headers,"},{"line_number":36,"context_line":"                         pecan.request.enforcer, target)"},{"line_number":37,"context_line":"            privileged \u003d True"},{"line_number":38,"context_line":"            LOG.debug("}],"source_content_type":"text/x-python","patch_set":1,"id":"eef041d7_c612793f","line":35,"range":{"start_line":35,"start_character":32,"end_line":35,"end_character":44},"in_reply_to":"cc766b6f_2fd929ed","updated":"2025-06-10 11:58:30.000000000","message":"I\u0027ve checked aodh and I see it uses the all_projects query parameter as the flag.","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"176975a1451a75d1ad99de23fd1c5bd0b222a68c","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        \"\"\"Label endpoint\"\"\""},{"line_number":33,"context_line":"        target \u003d {\"project_id\": pecan.request.headers.get(\u0027X-Project-Id\u0027)}"},{"line_number":34,"context_line":"        try:"},{"line_number":35,"context_line":"            rbac.enforce(\u0027label:all_projects\u0027, pecan.request.headers,"},{"line_number":36,"context_line":"                         pecan.request.enforcer, target)"},{"line_number":37,"context_line":"            privileged \u003d True"},{"line_number":38,"context_line":"            LOG.debug("}],"source_content_type":"text/x-python","patch_set":1,"id":"10ba9d83_9db54eb3","line":35,"range":{"start_line":35,"start_character":32,"end_line":35,"end_character":44},"in_reply_to":"e8f71888_8a2f47ec","updated":"2025-06-11 08:09:30.000000000","message":"That makes sense. Note that we probably have to add some logic to check usage of the query with project_id and restrict it to only admin(or anyone with global scope access).","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":34975,"name":"Jaromír Wysoglad","email":"jwysogla@redhat.com","username":"jwysogla"},"change_message_id":"254123274900d95e5db442051a14b896bc2935ef","unresolved":true,"context_lines":[{"line_number":32,"context_line":"        \"\"\"Label endpoint\"\"\""},{"line_number":33,"context_line":"        target \u003d {\"project_id\": pecan.request.headers.get(\u0027X-Project-Id\u0027)}"},{"line_number":34,"context_line":"        try:"},{"line_number":35,"context_line":"            rbac.enforce(\u0027label:all_projects\u0027, pecan.request.headers,"},{"line_number":36,"context_line":"                         pecan.request.enforcer, target)"},{"line_number":37,"context_line":"            privileged \u003d True"},{"line_number":38,"context_line":"            LOG.debug("}],"source_content_type":"text/x-python","patch_set":1,"id":"e8f71888_8a2f47ec","line":35,"range":{"start_line":35,"start_character":32,"end_line":35,"end_character":44},"in_reply_to":"eef041d7_c612793f","updated":"2025-06-10 13:06:18.000000000","message":"The idea is to stay as close to the Prometheus API as possible https://prometheus.io/docs/prometheus/latest/querying/api/ , although so far I focused only on a subset of the API which is being used by the observabilityclient and watcher. The Prometheus API doesn\u0027t have an all_projects flag, so I don\u0027t think we should be including it here. Aetos is written on purpose in a way to not create any restrictions for services (and admins), so a request to aetos by a service or admin should return the same data as if it was sent directly to Prometheus. Admins and services can add the project label themselves in the same way in their queries when using the `query` or the `series` endpoints. I can extend the `label` and `labels` endpoints in a followup to allow this as well. So after the extension, an admin would be able to do something like `curl \u003caetos\u003e/api/v1/labels?match[]\u003d{project\u003d\u0027\u003cproject_id\u003e\u0027}`","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"c1154f6bf3eb375e575d40772c239f26af4aaefc","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        else:"},{"line_number":58,"context_line":"            result \u003d self.prometheus_get("},{"line_number":59,"context_line":"                f\"label/{name}/values\","},{"line_number":60,"context_line":"                {\"match[]\": f\"{{project\u003d\u0027{target[\u0027project_id\u0027]}\u0027}}\"}"},{"line_number":61,"context_line":"            )"},{"line_number":62,"context_line":"        LOG.debug(\"Data received from prometheus: %s\", str(result))"},{"line_number":63,"context_line":"        return result"}],"source_content_type":"text/x-python","patch_set":1,"id":"40c986f8_23fc5d2a","line":60,"updated":"2025-06-10 09:53:16.000000000","message":"The \"project\" field should be configurable in aetos configuration. Currently we call it \"project\", but eventually we should change it to be \"project_id\" in the close future and it would be better if Aetos would be configurable.","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":34975,"name":"Jaromír Wysoglad","email":"jwysogla@redhat.com","username":"jwysogla"},"change_message_id":"40f79e893117a9a2f6d8dcc484e965d3755d9dab","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        else:"},{"line_number":58,"context_line":"            result \u003d self.prometheus_get("},{"line_number":59,"context_line":"                f\"label/{name}/values\","},{"line_number":60,"context_line":"                {\"match[]\": f\"{{project\u003d\u0027{target[\u0027project_id\u0027]}\u0027}}\"}"},{"line_number":61,"context_line":"            )"},{"line_number":62,"context_line":"        LOG.debug(\"Data received from prometheus: %s\", str(result))"},{"line_number":63,"context_line":"        return result"}],"source_content_type":"text/x-python","patch_set":1,"id":"422896c3_d6a1a886","line":60,"in_reply_to":"40c986f8_23fc5d2a","updated":"2025-06-10 11:39:34.000000000","message":"That\u0027s a bit unfortunate and it\u0027s a bit more work than just Aetos. We have it over here too: https://opendev.org/openstack/python-observabilityclient/src/branch/master/observabilityclient/rbac.py#L24 and the idea is that this class would be used by every service interacting with Prometheus on behalf of non-admin users (so aodh, aetos, I know you\u0027re working on cloudkitty, which might need that too, the grian horizon plugin and possibly in the far future Watcher). So basically every service will need to know what label name to use.\n\nI can see several approaches to do this:\n- Each service interacting with Prometheus will need to have this configurable\n- We could just rely on the /etc/openstack/prometheus.yaml config file for the observabilityclient, which is quite unfortunate as I was quite happy that we managed to get rid of its need recently\n- We could have some automatic discovery process of the label. Either through a special Aetos endpoint or maybe through a query to prometheus\n\nI\u0027ll investigate the options above further and come up with a solution, which I\u0027ll also discuss with you. In the meantime I\u0027ll adjust this code to use the rbac from the observabilityclient instead of hardcoding the labels here, so that we have the project labels only in one place.","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"176975a1451a75d1ad99de23fd1c5bd0b222a68c","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        else:"},{"line_number":58,"context_line":"            result \u003d self.prometheus_get("},{"line_number":59,"context_line":"                f\"label/{name}/values\","},{"line_number":60,"context_line":"                {\"match[]\": f\"{{project\u003d\u0027{target[\u0027project_id\u0027]}\u0027}}\"}"},{"line_number":61,"context_line":"            )"},{"line_number":62,"context_line":"        LOG.debug(\"Data received from prometheus: %s\", str(result))"},{"line_number":63,"context_line":"        return result"}],"source_content_type":"text/x-python","patch_set":1,"id":"4cabef3a_cdc1115a","line":60,"in_reply_to":"422896c3_d6a1a886","updated":"2025-06-11 08:09:30.000000000","message":"One option might be to accept both project_id and project for now and then aim to deprecate project.","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":34975,"name":"Jaromír Wysoglad","email":"jwysogla@redhat.com","username":"jwysogla"},"change_message_id":"d4533c517e7b5a7eea60c259f986d4485e72b260","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        else:"},{"line_number":58,"context_line":"            result \u003d self.prometheus_get("},{"line_number":59,"context_line":"                f\"label/{name}/values\","},{"line_number":60,"context_line":"                {\"match[]\": f\"{{project\u003d\u0027{target[\u0027project_id\u0027]}\u0027}}\"}"},{"line_number":61,"context_line":"            )"},{"line_number":62,"context_line":"        LOG.debug(\"Data received from prometheus: %s\", str(result))"},{"line_number":63,"context_line":"        return result"}],"source_content_type":"text/x-python","patch_set":1,"id":"832f6729_c56374f4","line":60,"in_reply_to":"4cabef3a_cdc1115a","updated":"2025-06-11 08:38:21.000000000","message":"Hmm, that\u0027s also a possibility. I guess we could just duplicate each query, once using the \"project\" label and once using the \"project_id\" label and or the results together. So we\u0027d end up with something like `ceilometer_cpu{project\u003d\u003cproject_id\u003e} or ceilometer_cpu{project_id\u003d\u003cproject_id\u003e}`. Unfortunately we can\u0027t just have `ceilometer_cpu{project\u003d\u003cproject_id\u003e, project_id\u003d\u003cproject_id\u003e}`, because Prometheus will \"and\" the labels, which would always result in an empty response.","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"4261fa7c1ca04fbd6f426b595f59402302990fa4","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        else:"},{"line_number":58,"context_line":"            result \u003d self.prometheus_get("},{"line_number":59,"context_line":"                f\"label/{name}/values\","},{"line_number":60,"context_line":"                {\"match[]\": f\"{{project\u003d\u0027{target[\u0027project_id\u0027]}\u0027}}\"}"},{"line_number":61,"context_line":"            )"},{"line_number":62,"context_line":"        LOG.debug(\"Data received from prometheus: %s\", str(result))"},{"line_number":63,"context_line":"        return result"}],"source_content_type":"text/x-python","patch_set":1,"id":"c60305cc_b4441546","line":60,"in_reply_to":"832f6729_c56374f4","updated":"2025-06-18 10:09:35.000000000","message":"CloudKitty lets the user configure the label, so \"project\" would be good to go from its perspective. My fear here is that this is called by default project_id everywhere, but in Prometheus. To me, this was a historical sg-core failure that needs to be corrected.\n\nThe \"or\" of every query will make the code far less legible, but in truth, we must find a way to move Prometheus label from project to project_id. We need to have a plan.\n\nFor me, this makes every service interacting with Prometheus to have this configurable. And we can do that one at a time. Having that support here will not be very useful at the beginning, while there are others where this is not implemented, but at least, we will end up with one less service to change in the future.","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"627b456ea73d19a4f859bb778d46dc75fc576fd4","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        else:"},{"line_number":58,"context_line":"            result \u003d self.prometheus_get("},{"line_number":59,"context_line":"                f\"label/{name}/values\","},{"line_number":60,"context_line":"                {\"match[]\": f\"{{project\u003d\u0027{target[\u0027project_id\u0027]}\u0027}}\"}"},{"line_number":61,"context_line":"            )"},{"line_number":62,"context_line":"        LOG.debug(\"Data received from prometheus: %s\", str(result))"},{"line_number":63,"context_line":"        return result"}],"source_content_type":"text/x-python","patch_set":1,"id":"a38efdeb_14ef8c56","line":60,"in_reply_to":"94f1d8e1_6bb6da12","updated":"2025-06-26 12:57:00.000000000","message":"Done","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"},{"author":{"_account_id":34975,"name":"Jaromír Wysoglad","email":"jwysogla@redhat.com","username":"jwysogla"},"change_message_id":"8e4b95e7d64e48350315bc2a2b744bcad73cc981","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        else:"},{"line_number":58,"context_line":"            result \u003d self.prometheus_get("},{"line_number":59,"context_line":"                f\"label/{name}/values\","},{"line_number":60,"context_line":"                {\"match[]\": f\"{{project\u003d\u0027{target[\u0027project_id\u0027]}\u0027}}\"}"},{"line_number":61,"context_line":"            )"},{"line_number":62,"context_line":"        LOG.debug(\"Data received from prometheus: %s\", str(result))"},{"line_number":63,"context_line":"        return result"}],"source_content_type":"text/x-python","patch_set":1,"id":"94f1d8e1_6bb6da12","line":60,"in_reply_to":"c60305cc_b4441546","updated":"2025-06-25 09:37:39.000000000","message":"@jlarriba@redhat.com I wonder if there is anything else to discuss here regarding the label names? Or can we proceed with merging this change?\n\nIn PS2 I removed the direct mentions of \"project\" label from this code, so now the label name comes from the observabilityclient. Only place where the \"project\" label is used in this change are the tests, which are mocking the observabilityclient anyway, so it doesn\u0027t really matter what label name is used there.\n\nAny support for using different labels or having them configurable will need to come from observabilityclient first and only then we can introduce config values in the individual services. I propose to take the discussion out of this change and propose additional changes as needed.","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"}],"aetos/controllers/api/v1/labels.py":[{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"c1154f6bf3eb375e575d40772c239f26af4aaefc","unresolved":true,"context_lines":[{"line_number":51,"context_line":"            result \u003d self.prometheus_get(\"labels\")"},{"line_number":52,"context_line":"        else:"},{"line_number":53,"context_line":"            result \u003d self.prometheus_get("},{"line_number":54,"context_line":"                \"labels\", {\"match[]\": f\"{{project\u003d\u0027{target[\u0027project_id\u0027]}\u0027}}\"}"},{"line_number":55,"context_line":"            )"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"        LOG.debug(\"Data received from prometheus: %s\", str(result))"}],"source_content_type":"text/x-python","patch_set":1,"id":"b793f29c_0e68a026","line":54,"updated":"2025-06-10 09:53:16.000000000","message":"See above","commit_id":"a4a09d9a4b92b51e698333a3560ab7fd2515d324"}]}
